合并代码

This commit is contained in:
余菲 2022-05-24 10:12:03 +08:00
commit 9f94ab36e5
16 changed files with 315 additions and 119 deletions

View File

@ -3,7 +3,7 @@ const asyncRoutes = [
path: '/system', path: '/system',
component: 'Layout', component: 'Layout',
redirect: '/system/menu', redirect: '/system/menu',
name: 'System', title: 'System',
meta: { meta: {
title: '系统管理' title: '系统管理'
}, },
@ -11,7 +11,7 @@ const asyncRoutes = [
{ {
path: 'menu', path: 'menu',
component: 'views/system/menu/index', component: 'views/system/menu/index',
name: 'SystemMenu', title: 'SystemMenu',
meta: { meta: {
title: '菜单管理' title: '菜单管理'
} }
@ -19,7 +19,7 @@ const asyncRoutes = [
{ {
path: 'user', path: 'user',
component: 'views/system/user/index', component: 'views/system/user/index',
name: 'SystemUser', title: 'SystemUser',
meta: { meta: {
title: '用户管理' title: '用户管理'
} }

View File

@ -14,3 +14,10 @@ export const refreshToken = () => {
method: 'post' method: 'post'
}) })
} }
export function getMenu() {
return request({
url: '/index/getMenuList',
method: 'GET'
})
}

View File

@ -76,7 +76,7 @@ export default {
/* tableData-start */ /* tableData-start */
const tableData = ref([]) const tableData = ref([])
const { getDataSourceRef, getRowKey, reload } = useDataSource(getProps, { getPaginationInfo, setPagination, tableData, setLoading }, emit) const { getDataSourceRef, getRowKey, reload, reFetch } = useDataSource(getProps, { getPaginationInfo, setPagination, tableData, setLoading }, emit)
const isRequest = !!unref(getProps).request const isRequest = !!unref(getProps).request
const getBindProps = computed(() => { const getBindProps = computed(() => {
return { return {
@ -97,7 +97,8 @@ export default {
pagination, pagination,
updatePage, updatePage,
updatePageSize, updatePageSize,
reload reload,
reFetch
} }
} }
} }

View File

@ -30,7 +30,7 @@ export const tableProps = {
// 每页数量字段名 // 每页数量字段名
sizeField: 'limit', sizeField: 'limit',
// 接口返回的数据字段名 // 接口返回的数据字段名
listField: 'list', listField: 'records',
// 接口返回总页数字段名 // 接口返回总页数字段名
totalField: 'total', totalField: 'total',
// 默认分页数量 // 默认分页数量

View File

@ -105,6 +105,19 @@ export function useDataSource(propsRef, { getPaginationInfo, setPagination, setL
await fetch(opt) await fetch(opt)
} }
async function reFetch(opt) {
console.log('opt', opt)
const { paginationSetting } = unref(propsRef)
const pageField = paginationSetting.pageField
const sizeField = paginationSetting.sizeField
const pageSize = paginationSetting.pageSize
setPagination({
[pageField]: 1,
[sizeField]: pageSize
})
await fetch(opt)
}
onMounted(() => { onMounted(() => {
setTimeout(() => { setTimeout(() => {
fetch() fetch()
@ -117,6 +130,7 @@ export function useDataSource(propsRef, { getPaginationInfo, setPagination, setL
getDataSource, getDataSource,
setTableData, setTableData,
getRowKey, getRowKey,
reload reload,
reFetch
} }
} }

View File

@ -1,52 +1,6 @@
<template /> <template />
<script setup> <script setup>
import { isNullOrUndef } from '@/utils/is'
import { useDialog } from 'naive-ui' import { useDialog } from 'naive-ui'
window['$dialog'] = useDialog()
const NDialog = useDialog()
class Dialog {
success(title, option) {
this.showDialog('success', { title, ...option })
}
warning(title, option) {
this.showDialog('warning', { title, ...option })
}
error(title, option) {
this.showDialog('error', { title, ...option })
}
showDialog(type = 'success', option) {
if (isNullOrUndef(option.title)) {
// ! title
option.showIcon = false
}
NDialog[type]({
positiveText: 'OK',
closable: false,
...option
})
}
confirm(option = {}) {
this.showDialog(option.type || 'error', {
positiveText: '确定',
negativeText: '取消',
onPositiveClick: option.confirm,
onNegativeClick: option.cancel,
onMaskClick: option.cancel,
...option
})
}
}
window['$dialog'] = new Dialog()
Object.freeze(window.$dialog)
Object.defineProperty(window, '$dialog', {
configurable: false,
writable: false
})
</script> </script>

View File

@ -0,0 +1,47 @@
<template>
<n-modal v-bind="getModalOptions" preset="dialog">
<n-card>
<slot name="Context" />
</n-card>
</n-modal>
</template>
<script>
import { defineComponent, computed, unref } from 'vue'
export default defineComponent({
name: 'ModalModules',
props: {
options: {
type: Object,
default: () => {}
}
},
emits: {
click: null, // click
onClose: (value) => {
return value
}
},
setup(props, { emit }) {
const getModalOptions = computed(() => {
return unref(props.options)
})
console.log(getModalOptions)
const handleClick = function() {
emit('click')
}
const handleCancel = function() {
emit('onClose', true)
}
return {
getModalOptions,
handleClick,
handleCancel
}
}
})
</script>
<style scoped lang='scss'>
</style>

View File

@ -2,13 +2,25 @@
<div> <div>
<n-form ref="formRef" v-bind="getFormOptions"> <n-form ref="formRef" v-bind="getFormOptions">
<template v-for="(item, index) in getFormOptions.info" :key="`${index}-${item.label}`"> <template v-for="(item, index) in getFormOptions.info" :key="`${index}-${item.label}`">
<n-form-item v-if="!item.options" :label="item.label"> <n-form-item v-if="['input'].includes(item.type) || !item.type" :label="item.label">
<n-input v-model:value="getFormOptions.form[item.key]" :placeholder="item.placeholder" /> <n-input v-model:value="getFormOptions.form[item.key]" v-bind="item.props" />
</n-form-item> </n-form-item>
<n-form-item v-if="item.options" :label="item.label"> <n-form-item v-if="['select'].includes(item.type) " :label="item.label">
<n-select v-model:value="getFormOptions.form[item.key]" :options="item.options" /> <n-select v-model:value="getFormOptions.form[item.key]" v-bind="item.props" />
</n-form-item>
<n-form-item v-if="['date'].includes(item.type) " :label="item.label">
<n-date-picker v-model="getFormOptions.form[item.key]" v-bind="item.props" />
</n-form-item> </n-form-item>
</template> </template>
<n-form-item class="form__button">
<n-button @click="handleSearch">查询</n-button>
<n-button @click="handleReset">重置</n-button>
<n-button
v-if="showButton"
type="text"
@click="showMoreItem"
>{{ showItemNum === getFormOptions.info.length - 1 ? '收起' : '展开' }}</n-button>
</n-form-item>
</n-form> </n-form>
</div> </div>
</template> </template>
@ -25,36 +37,49 @@ export default {
default: () => [] default: () => []
} }
}, },
emits: ['search'],
setup(props, { emit }) { setup(props, { emit }) {
// const formOption = reactive({ const showItemNum = ref(3)
// form: { const len = ref(props.info.length - 1)
const showButton = ref(!!(showItemNum.value < len.value))
// } /* 获取传递的props */
// }) const data = reactive({
const getFormRef = computed(() => { info: toRaw(props.info)
const { info } = unref(props) })
const form = ref({}) const form = ref({})
info.forEach((item) => { /* 初始化搜索表单信息 */
function initForm() {
data.info.forEach((item) => {
form.value[item.key] = '' form.value[item.key] = ''
}) })
return unref(form) }
})
console.log(getFormRef)
const getFormOptions = computed(() => { const getFormOptions = computed(() => {
return { return {
form: unref(getFormRef), form: unref(form),
labelWidth: 'auto', labelWidth: 'auto',
labelPlacement: 'left', labelPlacement: 'left',
inline: true, inline: true,
info: [...unref(props).info] info: [...unref(props).info]
} }
}) })
function getFormInfo() { function handleSearch() {
console.log(getFormOptions) emit('search', getFormOptions.value.form)
}
function handleReset() {
initForm()
emit('search', getFormOptions.value.form)
}
function showMoreItem() {
showItemNum.value = showItemNum.value === len.value ? 3 : len.value
} }
return { return {
showItemNum,
showButton,
getFormOptions, getFormOptions,
getFormInfo handleSearch,
handleReset,
showMoreItem
} }
} }
} }
@ -71,5 +96,11 @@ export default {
.n-select{ .n-select{
width: 200px; width: 200px;
} }
transition: all 10s;
}
.form__button{
button+button{
margin-left: 20px;
}
} }
</style> </style>

View File

@ -1,7 +1,7 @@
<template> <template>
<n-menu <n-menu
:mode="menuMode" :mode="menuMode"
:value="(currentRoute.meta && currentRoute.meta.activeMenu) || currentRoute.name" :value="(currentRoute.title && currentRoute.meta.activeMenu) || currentRoute.title"
:options="getMenuOptions" :options="getMenuOptions"
@update:value="handleMenuSelect" @update:value="handleMenuSelect"
/> />
@ -29,6 +29,8 @@ const getMenuOptions = computed(() => {
return generateOptions(permissionStore.routes, '') return generateOptions(permissionStore.routes, '')
}) })
console.log('getMenuOptions', getMenuOptions)
function resolvePath(basePath, path) { function resolvePath(basePath, path) {
if (isExternal(path)) return path if (isExternal(path)) return path
return ( return (
@ -43,10 +45,10 @@ function resolvePath(basePath, path) {
function generateOptions(routes, basePath) { function generateOptions(routes, basePath) {
const options = [] const options = []
routes.forEach((route) => { routes.forEach((route) => {
if (route.name && !route.isHidden) { if (route.title && !route.isHidden) {
const curOption = { const curOption = {
label: (route.meta && route.meta.title) || route.name, label: (route.meta && route.meta.title) || route.title,
key: route.name, key: route.title,
path: resolvePath(basePath, route.path) path: resolvePath(basePath, route.path)
} }
if (route.children && route.children.length) { if (route.children && route.children.length) {

View File

@ -4,7 +4,7 @@ import Home from '@/views/dashboard/index.vue'
export const basicRoutes = [ export const basicRoutes = [
{ {
path: '/login', path: '/login',
name: 'Login', title: 'Login',
component: () => import('@/views/login/index.vue'), component: () => import('@/views/login/index.vue'),
isHidden: true, isHidden: true,
meta: { meta: {
@ -13,16 +13,16 @@ export const basicRoutes = [
}, },
{ {
path: '/', path: '/',
name: 'Dashboard', title: '控制台',
component: Layout, component: Layout,
redirect: '/home', redirect: '/home',
meta: { meta: {
title: 'Dashboard' title: '控制台'
}, },
children: [ children: [
{ {
path: 'home', path: 'home',
name: 'Home', title: 'Home',
component: Home, component: Home,
meta: { meta: {
title: '首页', title: '首页',
@ -34,7 +34,7 @@ export const basicRoutes = [
] ]
export const NOT_FOUND_ROUTE = { export const NOT_FOUND_ROUTE = {
name: 'NOT_FOUND', title: 'NOT_FOUND',
path: '/:pathMatch(.*)*', path: '/:pathMatch(.*)*',
redirect: '/404', redirect: '/404',
isHidden: true isHidden: true
@ -42,7 +42,7 @@ export const NOT_FOUND_ROUTE = {
export const REDIRECT_ROUTE = { export const REDIRECT_ROUTE = {
path: '/redirect', path: '/redirect',
name: 'Redirect', title: 'Redirect',
component: Layout, component: Layout,
meta: { meta: {
title: 'Redirect', title: 'Redirect',

View File

@ -1,6 +1,6 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { asyncRoutes, basicRoutes } from '@/router/routes' import { asyncRoutes, basicRoutes } from '@/router/routes'
import { getMenu } from '@/api/system/menu' import { getMenu } from '@/api/auth/index'
import Layout from '@/layout/index.vue' import Layout from '@/layout/index.vue'
import modules from '@/utils/module.js' import modules from '@/utils/module.js'
@ -53,19 +53,36 @@ function dataArrayToRoutes(routes) {
const res = [] const res = []
routes.forEach(item => { routes.forEach(item => {
const tmp = { ...item } const tmp = { ...item }
// 如果有component配置 // // 如果有component配置
if (tmp.component) { // if (tmp.component) {
// // Layout引入
// if (tmp.component === 'Layout') {
// tmp.component = Layout
// } else {
// const sub_view = tmp.component.replace(/^\/*/g, '')
// const component = `../${sub_view}.vue`
// tmp.component = modules[component]
// }
// if (tmp.children) {
// tmp.children = dataArrayToRoutes(tmp.children)
// }
// }
// 如果pid为0
if (tmp.pid === 0) {
// Layout引入 // Layout引入
if (tmp.component === 'Layout') { tmp.component = Layout
tmp.component = Layout
} else {
const sub_view = tmp.component.replace(/^\/*/g, '')
const component = `../${sub_view}.vue`
tmp.component = modules[component]
}
if (tmp.children) { if (tmp.children) {
tmp.children = dataArrayToRoutes(tmp.children) tmp.children = dataArrayToRoutes(tmp.children)
} }
} else {
const sub_view = tmp.component.replace(/^\/*/g, '')
const component = `../${sub_view}.vue`
tmp.component = modules[component]
}
tmp.name = tmp.title
tmp.meta = {
...tmp.meta,
title: tmp.title
} }
res.push(tmp) res.push(tmp)
}) })
@ -97,6 +114,7 @@ export const usePermissionStore = defineStore('permission', {
const res = await getMenu() const res = await getMenu()
if (res.code === 0) { if (res.code === 0) {
const result = dataArrayToRoutes(res.data) const result = dataArrayToRoutes(res.data)
console.log(result)
this.accessRoutes = result this.accessRoutes = result
return Promise.resolve(result) return Promise.resolve(result)
} else { } else {

View File

@ -0,0 +1,50 @@
<template>
<Modal :options="getModalOptions">
<template #Context>
111
</template>
</Modal>
</template>
<script>
import { defineComponent, computed } from 'vue'
import Modal from '@/components/Modal/index.vue'
export default defineComponent({
name: 'MenuModal',
components: { Modal },
props: {
visible: {
type: Boolean,
default: false
},
row: {
type: Object,
default: () => {}
}
},
emits: {
'update:visible': null,
onClose: null,
done: null
},
setup(props, { emit }) {
const getModalOptions = computed(() => {
return {
visible: props.visible
}
})
/* 关闭弹窗 */
const handleClose = () => {
// vodModal.value.handleUploadCancel()
emit('update:visible', false)
}
return {
getModalOptions
}
}
})
</script>
<style scoped lang='scss'>
</style>

View File

@ -3,24 +3,27 @@
<n-card> <n-card>
<data-table :columns="data.columns" :pagination="false" :data="data.data" size="large"> <data-table :columns="data.columns" :pagination="false" :data="data.data" size="large">
<template #tableTitle> <template #tableTitle>
<n-button type="primary"> <n-button type="primary" @click="handlleRoleAdd">
添加角色 添加菜单
</n-button> </n-button>
</template> </template>
</data-table> </data-table>
</n-card> </n-card>
</div> </div>
<RoleModal :visible="data.modalShow" />
</template> </template>
<script> <script>
import dataTable from '@/components/DataTable/index.vue' import dataTable from '@/components/DataTable/index.vue'
import RoleModal from './components/RoleModal.vue'
import Action from '@/components/DataTable/tools/Action.vue' import Action from '@/components/DataTable/tools/Action.vue'
import { getMenuList } from '@/api/system/index.js' import { getMenuList } from '@/api/system/index.js'
import { h, onMounted } from 'vue' import { h, onMounted } from 'vue'
import { reactive } from 'vue' import { reactive } from 'vue'
export default { export default {
name: 'MenuPage', name: 'MenuPage',
components: { dataTable }, components: { dataTable, RoleModal },
setup() { setup() {
const data = reactive({ const data = reactive({
columns: [ columns: [
@ -118,7 +121,8 @@ export default {
], ],
data: [ data: [
] ],
modalShow: false
}) })
function play(row) { function play(row) {
@ -133,12 +137,15 @@ export default {
const res = await getMenuList() const res = await getMenuList()
data.data = res.data data.data = res.data
} }
function handlleRoleAdd() {
data.modalShow = true
}
onMounted(() => { onMounted(() => {
fetchList() fetchList()
}) })
return { data } return { data, handlleRoleAdd }
} }
} }

View File

@ -1,10 +1,10 @@
<template> <template>
<div> <div>
<n-card> <n-card>
<headSearch :info="data.info" @search="handleSearch" />
<headSearch :info="data.info" />
<data-table <data-table
ref="tableRef"
:columns="data.columns" :columns="data.columns"
:row-key="(row) => row.id" :row-key="(row) => row.id"
:request="loadDataTable" :request="loadDataTable"
@ -28,7 +28,7 @@
import headSearch from '@/components/Search/index.vue' import headSearch from '@/components/Search/index.vue'
import dataTable from '@/components/DataTable/index.vue' import dataTable from '@/components/DataTable/index.vue'
import TableAction from '@/components/DataTable/tools/Action.vue' import TableAction from '@/components/DataTable/tools/Action.vue'
import { getUserList } from '@/api/system/index.js' import { getRoleList } from '@/api/system/role/index'
import { h, ref, unref } from 'vue' import { h, ref, unref } from 'vue'
import { reactive } from 'vue' import { reactive } from 'vue'
import table from './table.js' import table from './table.js'
@ -79,19 +79,27 @@ export default {
console.log(row) console.log(row)
} }
const params = reactive({ const params = ref({})
name: 'xiaoMa'
}) const tableRef = ref()
function handleSearch(data) {
params.value = {
...data
}
console.log(params.value)
tableRef.value.reFetch({ ...unref(params) })
}
const loadDataTable = async(res) => { const loadDataTable = async(res) => {
const _params = { const _params = {
...unref(params), ...unref(params),
...res ...res
} }
return await getUserList(_params) return await getRoleList(_params)
} }
return { data, loadDataTable } return { data, tableRef, loadDataTable, handleSearch }
} }
} }

View File

@ -2,19 +2,28 @@ const data = [
{ {
label: '角色名称', label: '角色名称',
key: 'name', key: 'name',
placeholder: '请输入角色名称' props: {
}, placeholder: '请输入角色名称'
{ }
label: '角色备注',
key: 'desc'
},
{
label: '角色类型',
key: 'op',
options: [{
label: 11, value: 1
}]
} }
// {
// label: '角色类型',
// type: 'select',
// key: 'op',
// props: {
// options: [{
// label: 11, value: 1
// }]
// }
// },
// {
// label: '角色类型',
// type: 'date',
// key: 'date',
// props: {
// type: 'date'
// }
// }
] ]
export default data export default data

View File

@ -0,0 +1,48 @@
<template>
<Modal :options="getModelOptions">
<template #Context>
添加用户
</template>
</Modal>
</template>
<script>
import Modal from '@/components/Modal/index.vue'
import { defineComponent, computed } from 'vue'
export default {
name: 'UserModal',
components: { Modal },
props: {
visible: {
type: Boolean,
default: false
},
row: {
type: Object,
default: () => {}
}
},
emits: {
'update:visible': null,
onClose: null,
done: null
},
setup(props, { emit }) {
const getModalOptions = computed(() => {
return {
visible: props.visible
}
})
/* 关闭弹窗 */
const handleClose = () => {
// vodModal.value.handleUploadCancel()
emit('update:visible', false)
}
return {
getModalOptions
}
}
}
</script>