Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 74 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,87 @@
* test: 测试分支

## 测试环境服务启动
1. 前端启动:
1. nginx添加配置:
```
server {
listen 80;
server_name localhost;

#charset koi8-r;

#access_log logs/host.access.log main;

location / {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}

# api
location /api/ {
proxy_pass http://127.0.0.1:8000;
client_max_body_size 100m;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
#proxy_pass http://127.0.0.1:4523/mock/412521/api/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}


}

```
2. 前端启动:
```
进入www页面,执行:npm run serve
```
2. 后端启动
3. 后端启动
```
uvicorn server.main:app --reload
```

## 生产环境部署
1. 前端执行打包命令
```
npm run build
```
2. 添加nginx配置
```
server {
listen 80;
location / {
root /opt/www; #打包后前端放置目录
index index.html;
try_files $uri $uri/ /index.html;
}

location /api/ {
proxy_pass http://127.0.0.1:8000;
client_max_body_size 100m;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
#proxy_pass http://127.0.0.1:4523/mock/412521/api/;
}
}
```
3. 启动后端服务
生产环境使用,建议通过gunicorn启动服务
```
nohup gunicorn server.main:app -b 127.0.0.1:8000 -w 4 -k uvicorn.workers.UvicornWorker >gunicorn.log 2>&1&
```

## 约束
1. 后端数据库对于布尔值的传递统一数据库设置为tinyint,0为假,1为真
2. 前端所有bool都0为假,1为真
Expand Down
2 changes: 1 addition & 1 deletion server/crud/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def search(self, session: Session, search: Pagination, filter_type: Optional[Dic
else:
subquery = subquery.order_by(getattr(self.model, order_col))
subquery = subquery.offset(
(search.page - 1) * search.page_size).limit(1).subquery()
(search.page - 1) * search.page_size).limit(1).scalar_subquery()
if search.model == 'desc':
sql = sql.where(getattr(self.model, order_col) <= subquery).order_by(desc(getattr(self.model, order_col))).limit(
search.page_size)
Expand Down
2 changes: 1 addition & 1 deletion server/crud/internal/dictonary.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class CRUDDict(CRUDBase[DataDict]):

class CRUDItem(CRUDBase[DictItem]):
def get_items_by_code(self, db: Session, code: str):
dict_id = select(DataDict.id).where(DataDict.code == code).subquery()
dict_id = select(DataDict.id).where(DataDict.code == code).scalar_subquery()
sql = select(self.model).where(self.model.dict_id == dict_id).where(self.model.enable == 1).order_by(
self.model.sort)
return db.exec(sql).all()
Expand Down
32 changes: 16 additions & 16 deletions www/src/components/MenuList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<el-menu
class="el-menu-vertical-demo"
router
unique-opened
@open="handleOpen"
@close="handleClose">
<el-menu-item index="/dashboard">首页</el-menu-item>
Expand Down Expand Up @@ -35,25 +36,24 @@
</el-menu>
</template>

<script>
<script setup>
import {useStore} from '@/stores'
import {mapState} from 'pinia'
import {computed} from 'vue'

export default {
computed: {
...mapState(useStore, {
menuList: 'asyncRoutes'
})
},
methods: {
handleOpen(key, keyPath) {
console.log(key, keyPath)
},
handleClose(key, keyPath) {
console.log(key, keyPath)
}
}
const userStore = useStore()

const menuList = computed(() => {
return userStore.asyncRoutes
})

function handleOpen(key, keyPath) {
console.log(key, keyPath)
}

function handleClose(key, keyPath) {
console.log(key, keyPath)
}

</script>

<style>
Expand Down
14 changes: 9 additions & 5 deletions www/src/permission.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,22 @@ import {
import {
makeRouter
} from "@/utils/router";
import {useTabsStore} from '@/stores/tabs'



const whiteList = ['/login'] // no redirect whitelist

router.beforeEach((to) => {
const store = useStore()
const {tabAdd} = useTabsStore()
console.log('start before each')

if (getToken()) {
console.log('已经有token')
// 已登录且要跳转的页面是登录页
if (to.path === '/login') {
return '/dashboard'
return '/'
} else {
console.log('已经登录成功')
//登录成功,需要判断router是不是已经按照权限要求构建好,并且菜单是否按照权限要求生成,如没有,则生成
Expand All @@ -41,11 +44,12 @@ router.beforeEach((to) => {
location.reload()
})
})
} else {
console.log('当前生效路由表')
console.log(router.getRoutes())
return true
}
console.log('当前生效路由表')
console.log(router.getRoutes())
tabAdd(to)
return true

}
} else {
// 无token信息,表示未登录
Expand Down
2 changes: 1 addition & 1 deletion www/src/router/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ export const constantRouterMap = [
},
{
path: '/dashboard',
name: 'dashboard',
component: () => import('@/views/Layout'),
children: [
{
path: '',
name: 'dashboard',
component: () => import('@/views/DashBoard')
}
]
Expand Down
122 changes: 61 additions & 61 deletions www/src/stores/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {defineStore} from 'pinia'
import {ref} from 'vue'
import {
requestLogin,
GetUserInfo,
Expand All @@ -9,72 +10,71 @@ import {
removeToken
} from '@/utils/auth'

export const useStore = defineStore('user', {
state: () => {
return {
uid: '',
token: '',
name: '',
avatar: '',
asyncRoutes: [],
buttons:[],
}
export const useStore = defineStore('user', () => {

},
const uid = ref('')
const token = ref('')
const name = ref(null)
const avatar = ref(null)
const asyncRoutes = ref([])
const buttons = ref([])

actions: {
//执行登录请求,获取token
logIn(userInfo) {
const username = userInfo.username
const password = userInfo.password
const rememberMe = userInfo.rememberMe
console.log('user login actions')
return new Promise((resolve, reject) => {
requestLogin(username, password).then((response) => {
console.log(response)
setToken(response.token, rememberMe)
this.token = response.token
this.uid = response.uid
resolve()
}).catch((error) => {
reject(error)
})
})
},
// 获取用户状态信息
getInfo() {
return new Promise((resolve, reject) => {
console.log('get user info')
GetUserInfo(this.uid).then(response => {
this.name = response.name
this.avatar = response.avatar
resolve(response)
}).catch(error => {
reject(error)
})
})
},
logOut() {
return new Promise((resolve) => {
this.$reset()
removeToken()
//执行登录请求,获取token
function logIn(userInfo) {
const username = userInfo.username
const password = userInfo.password
const rememberMe = userInfo.rememberMe
console.log('user login actions')
return new Promise((resolve, reject) => {
requestLogin(username, password).then((response) => {
console.log(response)
setToken(response.token, rememberMe)
token.value = response.token
uid.value = response.uid
resolve()
}).catch((error) => {
reject(error)
})
})
}

// 获取用户状态信息
function getInfo() {
return new Promise((resolve, reject) => {
console.log('get user info')
GetUserInfo(this.uid).then(response => {
name.value = response.name
avatar.value = response.avatar
resolve(response)
}).catch(error => {
reject(error)
})
},
// 获取用户权限列表
getPermission() {
return new Promise((resolve, reject) => {
GetUserPermission().then(response => {
console.log('permission response is:')
console.log(response)
this.asyncRoutes = response.menus
this.buttons = response.btns
resolve(response)
}).catch(error => {
reject(error)
})
})
}

function logOut() {
return new Promise((resolve) => {
// this.$reset()
removeToken()
resolve()
})
}

// 获取用户权限列表
function getPermission() {
return new Promise((resolve, reject) => {
GetUserPermission().then(response => {
console.log('permission response is:')
console.log(response)
asyncRoutes.value = (response.menus)
buttons.value = (response.btns)
resolve(response)
}).catch(error => {
reject(error)
})
}
})
}

return {uid, token, name, avatar, asyncRoutes, buttons, getInfo, logIn, logOut, getPermission}
}
)
Loading