新增字典并完善菜单模块
This commit is contained in:
120
web/src/apps/core/AppDictionary/AppDictionary.vue
Normal file
120
web/src/apps/core/AppDictionary/AppDictionary.vue
Normal file
@@ -0,0 +1,120 @@
|
||||
<template>
|
||||
<section class="AppDictionary">
|
||||
<ku-layout v-if="!showDetail" :title="$options.label">
|
||||
<ku-search-bar>
|
||||
<template #left>
|
||||
<el-button type="primary" size="small" icon="iconfont iconAdd" @click="addDict">添加</el-button>
|
||||
</template>
|
||||
<template #right>
|
||||
<el-input size="small" v-model="search.condition" placeholder="数据项" clearable
|
||||
@change="page.current=1,getDicts()" prefix-icon="iconfont iconSearch"/>
|
||||
</template>
|
||||
</ku-search-bar>
|
||||
<el-table :data="dictList" header-cell-class-name="table-header" tooltip-effect="light"
|
||||
row-class-name="table-row" cell-class-name="table-cell" @expand-change="getDictInfo">
|
||||
<el-table-column type="expand">
|
||||
<el-row slot-scope="{row}" type="flex" align="middle" style="flex-wrap: wrap">
|
||||
<el-tag v-for="(op,i) in row.children||[]" :key="i" style="margin: 4px">{{ op.dictKey }}|{{
|
||||
op.dictValue
|
||||
}}
|
||||
{{ op.color ? '| ' + op.color : '' }}
|
||||
</el-tag>
|
||||
</el-row>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="数据项" prop="code"/>
|
||||
<el-table-column align="center" label="数据项名称" prop="dictValue"/>
|
||||
<el-table-column align="center" label="操作">
|
||||
<div slot-scope="{row}">
|
||||
<el-button type="text" @click="openDetail(row.code)" v-text="'编辑'"/>
|
||||
<el-button type="text" @click="handleDelete(row.id)" v-text="'删除'"/>
|
||||
</div>
|
||||
</el-table-column>
|
||||
<div slot="empty" class="no-data"/>
|
||||
</el-table>
|
||||
</ku-layout>
|
||||
<dict-detail v-else :permissions="permissions"/>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DictDetail from "./dictDetail";
|
||||
import KuLayout from "../../../components/KuLayout";
|
||||
import KuSearchBar from "../../../components/KuSearchBar";
|
||||
|
||||
export default {
|
||||
name: "AppDictionary",
|
||||
components: {KuSearchBar, KuLayout, DictDetail},
|
||||
label: "数据字典",
|
||||
props: {
|
||||
permissions: Function
|
||||
},
|
||||
computed: {
|
||||
showDetail() {
|
||||
return this.$route.hash == "#add"
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
page: {current: 1, total: 0, size: 10},
|
||||
search: {condition: ""},
|
||||
dictList: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getDicts() {
|
||||
this.$http.post("/api/dict/list").then(res => {
|
||||
this.dictList = res.data
|
||||
})
|
||||
},
|
||||
addDict() {
|
||||
this.$router.push({hash: "#add"})
|
||||
},
|
||||
handleDelete(ids) {
|
||||
this.$confirm("确定要删除该数据项吗?", {
|
||||
type: "error"
|
||||
}).then(() => {
|
||||
this.$http.post("/api/dict/remove", null, {
|
||||
params: {ids}
|
||||
}).then(res => {
|
||||
if (res?.code == 0) {
|
||||
this.getDicts();
|
||||
this.$message.success("删除成功!")
|
||||
}
|
||||
})
|
||||
}).catch(() => 0)
|
||||
},
|
||||
openDetail(code) {
|
||||
this.$router.push({query: {code}, hash: "#add"})
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.page.size = val;
|
||||
this.getDicts();
|
||||
},
|
||||
getDictInfo(row) {
|
||||
if (row.detail.length) {
|
||||
row.detail = []
|
||||
} else {
|
||||
this.getDict(row.id).then(res => {
|
||||
if (res && res.data) {
|
||||
row.detail = res.data.dictionaryDetails || []
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
getDict(dictionaryId) {
|
||||
return this.$http.post("/admin/dictionary/queryDictDetail", null, {
|
||||
params: {dictionaryId}
|
||||
})
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.getDicts()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AppDictionary {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
170
web/src/apps/core/AppDictionary/dictDetail.vue
Normal file
170
web/src/apps/core/AppDictionary/dictDetail.vue
Normal file
@@ -0,0 +1,170 @@
|
||||
<template>
|
||||
<section class="dictDetail">
|
||||
<ku-layout title="字典信息" @back="$router.push({})">
|
||||
<ai-card title="基本信息">
|
||||
<el-form ref="DictForm" :model="form" :rules="rules" size="small" label-width="110px">
|
||||
<el-form-item required label="字典:" prop="code">
|
||||
<el-input v-model="form.code" clearable placeholder="请输入..."/>
|
||||
</el-form-item>
|
||||
<el-form-item required label="备注:" prop="name">
|
||||
<el-input v-model="form.name" clearable placeholder="请输入..."/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ai-card>
|
||||
<ai-card title="数据值">
|
||||
<template #right>
|
||||
<el-button type="text" icon="iconfont iconAdd" @click="form.children.push({name:'',value:'',editable:true})">
|
||||
添加
|
||||
</el-button>
|
||||
</template>
|
||||
<template #content>
|
||||
<el-table border :data="form.children" header-cell-class-name="table-header" cell-class-name="table-cell">
|
||||
<el-table-column align="center" label="值">
|
||||
<div slot-scope="{row}">
|
||||
<el-input size="small" v-if="row.editable" v-model="row.value" clearable/>
|
||||
<span v-else>{{ row.dictKey }}</span>
|
||||
</div>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="描述">
|
||||
<div slot-scope="{row}">
|
||||
<el-input size="small" v-if="row.editable" v-model="row.name" clearable/>
|
||||
<span v-else>{{ row.dictValue }}</span>
|
||||
</div>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="颜色">
|
||||
<div slot-scope="{row}">
|
||||
<el-color-picker v-if="row.editable" v-model="row.dictColor"/>
|
||||
<span v-else>{{ row.dictColor || '未设置' }}</span>
|
||||
</div>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="操作" width="109px">
|
||||
<div slot-scope="{row,$index}">
|
||||
<section v-if="row.editable">
|
||||
<el-button type="text" icon="iconfont iconCorrect" @click="handleAdd(row)"/>
|
||||
<el-button type="text" icon="iconfont iconClean" @click="cancelEdit(row,$index)"/>
|
||||
</section>
|
||||
<section v-else>
|
||||
<el-button class="dict-detail-operation" type="text" icon="iconfont iconEdit"
|
||||
@click="editDetail(row)"/>
|
||||
<el-button class="dict-detail-operation" type="text" icon="iconfont iconDelete"
|
||||
@click="handleDelete(row.id)"/>
|
||||
</section>
|
||||
</div>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
</ai-card>
|
||||
<template #footer>
|
||||
<el-button @click="$router.push({})">返回</el-button>
|
||||
<el-button type="primary" @click="submit">保存</el-button>
|
||||
</template>
|
||||
</ku-layout>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import KuLayout from "../../../components/KuLayout";
|
||||
|
||||
export default {
|
||||
name: "dictDetail",
|
||||
components: {KuLayout},
|
||||
props: {
|
||||
permissions: Function
|
||||
},
|
||||
computed: {
|
||||
rules() {
|
||||
return {
|
||||
code: [{required: true, message: "请填写数据项"}],
|
||||
name: [{required: true, message: "请填写数据项名称"}],
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: {}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getDict()
|
||||
},
|
||||
methods: {
|
||||
getDict() {
|
||||
const {code} = this.$route.query
|
||||
this.$http.post("/api/dict/list", {params: {code}}).then(res => {
|
||||
if (res?.data) {
|
||||
const info = res.data?.[0]
|
||||
info.children?.map(e => {
|
||||
e.editable = false
|
||||
e.name = ""
|
||||
e.value = ""
|
||||
})
|
||||
this.form = {...info, name: info.dictValue}
|
||||
}
|
||||
})
|
||||
},
|
||||
handleDelete(ids) {
|
||||
this.$confirm("是否要删除该字典值", {
|
||||
type: 'error'
|
||||
}).then(() => {
|
||||
this.$http.post("/dict/remove", null, {
|
||||
params: {ids}
|
||||
}).then(res => {
|
||||
if (res?.code == 0) {
|
||||
this.$message.success("删除成功!")
|
||||
this.getDict()
|
||||
}
|
||||
})
|
||||
}).catch(() => 0)
|
||||
},
|
||||
editDetail(row) {
|
||||
row.editable = true
|
||||
row.name = row.dictValue
|
||||
row.value = row.dictKey
|
||||
},
|
||||
handleAdd(row) {
|
||||
row.dictKey = row.value
|
||||
row.dictValue = row.name
|
||||
this.$http.post("/dict/submit", {parentId: this.form.id, ...row}).then(res => {
|
||||
row.editable = false
|
||||
row = res.data.data
|
||||
this.$message.success("提交成功!")
|
||||
})
|
||||
},
|
||||
cancelEdit(row, index) {
|
||||
if (row.id) {
|
||||
row.editable = false
|
||||
} else {
|
||||
this.form.children?.splice(index, 1)
|
||||
}
|
||||
},
|
||||
submit() {
|
||||
this.$refs.DictForm.validate().then(() => {
|
||||
this.$http.post("/dict/submit", this.form).then(res => {
|
||||
if (res?.code == 0) {
|
||||
this.$message.success("提交成功!")
|
||||
this.$router.push({})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.dictDetail {
|
||||
height: 100%;
|
||||
|
||||
:deep( .el-table__row ) {
|
||||
|
||||
.el-input__inner {
|
||||
padding: 0 30px;
|
||||
border: none;
|
||||
text-align: center;
|
||||
background: #ddd;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
@@ -23,7 +23,7 @@
|
||||
<el-input v-model="form.name" placeholder="请输入" clearable/>
|
||||
</el-form-item>
|
||||
<el-form-item label="菜单类型" prop="type">
|
||||
<ku-select v-model="form.type" clearable :selectList="$dict.getDict('menuType')"/>
|
||||
<ku-select v-model="form.type" clearable :selectList="menuTypes"/>
|
||||
</el-form-item>
|
||||
<template v-if="form.type==0">
|
||||
<el-form-item label="菜单图标" prop="style">
|
||||
@@ -50,7 +50,7 @@
|
||||
</el-form-item>
|
||||
</template>
|
||||
<el-form-item label="显示菜单" prop="status">
|
||||
<ku-select v-model="form.status" clearable :selectList="$dict.getDict('yesOrNo')"/>
|
||||
<ku-select v-model="form.status" clearable dict="yesOrNo"/>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.type<2" label="排序" prop="showIndex">
|
||||
<el-input v-model="form.showIndex" placeholder="请输入" clearable/>
|
||||
@@ -61,19 +61,29 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import KuLayout from "../components/KuLayout";
|
||||
import KuSearchBar from "../components/KuSearchBar";
|
||||
import KuTable from "../components/KuTable";
|
||||
import KuSelect from "../components/KuSelect";
|
||||
import KuDialog from "../components/KuDialog";
|
||||
import KuLayout from "../../components/KuLayout";
|
||||
import KuSearchBar from "../../components/KuSearchBar";
|
||||
import KuTable from "../../components/KuTable";
|
||||
import KuSelect from "../../components/KuSelect";
|
||||
import KuDialog from "../../components/KuDialog";
|
||||
|
||||
export default {
|
||||
name: "AppMenu",
|
||||
components: {KuDialog, KuSelect, KuTable, KuSearchBar, KuLayout},
|
||||
label: "菜单管理",
|
||||
computed: {
|
||||
columns: v => [
|
||||
{label: "菜单名称", prop: "menuName"},
|
||||
{label: "菜单类型", prop: "type", render: (h, {row}) => h(v.menuTypes[row.type])},
|
||||
{label: "应用模块", prop: "component"},
|
||||
{label: "是否显示", prop: "status", dict: "yesOrNo"},
|
||||
{label: "排序", prop: "showIndex"},
|
||||
]
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
search: {name: null},
|
||||
menuTypes: {0: "菜单", 1: "应用", 2: "权限"},
|
||||
tableData: [
|
||||
{
|
||||
id: 1, menuName: "测试", type: "菜单", status: 1, showIndex: 1,
|
||||
@@ -83,13 +93,6 @@ export default {
|
||||
]
|
||||
}
|
||||
],
|
||||
columns: [
|
||||
{label: "菜单名称", prop: "menuName"},
|
||||
{label: "菜单类型", prop: "type"},
|
||||
{label: "应用模块", prop: "component"},
|
||||
{label: "是否显示", prop: "status", dict: "yesOrNo"},
|
||||
{label: "排序", prop: "showIndex"},
|
||||
],
|
||||
dialog: false,
|
||||
form: {},
|
||||
rules: {
|
||||
@@ -121,11 +124,19 @@ export default {
|
||||
|
||||
},
|
||||
submit() {
|
||||
|
||||
this.$refs.MenuForm.validate()
|
||||
.then(() => this.$http.post("/api/menu/submit", this.form))
|
||||
.then(res => {
|
||||
if (res?.code == 0) {
|
||||
this.$message.success("提交成功!")
|
||||
this.dialog = false
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getTableData()
|
||||
this.$dict.load("yesOrNo")
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -6,7 +6,7 @@
|
||||
<el-option v-for="op in actionOps" :key="op.id" :label="op[actionProp.label]" :value="op[actionProp.value]"/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-option v-for="(item, index) in ops" :key="index" :label="item.dictName" :value="item.dictValue"/>
|
||||
<el-option v-for="(v, k) in ops" :key="k" :label="v" :value="k"/>
|
||||
</template>
|
||||
</el-select>
|
||||
</div>
|
||||
@@ -54,7 +54,13 @@ export default {
|
||||
...this.prop
|
||||
}
|
||||
},
|
||||
ops: v => v.dict ? v.$dict.getDict(v.dict) : v.selectList
|
||||
ops: v => {
|
||||
if (v.dict) {
|
||||
const options = {}
|
||||
v.$dict.getDict(v.dict).map(e => options[e.dictValue] = e.dictName)
|
||||
return options
|
||||
} else return v.selectList
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getOptions() {
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
</el-icon>
|
||||
</el-row>
|
||||
<template v-if="menu.expand">
|
||||
<div class="app mar-h8" v-for="app in menu.children" :key="app.id" v-text="app.label" :class="{active:app.id==12}" @click="handleGoto(app.route)"/>
|
||||
<div class="app mar-h8" v-for="app in menu.children" :key="app.id" v-text="app.label"
|
||||
:class="{active:app.id==12}" @click="handleGoto(app.route)"/>
|
||||
</template>
|
||||
</template>
|
||||
<div v-else class="flex pad-h8 center" @click="handleGoto(menu.route)">
|
||||
@@ -59,8 +60,12 @@ export default {
|
||||
this.menus = this.$arr2tree(menus, {parent: "parent"})
|
||||
}
|
||||
}).finally(() => {
|
||||
//超管才有的初始化菜单
|
||||
if (this.menus.length == 0 && this.user.level == 1) {
|
||||
this.menus = [{id: '202302071139', label: "菜单管理", route: "AppMenu"}]
|
||||
this.menus = [
|
||||
{id: '202302071139', label: "菜单管理", route: "AppMenu"},
|
||||
{id: '202302102232', label: "字典管理", route: "AppDictionary"},
|
||||
]
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
@@ -4,7 +4,6 @@ import http from "./axios";
|
||||
* 封装字典工具类
|
||||
*/
|
||||
const $dict = {
|
||||
url: "/api/dict/listByCodes",
|
||||
loading: [],
|
||||
resolves: [],
|
||||
getStorage() {
|
||||
@@ -13,9 +12,15 @@ const $dict = {
|
||||
},
|
||||
getData(codeList) {
|
||||
codeList = [codeList].flat().filter(Boolean).toString()
|
||||
return http.post(this.url, null, {
|
||||
return http.post("/api/dict/listByCodes", null, {
|
||||
withoutToken: true, params: {codeList}
|
||||
}).then(res => res?.data && this.setStorage(res.data))
|
||||
.finally(() => this.setStorage({
|
||||
key: "yesOrNo", values: [
|
||||
{dictValue: '0', dictName: "否"},
|
||||
{dictValue: '1', dictName: "是"}
|
||||
]
|
||||
}))
|
||||
},
|
||||
load(...code) {
|
||||
return new Promise(resolve => {
|
||||
@@ -32,8 +37,8 @@ const $dict = {
|
||||
})
|
||||
},
|
||||
setStorage(data) {
|
||||
let ds = this.getStorage()
|
||||
data.map(p => {
|
||||
let ds = this.getStorage();
|
||||
[data].flat().map(p => {
|
||||
if (ds.some(d => d.key == p.key)) {
|
||||
const index = ds.findIndex(d => d.key == p.key)
|
||||
ds.splice(index, 1, p)
|
||||
|
||||
@@ -6,7 +6,7 @@ import {mainStore} from "./store";
|
||||
let home = {name: "工作台", path: "/", component: () => import('../views/home')},
|
||||
routes = [{name: "登录", path: "/login", component: () => import('../views/login')}]
|
||||
const loadApps = () => {
|
||||
const files = import.meta.glob('../apps/App*.vue'), apps = []
|
||||
const files = import.meta.glob('../apps/**/App*.vue'), apps = []
|
||||
return Promise.all(Object.keys(files).map(path => {
|
||||
return files?.[path]()?.then(file => {
|
||||
if (file.default) {
|
||||
|
||||
Reference in New Issue
Block a user