Merge branch 'vue-i18n' of https://gitee.com/yuanzbz/vue-admin-perfect into ghpages
Conflicts: src/main.ts
This commit is contained in:
commit
ff44288888
File diff suppressed because it is too large
Load Diff
|
|
@ -25,7 +25,7 @@
|
||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
"dayjs": "^1.11.4",
|
"dayjs": "^1.11.4",
|
||||||
"echarts": "^5.3.1",
|
"echarts": "^5.3.1",
|
||||||
"element-plus": "^2.2.21",
|
"element-plus": "^2.2.28",
|
||||||
"exceljs": "^4.3.0",
|
"exceljs": "^4.3.0",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"fuse.js": "^6.6.2",
|
"fuse.js": "^6.6.2",
|
||||||
|
|
@ -50,6 +50,7 @@
|
||||||
"vue-qr": "^4.0.6",
|
"vue-qr": "^4.0.6",
|
||||||
"vue-router": "^4.1.6",
|
"vue-router": "^4.1.6",
|
||||||
"vue-splitpane": "^1.0.6",
|
"vue-splitpane": "^1.0.6",
|
||||||
|
"vue3-text-clamp": "^0.1.1",
|
||||||
"vuedraggable": "^4.1.0",
|
"vuedraggable": "^4.1.0",
|
||||||
"vuex": "^4.0.0-0",
|
"vuex": "^4.0.0-0",
|
||||||
"xlsx": "^0.18.5"
|
"xlsx": "^0.18.5"
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ registerElIcons(app)
|
||||||
|
|
||||||
app.component('svg-icon',SvgIcon)
|
app.component('svg-icon',SvgIcon)
|
||||||
app.component('PageWrapLayout',PageWrapLayout)
|
app.component('PageWrapLayout',PageWrapLayout)
|
||||||
|
|
||||||
app.use(I18n)
|
app.use(I18n)
|
||||||
app.use(pinia)
|
app.use(pinia)
|
||||||
app.use(router)
|
app.use(router)
|
||||||
|
|
|
||||||
|
|
@ -381,4 +381,96 @@ export const menuData =[
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
export const dictionaryData = [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "性别",
|
||||||
|
"keyCode":'sex',
|
||||||
|
"createTime": "2011-02-25 18:37:39",
|
||||||
|
"remark": "性别",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"name": "证件类型",
|
||||||
|
"keyCode":'idType',
|
||||||
|
"createTime": "2011-02-25 18:37:39",
|
||||||
|
"remark": "证件类型",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
export const dictionaryDetailData = [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"keyCode":'sex',
|
||||||
|
"name": "性别",
|
||||||
|
"createTime": "2011-02-25 18:37:39",
|
||||||
|
"remark": "性别",
|
||||||
|
"children":[
|
||||||
|
{
|
||||||
|
"id": 11,
|
||||||
|
"name": "男",
|
||||||
|
"key":1,
|
||||||
|
"pid":1,
|
||||||
|
"createTime": "2011-02-25 18:37:39",
|
||||||
|
"remark": "男",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 12,
|
||||||
|
"name": "女",
|
||||||
|
"key":0,
|
||||||
|
"pid":1,
|
||||||
|
"createTime": "2011-02-25 18:37:39",
|
||||||
|
"remark": "女",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"keyCode":'idType',
|
||||||
|
"name": "证件类型",
|
||||||
|
"createTime": "2011-02-25 18:37:39",
|
||||||
|
"remark": "证件类型",
|
||||||
|
"children":[
|
||||||
|
{
|
||||||
|
"id": 21,
|
||||||
|
"name": "身份证",
|
||||||
|
"key":1,
|
||||||
|
"pid":2,
|
||||||
|
"createTime": "2011-02-25 18:37:39",
|
||||||
|
"remark": "身份证",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 22,
|
||||||
|
"name": "社保卡",
|
||||||
|
"key":2,
|
||||||
|
"pid":2,
|
||||||
|
"createTime": "2011-02-25 18:37:39",
|
||||||
|
"remark": "社保卡",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 23,
|
||||||
|
"name": "驾驶证",
|
||||||
|
"key":3,
|
||||||
|
"pid":2,
|
||||||
|
"createTime": "2011-02-25 18:37:39",
|
||||||
|
"remark": "驾驶证",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 24,
|
||||||
|
"name": "护照",
|
||||||
|
"key":4,
|
||||||
|
"pid":2,
|
||||||
|
"createTime": "2011-02-25 18:37:39",
|
||||||
|
"remark": "护照",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 25,
|
||||||
|
"name": "工作证",
|
||||||
|
"key":5,
|
||||||
|
"pid":2,
|
||||||
|
"createTime": "2011-02-25 18:37:39",
|
||||||
|
"remark": "工作证",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,12 @@ const functionPageRouter = [{
|
||||||
name: 'fullscreen',
|
name: 'fullscreen',
|
||||||
meta: { title: '元素 全屏', keepAlive: true , icon: 'MenuIcon'}
|
meta: { title: '元素 全屏', keepAlive: true , icon: 'MenuIcon'}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'information-list',
|
||||||
|
component: () => import('@/views/functionPage/informationList/index.vue'),
|
||||||
|
name: 'informationList',
|
||||||
|
meta: { title: '信息列表', keepAlive: true , icon: 'MenuIcon'}
|
||||||
|
},
|
||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,14 @@ const othersRouter = [{
|
||||||
component: () => import('@/views/other/count/index.vue'),
|
component: () => import('@/views/other/count/index.vue'),
|
||||||
name: 'count',
|
name: 'count',
|
||||||
meta: { title: '数字动画', icon: 'MenuIcon' }
|
meta: { title: '数字动画', icon: 'MenuIcon' }
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
path: 'text-clamp',
|
||||||
|
component: () => import('@/views/other/textClamp/index.vue'),
|
||||||
|
name: 'text-clamp',
|
||||||
|
meta: { title: '多行文本省略', icon: 'MenuIcon' }
|
||||||
|
},
|
||||||
|
|
||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,12 @@ const systemRouter = [{
|
||||||
name: 'menu',
|
name: 'menu',
|
||||||
meta: { title: '菜单管理', icon: 'MenuIcon'}
|
meta: { title: '菜单管理', icon: 'MenuIcon'}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'dictionary',
|
||||||
|
component: () => import('@/views/system/dictionary/index.vue'),
|
||||||
|
name: 'dictionary',
|
||||||
|
meta: { title: '字典管理', icon: 'MenuIcon'}
|
||||||
|
},
|
||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
<template>
|
||||||
|
<el-card header="信息列表" class="m-list">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="6" v-for="item in 20">
|
||||||
|
<el-card class="inner" >
|
||||||
|
<div class="header">
|
||||||
|
<div class="title">
|
||||||
|
<div class="border"></div>
|
||||||
|
<div>年度考核目标</div>
|
||||||
|
<div class="text">张三 | 2022-12-30 10:38:24</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
<div class="flex-center item-child">
|
||||||
|
<el-icon><View /></el-icon>
|
||||||
|
<span class="text">预览</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex-center item-child">
|
||||||
|
<el-icon><Edit /></el-icon>
|
||||||
|
<span class="text">编辑</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex-center item-child">
|
||||||
|
<el-icon><Delete /></el-icon>
|
||||||
|
<span class="text">删除</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<Pagination/>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import Pagination from './Pagination'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.m-list{
|
||||||
|
margin-top: 10px;
|
||||||
|
.header{
|
||||||
|
padding: 20px;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
.text{
|
||||||
|
margin-top: 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #D7D7D7;
|
||||||
|
}
|
||||||
|
.title{
|
||||||
|
position: relative;
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
.border{
|
||||||
|
left: 0;
|
||||||
|
position: absolute;
|
||||||
|
border-left:2px solid $primaryColor;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.footer{
|
||||||
|
border-top: 1px solid #e4e7ed;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
.text{
|
||||||
|
margin-left: 6px;
|
||||||
|
}
|
||||||
|
.item-child{
|
||||||
|
flex: 1;
|
||||||
|
padding: 10px 0;
|
||||||
|
color: #7F7F7F;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.item-child:after{
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
height: 20px;
|
||||||
|
border-right:1px solid #e4e7ed;
|
||||||
|
}
|
||||||
|
.item-child:last-child:after{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.inner{
|
||||||
|
::v-deep(.el-card__body){
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
::v-deep(.el-col){
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
<template>
|
||||||
|
<div class="pagination">
|
||||||
|
<el-pagination
|
||||||
|
v-model:currentPage="currentPage"
|
||||||
|
:page-size="10"
|
||||||
|
background
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="1000"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import {ref} from "vue";
|
||||||
|
|
||||||
|
const currentPage = ref(1)
|
||||||
|
|
||||||
|
const handleSizeChange = (val: number) => {
|
||||||
|
console.log(`${val} items per page`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCurrentChange = (val: number) => {
|
||||||
|
currentPage.value = val
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.pagination{
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
<template>
|
||||||
|
<el-card>
|
||||||
|
<el-form :inline="true" :model="formInline" >
|
||||||
|
<el-form-item label="名称">
|
||||||
|
<el-input v-model="formInline.name" placeholder="请输入名称" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="onSubmit">搜索</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { reactive } from 'vue'
|
||||||
|
|
||||||
|
const formInline = reactive({
|
||||||
|
name: '',
|
||||||
|
})
|
||||||
|
|
||||||
|
const onSubmit = () => {
|
||||||
|
console.log('submit!')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
::v-deep(.el-form-item){
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
<template>
|
||||||
|
<div class="item-card">
|
||||||
|
<div class="zb-pro-checkcard" v-for="(item,index) in 5" @click="check(item,index)"
|
||||||
|
:key="item"
|
||||||
|
:class="{
|
||||||
|
'single-active':active===index
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div class="pro-checkcard-content flex-justify-between">
|
||||||
|
<div>今日访问量</div>
|
||||||
|
<div class="num">561</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import {ref} from "vue";
|
||||||
|
|
||||||
|
let active = ref(0)
|
||||||
|
|
||||||
|
const check = (item,index)=>{
|
||||||
|
active.value = index
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.item-card{
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zb-pro-checkcard{
|
||||||
|
box-shadow: 0 2px 12px 0 #0000001a;
|
||||||
|
width: 19.2%;
|
||||||
|
margin-right: 1%;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
background: white;
|
||||||
|
position: relative;
|
||||||
|
.pro-checkcard-content{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
padding: 20px 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.num{
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
.tool{
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
.el-icon-error{
|
||||||
|
color: #F56C6C;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.zb-pro-checkcard:nth-child(5n+5){
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
.single-active{
|
||||||
|
background: #409eff;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
<template>
|
||||||
|
<div class="m-check-card app-container">
|
||||||
|
<SingleCheck/>
|
||||||
|
<Search/>
|
||||||
|
<List/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import SingleCheck from './components/SingleCheck'
|
||||||
|
import Search from './components/Search'
|
||||||
|
import List from './components/List'
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
<template>
|
||||||
|
<PageWrapLayout>
|
||||||
|
<div class="text-clamp-wrap">
|
||||||
|
<text-clamp :text="str" :max-lines="3">
|
||||||
|
<template #after="{ toggle, expanded, clamped }">
|
||||||
|
<el-button type="primary" v-if="expanded || clamped" @click="toggle">{{ expanded?'收起':'展开' }}</el-button>
|
||||||
|
</template>
|
||||||
|
</text-clamp>
|
||||||
|
</div>
|
||||||
|
</PageWrapLayout>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import TextClamp from 'vue3-text-clamp';
|
||||||
|
const str = `Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。`
|
||||||
|
|
||||||
|
const expand = ()=>{
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.text-clamp-wrap{
|
||||||
|
padding: 20px;
|
||||||
|
width: 300px;
|
||||||
|
background: #f8f8f8;
|
||||||
|
border: 1px solid #f1f1f1;
|
||||||
|
border-radius: 2px;
|
||||||
|
line-height: 2;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,110 @@
|
||||||
|
<template>
|
||||||
|
<el-card class="m-dept-side" >
|
||||||
|
<div class="title">字典管理</div>
|
||||||
|
|
||||||
|
<el-button type="primary" @click="addDictsort">
|
||||||
|
<el-icon color="#fff"><Plus /></el-icon><span style="margin-left: 8px">添加字典分类</span>
|
||||||
|
</el-button>
|
||||||
|
|
||||||
|
<el-input v-model="filterText" placeholder="输入关键字进行过滤" class="filter-search"/>
|
||||||
|
|
||||||
|
<div class="filter-tree">
|
||||||
|
<el-scrollbar class="scrollbar">
|
||||||
|
<el-tree
|
||||||
|
ref="treeRef"
|
||||||
|
:data="tableData"
|
||||||
|
:props="defaultProps"
|
||||||
|
default-expand-all
|
||||||
|
:filter-node-method="filterNode"
|
||||||
|
>
|
||||||
|
<template #default="{ node, data }">
|
||||||
|
<span class="custom-tree-node" @click="selectAction(node, data)">
|
||||||
|
<span>{{ node.label }}</span>
|
||||||
|
<span v-if="data.id!=null">
|
||||||
|
<el-button @click.stop="editDictsort(data)" type="primary" link>编辑</el-button>
|
||||||
|
<el-button style="margin-left: 6px" type="danger" link @click.stop="remove(node, data)" >删除</el-button>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-tree>
|
||||||
|
</el-scrollbar>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<DictsortDialog ref="dictsortDialog"/>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import {onBeforeMount, ref, watch} from 'vue'
|
||||||
|
import { ElMessageBox, ElTree } from "element-plus";
|
||||||
|
import DictsortDialog from './dictsortDialog.vue'
|
||||||
|
import { dictionaryData } from '@/mock/system'
|
||||||
|
|
||||||
|
const emit = defineEmits(['change'])
|
||||||
|
|
||||||
|
const tableData = ref<Tree[]>(dictionaryData)
|
||||||
|
const dictsortDialog = ref(null)
|
||||||
|
interface Tree {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
createTime?:string
|
||||||
|
remark?:string
|
||||||
|
children?: Tree[]
|
||||||
|
}
|
||||||
|
|
||||||
|
onBeforeMount( () => {
|
||||||
|
let allObj = {"id":null, "name": "全部"}
|
||||||
|
tableData.value = [allObj,...dictionaryData]
|
||||||
|
});
|
||||||
|
|
||||||
|
const filterText = ref('')
|
||||||
|
const treeRef = ref<InstanceType<typeof ElTree>>()
|
||||||
|
|
||||||
|
const defaultProps = {
|
||||||
|
children: 'children',
|
||||||
|
label: 'name',
|
||||||
|
value:'id'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听输入
|
||||||
|
watch(filterText, (val) => {
|
||||||
|
treeRef.value!.filter(val)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 搜索
|
||||||
|
const filterNode = (value: string, data: Tree) => {
|
||||||
|
console.log(data)
|
||||||
|
if (!value) return true
|
||||||
|
return data.name.includes(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const addDictsort = ()=>{
|
||||||
|
dictsortDialog.value.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
const editDictsort = (item)=>{
|
||||||
|
dictsortDialog.value.show(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectAction = (node, data)=>{
|
||||||
|
emit('change',data)
|
||||||
|
console.log('node, data============',node, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
const remove = (node,data)=>{
|
||||||
|
ElMessageBox.confirm('你确定要删除当前项吗?', '温馨提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
draggable: true,
|
||||||
|
})
|
||||||
|
.then(() => {})
|
||||||
|
.catch(() => {})
|
||||||
|
|
||||||
|
console.log('data===',node,data)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../index.scss";
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,160 @@
|
||||||
|
<template>
|
||||||
|
<div class="m-user-table">
|
||||||
|
<div class="header">
|
||||||
|
<el-form :inline="true" :model="formInline" ref="ruleFormRef">
|
||||||
|
<el-form-item label="名称" prop="username">
|
||||||
|
<el-input v-model="formInline.username" placeholder="请输入名称"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="onSubmit" :icon="Search">查询</el-button>
|
||||||
|
<el-button @click="reset(ruleFormRef)">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
<div class="util">
|
||||||
|
<el-button type="primary" @click="addHandler">
|
||||||
|
<el-icon><Plus /></el-icon>
|
||||||
|
新增字典项
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="table-inner">
|
||||||
|
<el-table
|
||||||
|
v-loading="loading"
|
||||||
|
:data="tableData" style="width: 100%;height: 100%" border>
|
||||||
|
<el-table-column prop="id" label="id" align="center" width="100"/>
|
||||||
|
<el-table-column prop="name" label="名称" align="center" width="100"/>
|
||||||
|
<el-table-column prop="key" label="键值" align="center"/>
|
||||||
|
<el-table-column prop="remark"
|
||||||
|
:show-overflow-tooltip="true"
|
||||||
|
width="180"
|
||||||
|
label="描述" align="center"/>
|
||||||
|
<el-table-column prop="createTime" label="创建时间" align="center" width="180"/>
|
||||||
|
<el-table-column prop="operator" label="操作" width="200px" align="center" fixed="right">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button type="primary" size="small" icon="Edit" @click="editHandler(scope.row)">
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button @click="del(scope.row)" type="danger" size="small" icon="Delete">
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
<div class="pagination">
|
||||||
|
<el-pagination
|
||||||
|
v-model:currentPage="currentPage1"
|
||||||
|
:page-size="10"
|
||||||
|
background
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="1000"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<DictionaryEntryDialog ref="dictionaryEntryDialog"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ElMessageBox, ElMessage, FormInstance } from 'element-plus'
|
||||||
|
import {Search } from '@element-plus/icons-vue'
|
||||||
|
import {onMounted, reactive, ref} from 'vue'
|
||||||
|
import { dictionaryDetailData } from '@/mock/system'
|
||||||
|
import UserDialog from './userDialog.vue'
|
||||||
|
import DictionaryEntryDialog from './dictionaryEntryDialog.vue'
|
||||||
|
|
||||||
|
const tableData = ref(dictionaryDetailData[0].children)
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
const dictionaryEntryDialog = ref()
|
||||||
|
const ruleFormRef = ref<FormInstance>()
|
||||||
|
const formInline = reactive({})
|
||||||
|
const loading = ref(true)
|
||||||
|
const currentPage1 = ref(1)
|
||||||
|
|
||||||
|
const onSubmit = () => {
|
||||||
|
console.log('submit!', formInline)
|
||||||
|
loading.value = true
|
||||||
|
setTimeout(()=>{
|
||||||
|
loading.value = false
|
||||||
|
},1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
const reset = (formEl: FormInstance | undefined) => {
|
||||||
|
loading.value = true
|
||||||
|
setTimeout(()=>{
|
||||||
|
loading.value = false
|
||||||
|
},1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getList = (data)=>{
|
||||||
|
loading.value = true
|
||||||
|
if(!data.id){
|
||||||
|
tableData.value = []
|
||||||
|
}else {
|
||||||
|
let obj = dictionaryDetailData.find(item=>item.id===data.id)
|
||||||
|
tableData.value = obj.children
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(()=>{
|
||||||
|
loading.value = false
|
||||||
|
},500)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const addHandler = () => {
|
||||||
|
dictionaryEntryDialog.value.show()
|
||||||
|
}
|
||||||
|
const editHandler = (row) => {
|
||||||
|
dictionaryEntryDialog.value.show(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
const del = (row) => {
|
||||||
|
ElMessageBox.confirm('你确定要删除当前项吗?', '温馨提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
draggable: true,
|
||||||
|
})
|
||||||
|
.then(() => {})
|
||||||
|
.catch(() => {})
|
||||||
|
}
|
||||||
|
const changeStatus = (row) => {
|
||||||
|
ElMessageBox.confirm(
|
||||||
|
`确定要${!row.status ? '禁用' : '启用'} ${row.username} 账户吗?`,
|
||||||
|
'温馨提示',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.then(async () => {})
|
||||||
|
.catch(() => {
|
||||||
|
row.status = !row.status
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSizeChange = (val: number) => {
|
||||||
|
console.log(`${val} items per page`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCurrentChange = (val: number) => {
|
||||||
|
currentPage1.value = val
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(()=>{
|
||||||
|
setTimeout(()=>{
|
||||||
|
loading.value = false
|
||||||
|
},1000)
|
||||||
|
})
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
getList
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../index";
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
<template>
|
||||||
|
<el-dialog @close="close" v-model="dialogVisible" :title="title" width="50%">
|
||||||
|
<el-form
|
||||||
|
ref="ruleFormRef"
|
||||||
|
:model="ruleForm"
|
||||||
|
:rules="rules"
|
||||||
|
label-width="100px"
|
||||||
|
>
|
||||||
|
<el-form-item label="所属字典" prop="pid">
|
||||||
|
<el-cascader
|
||||||
|
v-model="ruleForm.pid"
|
||||||
|
style="width: 100%"
|
||||||
|
:options="dictionaryData"
|
||||||
|
:props="cascaderProps" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="字典项名称" prop="name">
|
||||||
|
<el-input v-model="ruleForm.name" placeholder="请输入字典项名称"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="字典项键值" prop="key">
|
||||||
|
<el-input v-model="ruleForm.key" placeholder="请输入字典项键值"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="字典项描述" prop="remark" >
|
||||||
|
<el-input v-model="ruleForm.remark"
|
||||||
|
type="textarea"
|
||||||
|
placeholder="请输入字典项描述"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="handleClose(ruleFormRef)">确定</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ElMessageBox, ElMessage, FormInstance } from 'element-plus'
|
||||||
|
import {reactive, ref} from "vue";
|
||||||
|
|
||||||
|
const ruleFormRef = ref<FormInstance>()
|
||||||
|
const dialogVisible = ref<boolean>(false)
|
||||||
|
const title = ref('新增字典项')
|
||||||
|
import { dictionaryData } from '@/mock/system'
|
||||||
|
|
||||||
|
const cascaderProps = {
|
||||||
|
value: 'id',
|
||||||
|
label: 'name',
|
||||||
|
checkStrictly: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
const rules = reactive({
|
||||||
|
name: [
|
||||||
|
{ required: true, message: '请输入名称', trigger: 'blur' },
|
||||||
|
{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
key: [{required: true, message: '请输入字典项键值', trigger: 'blur',},],
|
||||||
|
pid: [{required: true, message: '请选择所属字典', trigger: 'change',},],
|
||||||
|
})
|
||||||
|
|
||||||
|
const ruleForm = reactive({
|
||||||
|
pid: '',
|
||||||
|
name: null,
|
||||||
|
remark: '',
|
||||||
|
key: null,
|
||||||
|
})
|
||||||
|
|
||||||
|
function close() {
|
||||||
|
ruleFormRef.value.resetFields()
|
||||||
|
Object.keys(ruleForm).forEach(key=>{
|
||||||
|
ruleForm[key] = null
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const show = (item={})=>{
|
||||||
|
console.log('======item=======',item)
|
||||||
|
title.value = '新增字典项'
|
||||||
|
if(item.pid){
|
||||||
|
title.value = '编辑字典项'
|
||||||
|
Object.keys(item).forEach(key=>{
|
||||||
|
ruleForm[key] = item[key]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleClose = async (done: () => void) => {
|
||||||
|
await ruleFormRef.value.validate((valid, fields) => {
|
||||||
|
if (valid) {
|
||||||
|
dialogVisible.value = false
|
||||||
|
console.log('submit!', ruleForm)
|
||||||
|
} else {
|
||||||
|
console.log('error submit!', fields)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
show,
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
@ -0,0 +1,104 @@
|
||||||
|
<template>
|
||||||
|
<el-dialog @close="close" v-model="dialogVisible" :title="title" width="50%">
|
||||||
|
<el-form
|
||||||
|
ref="ruleFormRef"
|
||||||
|
:model="ruleForm"
|
||||||
|
:rules="rules"
|
||||||
|
label-width="100px"
|
||||||
|
>
|
||||||
|
<el-form-item label="父级字典">
|
||||||
|
<el-cascader
|
||||||
|
v-model="ruleForm.pid"
|
||||||
|
style="width: 100%"
|
||||||
|
:options="dictionaryData"
|
||||||
|
placeholder="请选择父级字典,默认为根字典"
|
||||||
|
:props="cascaderProps" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="字典名称" prop="name">
|
||||||
|
<el-input v-model="ruleForm.name" placeholder="请输入字典项名称"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="字典编码" prop="keyCode">
|
||||||
|
<el-input v-model="ruleForm.keyCode" placeholder="请输入字典编码"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="字典描述" prop="remark" >
|
||||||
|
<el-input v-model="ruleForm.remark"
|
||||||
|
type="textarea"
|
||||||
|
placeholder="请输入字典项描述"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="handleClose(ruleFormRef)">确定</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ElMessageBox, ElMessage, FormInstance } from 'element-plus'
|
||||||
|
import {reactive, ref} from "vue";
|
||||||
|
|
||||||
|
const ruleFormRef = ref<FormInstance>()
|
||||||
|
const dialogVisible = ref<boolean>(false)
|
||||||
|
const title = ref('新增字典项')
|
||||||
|
import { dictionaryData } from '@/mock/system'
|
||||||
|
|
||||||
|
const cascaderProps = {
|
||||||
|
value: 'id',
|
||||||
|
label: 'name',
|
||||||
|
checkStrictly: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
const rules = reactive({
|
||||||
|
name: [
|
||||||
|
{ required: true, message: '请输入名称', trigger: 'blur' },
|
||||||
|
{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
keyCode: [{required: true, message: '请输入字典编码', trigger: 'blur',},],
|
||||||
|
})
|
||||||
|
|
||||||
|
const ruleForm = reactive({
|
||||||
|
id: '',
|
||||||
|
name: null,
|
||||||
|
remark: '',
|
||||||
|
keyCode: null,
|
||||||
|
})
|
||||||
|
|
||||||
|
function close() {
|
||||||
|
ruleFormRef.value.resetFields()
|
||||||
|
Object.keys(ruleForm).forEach(key=>{
|
||||||
|
ruleForm[key] = null
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const show = (item={})=>{
|
||||||
|
title.value = '新增字典项'
|
||||||
|
if(item.id){
|
||||||
|
title.value = '编辑字典项'
|
||||||
|
Object.keys(item).forEach(key=>{
|
||||||
|
ruleForm[key] = item[key]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleClose = async (done: () => void) => {
|
||||||
|
await ruleFormRef.value.validate((valid, fields) => {
|
||||||
|
if (valid) {
|
||||||
|
dialogVisible.value = false
|
||||||
|
console.log('submit!', ruleForm)
|
||||||
|
} else {
|
||||||
|
console.log('error submit!', fields)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
show,
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
.m-user{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
.m-user-table{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
position: relative;
|
||||||
|
width: calc(100% - 230px);
|
||||||
|
.header{
|
||||||
|
display: flex;
|
||||||
|
padding: 16px 16px 0px 16px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: white;
|
||||||
|
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
||||||
|
}
|
||||||
|
.footer{
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
padding: 16px;
|
||||||
|
flex-direction: column;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
background: white;
|
||||||
|
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
.util{
|
||||||
|
margin-bottom: 15px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.table-inner{
|
||||||
|
flex: 1;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.table{
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.pagination{
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
padding-top: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.custom-tree-node{
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-dept-side{
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 220px;
|
||||||
|
height: 100%;
|
||||||
|
padding: 18px;
|
||||||
|
margin-right: 10px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
::v-deep(.el-card__body){
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0!important;
|
||||||
|
.el-tree-node__content{
|
||||||
|
height: 33px;
|
||||||
|
}
|
||||||
|
.el-tree{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.filter-search{
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.title{
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin: 0 0 15px;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.scrollbar{
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
}
|
||||||
|
.filter-tree{
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container m-user">
|
||||||
|
<Side @change="changeAction"/>
|
||||||
|
<Table ref="table"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import Table from './components/Table.vue'
|
||||||
|
import Side from './components/Side.vue'
|
||||||
|
import { ref } from "vue";
|
||||||
|
|
||||||
|
const table = ref()
|
||||||
|
|
||||||
|
const changeAction = (data)=>{
|
||||||
|
table.value.getList(data)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import "./index";
|
||||||
|
</style>
|
||||||
Loading…
Reference in New Issue