Commit fa31c71d authored by 赵啸非's avatar 赵啸非

前端重构菜单选择,修改为树形结构

parent 2a384aa2
...@@ -103,6 +103,33 @@ const find = (list, key, val) => { ...@@ -103,6 +103,33 @@ const find = (list, key, val) => {
} }
} }
/**
* 构造树型结构数据
* @param {*} data 数据源
* @param {*} id id字段 默认 'id'
* @param {*} parentId 父节点字段 默认 'parentId'
* @param {*} children 孩子节点字段 默认 'children'
* @param {*} rootId 根Id 默认 0
*/
function handleTree(data, id, parentId, children, rootId) {
id = id || 'id'
parentId = parentId || 'parentId'
children = children || 'children'
rootId = rootId || Math.min.apply(Math, data.map(item => { return item[parentId] })) || 0
//对源数据深度克隆
const cloneData = JSON.parse(JSON.stringify(data))
//循环所有项
const treeData = cloneData.filter(father => {
let branchArr = cloneData.filter(child => {
//返回每一项的子级数组
return father[id] === child[parentId]
});
branchArr.length > 0 ? father.children = branchArr : '';
//返回第一层
return father[parentId] === rootId;
});
return treeData != '' ? treeData : data;
};
export { export {
formatter, formatter,
...@@ -110,4 +137,5 @@ export { ...@@ -110,4 +137,5 @@ export {
formatterDate, formatterDate,
formatterDateOnly, formatterDateOnly,
find, find,
handleTree
}; };
// 添加,编辑设备
<template> <template>
<!-- 弹出框表单 --> <!-- 弹出框表单 -->
<el-dialog :title="title" :visible.sync="open" width="35%" append-to-body> <el-dialog :title="title" :visible.sync="open" width="90%" append-to-body>
<el-form <el-form ref="form" :model="form" :rules="rules" label-width="120px">
ref="form"
:model="form"
:rules="rules"
label-width="110px"
label-position="right"
>
<el-row> <el-row>
<Field <el-col :span="24" v-if="form.parentId !== 0">
:span="22" <el-form-item label="上级节点" prop="parentId">
label="ID" <treeselect
prop="id"
v-model="form.id"
v-if="pageInfo.type !== 'add'"
disabled
/>
<Field :span="22" label="名称" prop="name" v-model="form.name" />
<Field
:span="22"
label="权限类型"
prop="authType"
v-model="form.authType"
:enumData="dict.authType"
type="select"
/>
<Field
:span="22"
label="父级菜单"
prop="parentId"
v-model="form.parentId" v-model="form.parentId"
:enumData="menu" :options="menuOptions"
type="select" :normalizer="normalizer"
/> placeholder="选择上级菜单信息"
<Field :span="22" label="访问地址" prop="url" v-model="form.url" />
<Field
:span="22"
label="状态"
prop="status"
v-model="form.status"
:enumData="dict.status"
type="radio"
/> />
</el-form-item>
</el-col>
<Field <!-- <Field label="ID" prop="id" v-model="form.id" v-if='pageInfo.type !== "add"' disabled />
:span="22" --> <Field label="名称" prop="name" v-model="form.name"/>
label="图标" <Field label="权限类型" prop="authType" v-model="form.authType" :enumData='dict.authType' type='select' />
placeholder="请输入图标名称" <Field label="访问地址" prop="url" v-model="form.url" />
prop="imgPath" <Field label="状态" prop="status" v-model="form.status" :enumData='dict.status' type='radio' />
v-model="form.imgPath" <Field class="radio-group-container" label="图标" prop="imgPath" :span='24'>
/> <el-radio-group v-model="form.imgPath" class='form-el-radio-group'>
<!-- <Field v-else :span="22" label="图标" prop="imgPath"> <el-radio-button style="width: 180px" label="">不需要图标</el-radio-button>
<el-radio-group v-model="form.imgPath" class="form-el-radio-group"> <el-radio-button style="width: 180px" v-for='(icon, index) in icons' :key='index' :label="icon">
<el-radio-button label="">不需要图标</el-radio-button> <i :class="'el-icon-'+icon" style="font-size: 20px"></i>
<el-radio-button {{icon}}
v-for="(icon, index) in icons"
:key="index"
:label="icon"
>
<i :class="'el-icon-' + icon"></i>
{{ icon }}
</el-radio-button> </el-radio-button>
</el-radio-group> </el-radio-group>
</Field> --> </Field>
</el-row> </el-row>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button <el-button type="primary" @click="submitForm">确 定</el-button>
type="primary"
v-if="pageInfo.type !== 'view'"
@click="submitForm"
>确 定</el-button
>
<el-button @click="cancel">取 消</el-button> <el-button @click="cancel">取 消</el-button>
</div> </div>
</el-dialog> </el-dialog>
...@@ -81,55 +39,81 @@ ...@@ -81,55 +39,81 @@
<script> <script>
import form from "@/assets/mixins/formdialog"; import form from "@/assets/mixins/formdialog";
import dialogShow from "./dialogshow"; import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import axios from 'axios'
export default { export default {
mixins: [form], mixins: [form],
components: { components: {
dialogShow, Treeselect,
}, },
computed: { data() {
menu() { return {
let menu = { 0: "" }; fileContent:"",
this.$store.state.userData.barList.forEach((item) => { icons: [
menu[item.id + ""] = item.name; 'info', 'error', 'success', 'warning', 'question',
}); 'tickets', 'document', 'goods', 'sold-out', 'news',
return menu; 'message', 'date', 'printer', 'time', 'bell',
'mobile-phone', 'service', 'view', 'menu', 'star-on',
'location', 'phone', 'picture', 'delete', 'search',
'edit', 'rank', 'refresh', 'share', 'setting',
'upload', 'upload2', 'download', 'loading',
],
menuOptions: [],
// 遮罩层
loading: true,
// 弹出层标题
title: "菜单信息",
// 是否显示弹出层
open: false,
toString:[
"status",
"linkType",
"commMenu",
"menuType",
"authType",
],
// 表单校验
rules: {
}
};
}, },
created() {
axios.get('/icon.txt')
.then(response => {
this.fileContent = response.data
this.icons = this.fileContent.split('\n')
})
}, },
methods: { methods: {
afterSubmit() {
this.$store.dispatch("login");
this.$router.go(-1);
},
/** 编辑 */ /** 编辑 */
edit(row) { edit(row, menuOptions) {
this.reset(); this.reset()
this.query = { id: row.id }; this.query = { id: row.id };
this.urls.currUrl = this.pageInfo.editUrl; this.urls.currUrl =this.pageInfo.editUrl;;
this.getData(); this.getData();
this.pageInfo.type = "edit"; this.menuOptions = menuOptions;
this.title = "修改菜单"; this.title = "修改菜单信息";
}, },
/** 新增 */ /** 新增 */
add(row) { add(row, menuOptions) {
this.reset(); this.reset()
this.query = { id: row.id }; this.query = { id: row.id };
this.urls.currUrl = this.pageInfo.addUrl; this.urls.currUrl = this.pageInfo.addUrl;
this.getData(); this.getData();
this.pageInfo.type = "add"; if(row.id){
this.open = true; this.form.parentId=row.id
this.title = "新增菜单"; }
this.menuOptions = menuOptions;
this.title = "新增菜单信息";
}, },
/** 查看*/ /** 查看*/
view(row) { view(row, menuOptions) {
this.reset();
this.query = { id: row.id }; this.query = { id: row.id };
this.urls.currUrl = this.pageInfo.viewUrl; this.urls.currUrl =this.pageInfo.viewUrl;;
this.getData(); this.getData();
this.pageInfo.type = "view"; this.menuOptions = menuOptions;
this.open = true; this.title = "菜单信息详细";
this.title = "菜单详细";
}, },
/**取消按钮 */ /**取消按钮 */
cancel() { cancel() {
...@@ -139,14 +123,42 @@ export default { ...@@ -139,14 +123,42 @@ export default {
afterRender(data) { afterRender(data) {
this.open = true; this.open = true;
}, },
afterSubmit(data) { afterSubmit(data) {
this.open = false; this.open = false;
this.$emit("ok"); this.$emit("ok");
}, },
/** 转换菜单信息数据结构 */
normalizer(node) {
if (node.children && !node.children.length) {
delete node.children;
}
return {
id: node.id,
label: node.name,
children: node.children,
};
},
// 表单重置 // 表单重置
reset() { reset() {
// this.form={} this.form = {
name : null,
url : null,
ancestors : null,
parentId : null,
orderId : null,
status : 1,
linkType : 0,
groupId : 1,
groupName : null,
imgPath : null,
buttonImgPath : null,
imgCommPath : null,
commMenu : 0,
menuType : 0,
authType : 3,
createUserName : null,
};
this.resetForm("form"); this.resetForm("form");
}, },
resetForm(refName) { resetForm(refName) {
...@@ -155,74 +167,42 @@ export default { ...@@ -155,74 +167,42 @@ export default {
} }
}, },
}, },
data() {
return {
// 遮罩层
loading: true,
// 弹出层标题
title: "菜单",
// 是否显示弹出层
open: false,
toString: ["parentId", "authType", "status"],
icons: [
"info",
"error",
"success",
"warning",
"question",
"tickets",
"document",
"goods",
"sold-out",
"news",
"message",
"date",
"printer",
"time",
"bell",
"mobile-phone",
"service",
"view",
"menu",
"star-on",
"location",
"phone",
"picture",
"delete",
"search",
"edit",
"rank",
"refresh",
"share",
"setting",
"upload",
"upload2",
"download",
"loading",
"reading",
],
rules: {
name: [{ required: true, message: "请输入名称", trigger: "blur" }],
},
};
},
}; };
</script> </script>
<style lang="less"> <style lang="scss">
.el-select { .ml-row {
width: 100%; margin-bottom: 5px;
}
.el-date-editor.el-input {
width: 100%;
}
.form-el-radio-group.label {
width: 160px;
} }
.el-radio-button__inner { .el-radio-button__inner {
border: 0; // width: 82px;
height: 36px;
border-radius: 4px 0px 0px 4px;
border: 1px solid rgba(0, 0, 0, 0) !important;
border-radius: 2px !important;
background-color: rgba(0, 0, 0, 0);
font-size: 14px;
font-weight: 400;
color: #606677;
line-height: 14px;
outline: none;
box-shadow: none;
} }
</style>
.el-radio-button__orig-radio:checked+.el-radio-button__inner {
background: rgba(0, 0, 0, 0);
border: 1px solid #3E7BFA !important;
color: #3E7BFA;
line-height: 14px;
outline: none;
box-shadow: none;
}
.ml-top-button {
border-color: #ffffff;
background: rgba(0, 0, 0, 0);
font-size: 16px;
margin: 0 10px 0 10px;
}
</style>
// 添加,编辑设备
<template>
<!-- 弹出框表单 -->
<el-dialog :title="title" :visible.sync="open" width="35%" append-to-body>
<el-form
ref="form"
:model="form"
:rules="rules"
label-width="110px"
label-position="right"
>
<el-row>
<Field
:span="22"
label="ID"
prop="id"
v-model="form.id"
v-if="pageInfo.type !== 'add'"
disabled
/>
<Field :span="22" label="名称" prop="name" v-model="form.name" />
<Field
:span="22"
label="权限类型"
prop="authType"
v-model="form.authType"
:enumData="dict.authType"
type="select"
/>
<Field
:span="22"
label="父级菜单"
prop="parentId"
v-model="form.parentId"
:enumData="menu"
type="select"
/>
<Field :span="22" label="访问地址" prop="url" v-model="form.url" />
<Field
:span="22"
label="状态"
prop="status"
v-model="form.status"
:enumData="dict.status"
type="radio"
/>
<Field
:span="22"
label="图标"
placeholder="请输入图标名称"
prop="imgPath"
v-model="form.imgPath"
/>
<!-- <Field v-else :span="22" label="图标" prop="imgPath">
<el-radio-group v-model="form.imgPath" class="form-el-radio-group">
<el-radio-button label="">不需要图标</el-radio-button>
<el-radio-button
v-for="(icon, index) in icons"
:key="index"
:label="icon"
>
<i :class="'el-icon-' + icon"></i>
{{ icon }}
</el-radio-button>
</el-radio-group>
</Field> -->
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button
type="primary"
v-if="pageInfo.type !== 'view'"
@click="submitForm"
>确 定</el-button
>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
</template>
<script>
import form from "@/assets/mixins/formdialog";
import dialogShow from "./dialogshow";
export default {
mixins: [form],
components: {
dialogShow,
},
computed: {
menu() {
let menu = { 0: "无" };
this.$store.state.userData.barList.forEach((item) => {
menu[item.id + ""] = item.name;
});
return menu;
},
},
methods: {
afterSubmit() {
this.$store.dispatch("login");
this.$router.go(-1);
},
/** 编辑 */
edit(row) {
this.reset();
this.query = { id: row.id };
this.urls.currUrl = this.pageInfo.editUrl;
this.getData();
this.pageInfo.type = "edit";
this.title = "修改菜单";
},
/** 新增 */
add(row) {
this.reset();
this.query = { id: row.id };
this.urls.currUrl = this.pageInfo.addUrl;
this.getData();
this.pageInfo.type = "add";
this.open = true;
this.title = "新增菜单";
},
/** 查看*/
view(row) {
this.reset();
this.query = { id: row.id };
this.urls.currUrl = this.pageInfo.viewUrl;
this.getData();
this.pageInfo.type = "view";
this.open = true;
this.title = "菜单详细";
},
/**取消按钮 */
cancel() {
this.open = false;
},
/**获取数据后弹框 */
afterRender(data) {
this.open = true;
},
afterSubmit(data) {
this.open = false;
this.$emit("ok");
},
// 表单重置
reset() {
// this.form={}
this.resetForm("form");
},
resetForm(refName) {
if (this.$refs[refName]) {
this.$refs[refName].resetFields();
}
},
},
data() {
return {
// 遮罩层
loading: true,
// 弹出层标题
title: "菜单",
// 是否显示弹出层
open: false,
toString: ["parentId", "authType", "status"],
icons: [
"info",
"error",
"success",
"warning",
"question",
"tickets",
"document",
"goods",
"sold-out",
"news",
"message",
"date",
"printer",
"time",
"bell",
"mobile-phone",
"service",
"view",
"menu",
"star-on",
"location",
"phone",
"picture",
"delete",
"search",
"edit",
"rank",
"refresh",
"share",
"setting",
"upload",
"upload2",
"download",
"loading",
"reading",
],
rules: {
name: [{ required: true, message: "请输入名称", trigger: "blur" }],
},
};
},
};
</script>
<style lang="less">
.el-select {
width: 100%;
}
.el-date-editor.el-input {
width: 100%;
}
.form-el-radio-group.label {
width: 160px;
}
.el-radio-button__inner {
border: 0;
}
</style>
<template>
<div class="page">
<!-- <LayoutTable :data='tableData' :config='tableConfig' notPagination /> -->
<!-- <dialog-show ref="dialogform" @ok="getData" /> -->
<el-table
:data="tableData"
style="width: 100%;margin-bottom: 20px;"
row-key="id"
border
default-expand-all
:tree-props="{children: 'children', hasChildren: 'hasChildren'}">
<el-table-column
v-for="(item,index) in config.columns" :key="index"
:prop="item.prop"
:label="item.label"
width="180">
</el-table-column>
</el-table>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="query.page"
:page-sizes="[10, 20, 30, 40]"
:page-size="query.size"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
</template>
<script>
// import table from '@/assets/mixins/table';
import dialogShow from "./dialogshow";
export default {
// mixins: [table],
components: { dialogShow },
methods: {
// 菜单表格
gettableList(){
this.$post('/menu/list',this.query).then(res => {
if(res.code == 1){
// 原数组
let arr = res.data.data
this.tableData = this.resetTableList(arr)
this.total = res.data.total
}
})
},
// 重排表格
resetTableList(arr){
let result = arr.map(item => {
// 一级目录
if(item.childList.length == 0){
return {
...item,
children:[]
}
}else if(item.childList.length > 0){
return {
...item,
children:this.resetTableList(item.childList)
}
}
})
return result
},
//
handleSizeChange(size){
this.query.size = size
this.gettableList()
},
handleCurrentChange(page){
this.query.page = page
this.gettableList()
},
beforeRender(data) {
this.allMenu = this.sortByGroup(this.util_copy(data.data));
console.log(this.allMenu,'菜单数据')
// 存在查询条件,展开全部
if(Object.keys(this.$route.query).length) {
this.select = this.allMenu.filter(i=>!i.parentId).map(i=>i.id);
}
return data;
},
afterRender() {
this.showChild();
},
// 按parentId排序分组
sortByGroup(data) {
return data.filter(i=>!i.parentId).reduce((prev, item)=>{
return prev.concat([item], data.filter(i=>i.parentId == item.id))
}, [])
},
//重排table
resetTable(arr){
// 一级父级
},
// 查看下级菜单
selectHandler({id}) {
// 如果已展开,则关闭
const index = this.select.indexOf(id);
if(index > -1) {
this.select.splice(index, 1);
}else{
this.select.push(id);
}
this.showChild();
},
showChild() {
this.tableData.data = this.allMenu.filter(item=>{
return !item.parentId || this.select.indexOf(item.parentId) > -1
})
},
// 展示菜单图标
showIcon(row, column) {
return <i class={'el-icon-'+row.imgPath}></i>
},
// 操作菜单状态
changeStatus(row, column) {
return (
<my-switch
confirm
url='/menu/save'
row={row}
onChange={this.statusChange}
value={this.tableData.data}
onInput={(data)=>{
this.tableData.data = data;
}}/>
)
},
afterDel(id) {
this.$store.dispatch('login');
},
statusChange() {
this.$store.dispatch('login');
},
handleUp(data) {
let type = 0;
let url = "/menu/upOrDown";
this.switchSort(url, data.id, type);
},
handleDown(data) {
let type = 1;
let url = "/menu/upOrDown";
this.switchSort(url, data.id, type);
},
switchSort(url, id, type) {
this.loading = true;
this.$post(url, {
id: id,
type: type,
})
.then((res) => {
if (res && res.code && res.code == 1) {
this.getData()
this.loading = false;
this.$message.success("更新排序成功!");
}
})
.catch((error) => {
this.loading = false;
this.$message.error(error.message);
});
},
/** 重写新增方法 */
// toAdd(row) {
// this.$refs.dialogform.add(row);
// },
// /** 重写编辑方法 */
// toEdit(row) {
// this.$refs.dialogform.edit(row);
// },
// /** 重写查看方法 */
// toView(row) {
// this.$refs.dialogform.view(row);
// },
},
data() {
return {
tableData:[],
allMenu: [], // 经过分组排序的表格数据
select: [], // 当前展开的树节点
query: {
page:1,
size:10
},
total:0,
config: {
search: [
{
name: 'name',
type: 'text',
label: '菜单名称',
},
],
columns: [
// { type: "selection",reserveSelection:true, width: 60 },
// { type: "index", label: "序号",align:"center", width: 50 },
// {
// width: 60,
// formatter: row => {
// const icon = this.select.indexOf(row.id) === -1 ? 'right' : 'down';
// return (
// !row.parentId||row.childList.length>0
// ? <div onClick={()=>{this.selectHandler(row)}}>
// <i class={'el-icon-arrow-'+icon}></i>
// </div>
// : ''
// )
// }
// },
{
prop: 'id',
label: 'ID',
width: 60,
},
{
prop: 'name',
label: '名称',
width: 160,
},
{
prop: 'imgPath',
label: '图标',
width: 120,
// formatter: this.showIcon,
},
{
prop: 'authType',
label: '权限类型',
formatter: this.formatter,
},
{
prop: 'parentId',
label: '父ID',
},
{
prop: 'url',
label: '地址',
},
{
prop: 'status',
label: '状态',
width: 100,
formatter: this.changeStatus,
},
// {
// label: '操作',
// formatter: (row)=> {
// return (
// <div>
// <el-link
// style="margin-right:5px;margin-left:5px"
// icon="el-icon-top"
// onClick={() => {
// this.handleUp(row);
// }}
// ></el-link>
// <el-link
// style="margin-right:5px;margin-left:5px"
// icon="el-icon-bottom"
// onClick={() => {
// this.handleDown(row);
// }}
// ></el-link>
// <table-buttons noView row={row} onEdit={this.toEdit} onDel={this.toDel} />
// </div>
// )
// },
// },
],
},
}
},
created(){
this.gettableList()
}
}
</script>
/**
* 文件:MenuDao.java
* 版本:1.0.0
* 日期:
* Copyright &reg;
* All right reserved.
*/
package com.mortals.xhx.base.system.menu.dao; package com.mortals.xhx.base.system.menu.dao;
import com.mortals.framework.dao.ICRUDDao; import com.mortals.framework.dao.ICRUDDao;
import com.mortals.xhx.base.system.menu.model.MenuEntity; import com.mortals.xhx.base.system.menu.model.MenuEntity;
import java.util.List;
/** /**
* <p>Title: 菜单信息</p> * 菜单信息Dao
* <p>Description: MenuDao DAO接口 </p> * 菜单信息 DAO接口
* <p>Copyright: Copyright &reg; </p> *
* <p>Company: </p> * @author zxfei
* @author * @date 2023-04-10
* @version 1.0.0 */
*/
public interface MenuDao extends ICRUDDao<MenuEntity,Long> { public interface MenuDao extends ICRUDDao<MenuEntity,Long>{
/**
* 查询子节点
*
* @param
* @return
*/
List<MenuEntity> selectChildrenMenuById(String menuId);
} }
/**
* 文件:MenuDaoImpl.java
* 版本:1.0.0
* 日期:
* Copyright &reg;
* All right reserved.
*/
package com.mortals.xhx.base.system.menu.dao.ibatis; package com.mortals.xhx.base.system.menu.dao.ibatis;
import com.mortals.framework.dao.ibatis.BaseCRUDDaoMybatis; import com.mortals.framework.dao.ibatis.BaseCRUDDaoMybatis;
import com.mortals.xhx.base.system.menu.dao.MenuDao; import com.mortals.xhx.base.system.menu.dao.MenuDao;
import com.mortals.xhx.base.system.menu.model.MenuEntity; import com.mortals.xhx.base.system.menu.model.MenuEntity;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.util.List;
/** /**
* <p>Title: 菜单信息</p> * 菜单信息DaoImpl DAO接口
* <p>Description: MenuDaoImpl DAO接口 </p> *
* <p>Copyright: Copyright &reg; </p> * @author zxfei
* <p>Company: </p> * @date 2023-04-10
* @author */
* @version 1.0.0
*/
@Repository("menuDao") @Repository("menuDao")
public class MenuDaoImpl extends BaseCRUDDaoMybatis<MenuEntity,Long> implements MenuDao { public class MenuDaoImpl extends BaseCRUDDaoMybatis<MenuEntity,Long> implements MenuDao {
@Override
public List<MenuEntity> selectChildrenMenuById(String menuId) {
return getSqlSession().selectList(getSqlId("selectChildrenMenuById"), menuId);
}
} }
package com.mortals.xhx.base.system.menu.model;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
import java.util.stream.Collectors;
/**
* 菜单信息前端映射树结构实体类
*
* @author zxfei
* @date 2023-04-10
*/
@Data
public class MenuTreeSelect implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 节点ID
*/
private Long id;
/**
* 节点名称
*/
private String label;
/**
* 子节点
*/
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private List<MenuTreeSelect> children;
public MenuTreeSelect(MenuEntity entity) {
this.id = entity.getId();
this.label = entity.getName();
this.children = entity.getChildList().stream().map(MenuTreeSelect::new).collect(Collectors.toList());
}
}
\ No newline at end of file
package com.mortals.xhx.base.system.menu.model.vo;
import com.mortals.framework.model.BaseEntityLong;
import com.mortals.xhx.base.system.menu.model.MenuEntity;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* 菜单信息视图对象
*
* @author zxfei
* @date 2023-04-10
*/
@Data
public class MenuVo extends BaseEntityLong {
/** 子菜单信息 */
private List<MenuEntity> childList = new ArrayList<>();
private Integer type;
}
\ No newline at end of file
/**
* 文件:MenuService.java
* 版本:1.0.0
* 日期:
* Copyright &reg;
* All right reserved.
*/
package com.mortals.xhx.base.system.menu.service; package com.mortals.xhx.base.system.menu.service;
import com.mortals.framework.exception.AppException; import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.framework.service.ICRUDService; import com.mortals.framework.service.ICRUDService;
import com.mortals.framework.service.IUser; import com.mortals.framework.service.IUser;
import com.mortals.xhx.base.system.menu.model.MenuEntity; import com.mortals.xhx.base.system.menu.model.MenuEntity;
import com.mortals.xhx.base.system.menu.model.MenuTreeSelect;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
/** /**
* <p>Title: 菜单信息</p> * MenuService
* <p>Description: MenuService service接口 </p> * <p>
* <p>Copyright: Copyright &reg; </p> * 菜单信息 service接口
* <p>Company: </p> *
* @author * @author zxfei
* @version 1.0.0 * @date 2023-04-10
*/ */
public interface MenuService extends ICRUDService<MenuEntity, Long> {
public interface MenuService extends ICRUDService<MenuEntity,Long> {
/** /**
* 获取所有可用菜单 * 获取所有可用菜单
* *
...@@ -56,8 +49,47 @@ public interface MenuService extends ICRUDService<MenuEntity,Long> { ...@@ -56,8 +49,47 @@ public interface MenuService extends ICRUDService<MenuEntity,Long> {
/** /**
* 更新排列顺序 * 更新排列顺序
*
* @param id * @param id
* @param type * @param type
*/ */
void upOrDown(Long id, Integer type); void upOrDown(Long id, Integer type);
/**
* 是否存在菜单信息节点
*
* @param menuId 菜单信息ID
* @return 结果
*/
boolean hasChildByMenuId(Long menuId);
/**
* 查询菜单信息数据
*
* @param menu 菜单信息
* @return 菜单信息集合
*/
List<MenuEntity> selectMenuList(MenuEntity menu);
/**
* 构建前端所需要下拉树结构
*
* @param menuList 菜单信息列表
* @return 下拉树结构列表
*/
List<MenuTreeSelect> buildMenuTreeSelect(List<MenuEntity> menuList);
/**
* 根据父id查询子节点
*
* @param parentId
* @param context
* @return
*/
List<MenuTreeSelect> getListByParentId(Long parentId, Context context);
Set<Long> getPathSetById(Long id, Context context);
} }
\ No newline at end of file
/**
* 文件:MenuServiceImpl.java
* 版本:1.0.0
* 日期:
* Copyright &reg;
* All right reserved.
*/
package com.mortals.xhx.base.system.menu.service.impl; package com.mortals.xhx.base.system.menu.service.impl;
import com.mortals.framework.common.code.YesNo; import com.mortals.framework.common.code.YesNo;
...@@ -18,23 +10,22 @@ import com.mortals.framework.util.StringUtils; ...@@ -18,23 +10,22 @@ import com.mortals.framework.util.StringUtils;
import com.mortals.xhx.base.system.menu.dao.MenuDao; import com.mortals.xhx.base.system.menu.dao.MenuDao;
import com.mortals.xhx.base.system.menu.model.MenuEntity; import com.mortals.xhx.base.system.menu.model.MenuEntity;
import com.mortals.xhx.base.system.menu.model.MenuQuery; import com.mortals.xhx.base.system.menu.model.MenuQuery;
import com.mortals.xhx.base.system.menu.model.MenuTreeSelect;
import com.mortals.xhx.base.system.menu.service.MenuService; import com.mortals.xhx.base.system.menu.service.MenuService;
import com.mortals.xhx.common.code.SatusEnum;
import com.mortals.xhx.common.code.YesNoEnum; import com.mortals.xhx.common.code.YesNoEnum;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* <p>Title: 菜单信息</p> * MenuService
* <p>Description: MenuServiceImpl service接口 </p> * 菜单信息 service实现
* <p>Copyright: Copyright &reg; </p> *
* <p>Company: </p> * @author zxfei
* * @date 2023-04-10
* @author */
* @version 1.0.0
*/
@Service("menuService") @Service("menuService")
public class MenuServiceImpl extends AbstractCRUDServiceImpl<MenuDao, MenuEntity, Long> implements MenuService { public class MenuServiceImpl extends AbstractCRUDServiceImpl<MenuDao, MenuEntity, Long> implements MenuService {
...@@ -168,8 +159,10 @@ public class MenuServiceImpl extends AbstractCRUDServiceImpl<MenuDao, MenuEntity ...@@ -168,8 +159,10 @@ public class MenuServiceImpl extends AbstractCRUDServiceImpl<MenuDao, MenuEntity
} }
@Override @Override
protected void saveBefore(MenuEntity entity, Context context) throws AppException { protected void saveBefore(MenuEntity entity, Context context) throws AppException {
MenuQuery query = new MenuQuery(); MenuQuery query = new MenuQuery();
query.setParentId(entity.getParentId()); query.setParentId(entity.getParentId());
Comparator<Integer> comparator = Comparator.comparing(Integer::intValue); Comparator<Integer> comparator = Comparator.comparing(Integer::intValue);
...@@ -178,6 +171,188 @@ public class MenuServiceImpl extends AbstractCRUDServiceImpl<MenuDao, MenuEntity ...@@ -178,6 +171,188 @@ public class MenuServiceImpl extends AbstractCRUDServiceImpl<MenuDao, MenuEntity
e=e+1; e=e+1;
entity.setOrderId(e); entity.setOrderId(e);
}); });
MenuEntity parentMenuEntity = this.get(entity.getParentId());
if (!ObjectUtils.isEmpty(parentMenuEntity) && SatusEnum.DISENABLE.getValue() == parentMenuEntity.getStatus()) {
throw new AppException("菜单信息停用,不允许新增");
}
if (!ObjectUtils.isEmpty(parentMenuEntity)) {
entity.setAncestors(parentMenuEntity.getAncestors() + "," + entity.getParentId());
}
super.saveBefore(entity, context); super.saveBefore(entity, context);
} }
@Override
protected void updateBefore(MenuEntity entity, Context context) throws AppException {
MenuEntity newParentEntity = this.get(entity.getParentId());
MenuEntity oldEntity = this.get(entity.getId());
if (!ObjectUtils.isEmpty(newParentEntity) && !ObjectUtils.isEmpty(oldEntity)) {
String newAncestors = newParentEntity.getAncestors() + "," + newParentEntity.getId();
String oldAncestors = oldEntity.getAncestors();
entity.setAncestors(newAncestors);
updateMenuChildren(entity.getId(), newAncestors, oldAncestors, context);
}
super.updateBefore(entity, context);
}
@Override
protected void updateAfter(MenuEntity entity, Context context) throws AppException {
if (SatusEnum.ENABLE.getValue() == entity.getStatus()) {
entity= this.get(entity.getId());
updateParentMenuStatus(entity, context);
}
super.updateAfter(entity, context);
}
/**
* 修改该菜单信息的父级菜单信息状态
*
* @param menu 当前菜单信息
*/
private void updateParentMenuStatus(MenuEntity menu, Context context) {
MenuEntity menuEntity = this.get(menu.getParentId());
if(!ObjectUtils.isEmpty(menuEntity)){
menuEntity.setStatus(SatusEnum.ENABLE.getValue());
menuEntity.setUpdateTime(new Date());
menuEntity.setUpdateUser(context.getUser().getLoginName());
MenuEntity condition = new MenuEntity();
condition.setId(menuEntity.getId());
this.updateBatch(menuEntity, condition, context);
}
}
/**
* 修改子元素关系
*
* @param menuId 被修改的菜单信息ID
* @param newAncestors 新的父ID集合
* @param oldAncestors 旧的父ID集合
*/
public void updateMenuChildren(Long menuId, String newAncestors, String oldAncestors, Context context) {
List<MenuEntity> children = getDao().selectChildrenMenuById(menuId.toString());
for (MenuEntity child : children) {
child.setAncestors(child.getAncestors().replace(oldAncestors, newAncestors));
}
if (children.size() > 0) {
this.updateAfter(children, context);
}
}
@Override
protected void removeBefore(Long[] ids, Context context) throws AppException {
//有子节点 禁止删除
if (hasChildByMenuId(ids[0])) {
throw new AppException("存在下级菜单信息,不允许删除");
}
super.removeBefore(ids, context);
}
@Override
public boolean hasChildByMenuId(Long menuId) {
List<MenuEntity> list = this.find(new MenuQuery().parentId(menuId));
return list.size() > 0 ? true : false;
}
@Override
public List<MenuEntity> selectMenuList(MenuEntity menu) {
return this.find(new MenuQuery());
}
@Override
public List<MenuTreeSelect> buildMenuTreeSelect(List<MenuEntity> list) {
List<MenuEntity> returnList = new ArrayList<>();
List<Long> tempList = list.stream().map(MenuEntity::getId).collect(Collectors.toList());
for (Iterator<MenuEntity> iterator = list.iterator(); iterator.hasNext(); ) {
MenuEntity menuEntity = iterator.next();
if (!tempList.contains(menuEntity.getParentId())) {
recursionFn(list, menuEntity);
returnList.add(menuEntity);
}
}
if (returnList.isEmpty()) {
returnList = list;
}
return returnList.stream().map(MenuTreeSelect::new).collect(Collectors.toList());
}
/**
* 递归列表
*/
private void recursionFn(List<MenuEntity> list, MenuEntity t) {
// 得到子节点列表
List<MenuEntity> childList = getChildList(list, t);
t.setChildList(childList);
for (MenuEntity tChild : childList) {
if (hasChild(list, tChild)) {
recursionFn(list, tChild);
}
}
}
/**
* 判断是否有子节点
*/
private boolean hasChild(List<MenuEntity> list, MenuEntity t) {
return getChildList(list, t).size() > 0 ? true : false;
}
/**
* 得到子节点列表
*/
private List<MenuEntity> getChildList(List<MenuEntity> list, MenuEntity t) {
return list.stream().map(item->{
if (!ObjectUtils.isEmpty(item.getParentId()) && item.getParentId() == t.getId()) {
return item;
}
return null;
}).filter(f->f!=null).collect(Collectors.toList());
}
@Override
public List<MenuTreeSelect> getListByParentId(Long parentId, Context context) {
if (ObjectUtils.isEmpty(parentId)) {
parentId = 0L;
}
//只做一层
List<MenuTreeSelect> collect = this.find(new MenuQuery().parentId(parentId), context).stream().map(item -> new MenuTreeSelect(item)
).collect(Collectors.toList());
if ("0".equals(parentId)) {
return collect;
}
return collect;
}
@Override
public Set<Long> getPathSetById(Long id, Context context) {
Set<Long> idSet = new HashSet<>();
//idSet.add(id);
MenuEntity menuEntity = this.get(id, context);
if(!ObjectUtils.isEmpty(menuEntity)){
return extracted(context, idSet, menuEntity);
}
return idSet;
}
private Set<Long> extracted(Context context, Set<Long> idSet, MenuEntity menuEntity) {
MenuEntity parentMenu = this.get(menuEntity.getParentId(), context);
if(!ObjectUtils.isEmpty(parentMenu)){
idSet.add(parentMenu.getId());
return extracted(context,idSet,parentMenu);
}
return idSet;
}
} }
\ No newline at end of file
package com.mortals.xhx.base.system.menu.web; package com.mortals.xhx.base.system.menu.web;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.exception.AppException; import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context; import com.mortals.framework.model.Context;
import com.mortals.framework.model.OrderCol; import com.mortals.framework.model.OrderCol;
import com.mortals.framework.web.BaseCRUDJsonBodyMappingController; import com.mortals.framework.web.BaseCRUDJsonBodyMappingController;
import com.mortals.xhx.base.system.menu.model.MenuQuery;
import org.springframework.web.bind.annotation.*;
import com.mortals.framework.web.BaseCRUDJsonMappingController;
import com.mortals.xhx.base.system.menu.model.MenuEntity; import com.mortals.xhx.base.system.menu.model.MenuEntity;
import com.mortals.xhx.base.system.menu.model.MenuQuery;
import com.mortals.xhx.base.system.menu.model.MenuTreeSelect;
import com.mortals.xhx.base.system.menu.service.MenuService; import com.mortals.xhx.base.system.menu.service.MenuService;
import com.mortals.xhx.common.code.DataSatus; import com.mortals.xhx.base.system.param.service.ParamService;
import com.mortals.xhx.common.code.MenuAuthType; import com.mortals.xhx.common.code.*;
import com.mortals.xhx.common.code.MenuComm; import org.springframework.beans.factory.annotation.Autowired;
import com.mortals.xhx.common.code.MenuLinkType; import org.springframework.web.bind.annotation.*;
import com.mortals.xhx.common.code.MenuType;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
import static com.mortals.framework.ap.SysConstains.RESULT_KEY;
/** /**
* 菜单信息 *
* * 菜单信息
* @author: zxfei *
* @date: 2021/11/30 10:02 * @author zxfei
*/ * @date 2023-04-10
*/
@RestController @RestController
@RequestMapping("menu") @RequestMapping("menu")
public class MenuController extends BaseCRUDJsonBodyMappingController<MenuService, MenuEntity, Long> { public class MenuController extends BaseCRUDJsonBodyMappingController<MenuService,MenuEntity,Long> {
public MenuController() { @Autowired
super.setModuleDesc("菜单信息"); private ParamService paramService;
}
@Override @Override
...@@ -110,4 +101,88 @@ public class MenuController extends BaseCRUDJsonBodyMappingController<MenuServic ...@@ -110,4 +101,88 @@ public class MenuController extends BaseCRUDJsonBodyMappingController<MenuServic
} }
return ret.toJSONString(); return ret.toJSONString();
} }
@PostMapping("list/exclude")
public String excludeList(@RequestBody MenuEntity query) {
Map<String, Object> model = new HashMap<>();
JSONObject ret = new JSONObject();
String busiDesc = "查询" + this.getModuleDesc();
int code=VALUE_RESULT_SUCCESS;
try {
//查询所有菜单 排除当前菜单路径
Set<Long> idSet = new HashSet<>();
idSet.add(query.getId());
//Set<Long> idSets = this.service.getPathSetById(query.getId(), getContext());
List<MenuEntity> collect = this.service.find(new MenuQuery()).stream().map(item -> {
if(idSet.contains(item.getId())) return null;
//if(idSets.contains(item.getId())) return null;
//ArrayUtils.contains()
// if(ObjectUtils.isEmpty(item.getAncestors())){
// return null;
// }
// if (item.getId().intValue() == id || ArrayUtils.contains(StringUtils.split(item.getAncestors(), ","), id + "")) {
// return null;
// }
return item;
}).filter(f -> f != null).collect(Collectors.toList());
model.put("data", collect);
recordSysLog(request, busiDesc + " 【成功】");
} catch (Exception e) {
code = VALUE_RESULT_FAILURE;
this.doException(request, busiDesc, model, e);
}
ret.put(KEY_RESULT_DATA, model);
ret.put(KEY_RESULT_CODE, code);
return ret.toJSONString();
}
/**
* 获取站点下拉树列表
*/
@PostMapping("treeselect")
public String treeselect(MenuEntity query) {
Map<String, Object> model = new HashMap<>();
JSONObject ret = new JSONObject();
String busiDesc = "查询" + this.getModuleDesc();
int code=VALUE_RESULT_SUCCESS;
try {
List<MenuEntity> list = this.service.find(new MenuQuery());
List<MenuTreeSelect> treeSelects = this.service.buildMenuTreeSelect(list);
model.put("result", treeSelects);
recordSysLog(request, busiDesc + " 【成功】");
} catch (Exception e) {
code = VALUE_RESULT_FAILURE;
this.doException(request, busiDesc, model, e);
}
ret.put(KEY_RESULT_DATA, model);
ret.put(KEY_RESULT_CODE, code);
return ret.toJSONString();
}
/**
* 根据parentId查询子信息
*/
@GetMapping(value = "getListByParentId")
public String getListByParentId(Long parentId) {
JSONObject ret = new JSONObject();
Map<String, Object> model = new HashMap<>();
String busiDesc = "查询" + this.getModuleDesc()+"子节点";
try {
List<MenuTreeSelect> treeList = this.service.getListByParentId(parentId, getContext());
model.put(RESULT_KEY,treeList);
ret.put(KEY_RESULT_CODE, VALUE_RESULT_SUCCESS);
ret.put(KEY_RESULT_DATA, model);
recordSysLog(request, busiDesc+"【成功】");
} catch (Exception e) {
log.error("根据parentId查询子信息错误", e);
this.doException(request, busiDesc, model, e);
ret.put(KEY_RESULT_CODE, VALUE_RESULT_FAILURE);
ret.put(KEY_RESULT_MSG, e.getMessage());
}
return ret.toJSONString();
}
} }
\ No newline at end of file
...@@ -483,6 +483,6 @@ public class StaffEntity extends StaffVo { ...@@ -483,6 +483,6 @@ public class StaffEntity extends StaffVo {
this.remarkId = ""; this.remarkId = "";
this.source = 1; this.source = 2;
} }
} }
\ No newline at end of file
package com.mortals.xhx.module.staff.service.impl; package com.mortals.xhx.module.staff.service.impl;
import com.mortals.xhx.module.staff.model.StaffEntity;
import com.mortals.xhx.module.staff.service.StaffService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl; import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.framework.exception.AppException; import com.mortals.framework.exception.AppException;
...@@ -6,6 +9,9 @@ import com.mortals.framework.model.Context; ...@@ -6,6 +9,9 @@ import com.mortals.framework.model.Context;
import com.mortals.xhx.module.staff.dao.StaffRegularDao; import com.mortals.xhx.module.staff.dao.StaffRegularDao;
import com.mortals.xhx.module.staff.model.StaffRegularEntity; import com.mortals.xhx.module.staff.model.StaffRegularEntity;
import com.mortals.xhx.module.staff.service.StaffRegularService; import com.mortals.xhx.module.staff.service.StaffRegularService;
import java.util.List;
/** /**
* StaffRegularService * StaffRegularService
* 员工转正信息 service实现 * 员工转正信息 service实现
...@@ -15,5 +21,17 @@ import com.mortals.xhx.module.staff.service.StaffRegularService; ...@@ -15,5 +21,17 @@ import com.mortals.xhx.module.staff.service.StaffRegularService;
*/ */
@Service("staffRegularService") @Service("staffRegularService")
public class StaffRegularServiceImpl extends AbstractCRUDServiceImpl<StaffRegularDao, StaffRegularEntity, Long> implements StaffRegularService { public class StaffRegularServiceImpl extends AbstractCRUDServiceImpl<StaffRegularDao, StaffRegularEntity, Long> implements StaffRegularService {
@Autowired
private StaffService staffService;
private void test(){
StaffEntity cache = staffService.getCache("1");
List<StaffEntity> cacheList = staffService.getCacheList();
StaffEntity work001 = staffService.getExtCache("work001");
}
} }
\ No newline at end of file
package com.mortals.xhx.module.staff.service.impl; package com.mortals.xhx.module.staff.service.impl;
import com.mortals.framework.service.impl.AbstractCRUDCacheServiceImpl; import com.mortals.framework.service.impl.AbstractCRUDCacheServiceImpl;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl; import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
...@@ -8,19 +7,21 @@ import com.mortals.framework.model.Context; ...@@ -8,19 +7,21 @@ import com.mortals.framework.model.Context;
import com.mortals.xhx.module.staff.dao.StaffDao; import com.mortals.xhx.module.staff.dao.StaffDao;
import com.mortals.xhx.module.staff.model.StaffEntity; import com.mortals.xhx.module.staff.model.StaffEntity;
import com.mortals.xhx.module.staff.service.StaffService; import com.mortals.xhx.module.staff.service.StaffService;
/** /**
* StaffService * StaffService
* 员工基本信息 service实现 * 员工基本信息 service实现
* *
* @author zxfei * @author zxfei
* @date 2023-04-07 * @date 2023-04-07
*/ */
@Service("staffService") @Service("staffService")
public class StaffServiceImpl extends AbstractCRUDCacheServiceImpl<StaffDao, StaffEntity, Long> implements StaffService { public class StaffServiceImpl extends AbstractCRUDCacheServiceImpl<StaffDao, StaffEntity, Long> implements StaffService {
@Override @Override
protected String getExtKey(StaffEntity data) { protected String getExtKey(StaffEntity data) {
//工号作为redis 扩展key //工号作为redis 扩展key
return data.getWorkNum(); return data.getWorkNum();
} }
......
...@@ -6,6 +6,7 @@ import com.mortals.framework.web.BaseCRUDJsonBodyMappingController; ...@@ -6,6 +6,7 @@ import com.mortals.framework.web.BaseCRUDJsonBodyMappingController;
import com.mortals.xhx.base.system.param.service.ParamService; import com.mortals.xhx.base.system.param.service.ParamService;
import com.mortals.xhx.module.staff.model.StaffEntity; import com.mortals.xhx.module.staff.model.StaffEntity;
import com.mortals.xhx.module.staff.model.vo.HolidayListVo; import com.mortals.xhx.module.staff.model.vo.HolidayListVo;
import com.mortals.xhx.module.staff.model.vo.StaffVo;
import com.mortals.xhx.module.staff.service.StaffService; import com.mortals.xhx.module.staff.service.StaffService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
...@@ -50,6 +51,12 @@ public class StaffController extends BaseCRUDJsonBodyMappingController<StaffServ ...@@ -50,6 +51,12 @@ public class StaffController extends BaseCRUDJsonBodyMappingController<StaffServ
@Override @Override
protected int doListAfter(StaffEntity query, Map<String, Object> model, Context context) throws AppException { protected int doListAfter(StaffEntity query, Map<String, Object> model, Context context) throws AppException {
//
model.put("stat",new StaffVo());
return super.doListAfter(query, model, context); return super.doListAfter(query, model, context);
} }
...@@ -82,4 +89,6 @@ public class StaffController extends BaseCRUDJsonBodyMappingController<StaffServ ...@@ -82,4 +89,6 @@ public class StaffController extends BaseCRUDJsonBodyMappingController<StaffServ
return super.infoAfter(id, model, entity, context); return super.infoAfter(id, model, entity, context);
} }
} }
\ No newline at end of file
...@@ -29,6 +29,7 @@ CREATE TABLE `mortals_xhx_menu` ( ...@@ -29,6 +29,7 @@ CREATE TABLE `mortals_xhx_menu` (
`name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '菜单名称', `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '菜单名称',
`url` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '连接地址', `url` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '连接地址',
`parentId` bigint(20) NULL DEFAULT NULL COMMENT '父菜单ID,一级菜单的该字段值为-1', `parentId` bigint(20) NULL DEFAULT NULL COMMENT '父菜单ID,一级菜单的该字段值为-1',
`ancestors` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '',
`orderId` int(11) NULL DEFAULT NULL COMMENT '排序编号', `orderId` int(11) NULL DEFAULT NULL COMMENT '排序编号',
`status` tinyint(2) NULL DEFAULT 1 COMMENT '菜单状态,0:禁用,1:启用,默认1', `status` tinyint(2) NULL DEFAULT 1 COMMENT '菜单状态,0:禁用,1:启用,默认1',
`linkType` tinyint(2) NULL DEFAULT 0 COMMENT '链接方式,0:普通,1:弹出,2:脚本(JavaScript),默认0', `linkType` tinyint(2) NULL DEFAULT 0 COMMENT '链接方式,0:普通,1:弹出,2:脚本(JavaScript),默认0',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment