新增字典并完善菜单模块

This commit is contained in:
2023-02-10 23:26:27 +08:00
parent 2ee4dc4a97
commit 5ad8759685
7 changed files with 341 additions and 24 deletions

View 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>

View 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>

View File

@@ -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>

View File

@@ -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() {

View File

@@ -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"},
]
}
})
},

View File

@@ -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)

View File

@@ -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) {