|
@@ -1,438 +1,14 @@
|
|
|
<template>
|
|
|
<div class="pageWrap">
|
|
|
- <el-aside style="background: #fff; margin-right: 10px" width="200px">
|
|
|
- <el-container style="height: 100%">
|
|
|
- <el-header>
|
|
|
- <el-input v-model="groupFilterText" placeholder="输入关键字进行过滤" clearable style="margin-top: 10px" />
|
|
|
- </el-header>
|
|
|
- <el-main class="nopadding" style="flex-basis: 100%">
|
|
|
- <el-tree
|
|
|
- ref="treeRef"
|
|
|
- class="menu-tree"
|
|
|
- :data="treeData"
|
|
|
- node-key="id"
|
|
|
- :current-node-key="''"
|
|
|
- :highlight-current="true"
|
|
|
- :expand-on-click-node="false"
|
|
|
- :props="{ label: 'name' }"
|
|
|
- default-expand-all
|
|
|
- :filter-node-method="filterNode"
|
|
|
- @node-click="leftTreeClick"
|
|
|
- >
|
|
|
- <template #default="{ node, data }">
|
|
|
- <span class="custom-tree-node">
|
|
|
- <span class="label">{{ node.label }}</span>
|
|
|
- <span class="code">{{ data.code }}</span>
|
|
|
- <span class="do">
|
|
|
- <el-icon @click.stop="dicEdit(data)"><Edit /></el-icon>
|
|
|
- <el-icon @click.stop="dictDel(node, data)"><Delete /></el-icon>
|
|
|
- </span>
|
|
|
- </span>
|
|
|
- </template>
|
|
|
- </el-tree>
|
|
|
- </el-main>
|
|
|
- <el-footer style="height: 51px">
|
|
|
- <el-button type="primary" size="mini" :icon="Plus" style="width: 100%" @click="addDicTree"> 流程组 </el-button>
|
|
|
- </el-footer>
|
|
|
- </el-container>
|
|
|
- </el-aside>
|
|
|
- <div class="content-warp flex-column-page-wrap">
|
|
|
- <!-- LeTable 组件使用 -->
|
|
|
- <LeTable
|
|
|
- ref="tableRef"
|
|
|
- v-model:searchParams="tableOpts.searchParams"
|
|
|
- v-bind="tableOpts"
|
|
|
- v-model:curRow="tableOpts.curRow"
|
|
|
- v-model:checked-options="checkedColumns"
|
|
|
- :columns="activeColumns"
|
|
|
- >
|
|
|
- <template #toolLeft>
|
|
|
- <el-button type="primary" @click="addHandler">
|
|
|
- <el-icon class="btn-icon">
|
|
|
- <Plus />
|
|
|
- </el-icon>
|
|
|
- </el-button>
|
|
|
- <el-button type="danger" :disabled="curSelectionRows.length === 0" @click="batch_del">
|
|
|
- <el-icon class="btn-icon">
|
|
|
- <Delete />
|
|
|
- </el-icon>
|
|
|
- </el-button>
|
|
|
- </template>
|
|
|
-
|
|
|
- <template #filterAvatarSlot="scope">
|
|
|
- <el-avatar :src="scope.row.avatar" size="small"></el-avatar>
|
|
|
- </template>
|
|
|
-
|
|
|
- <template #statusSlot="scope">
|
|
|
- <status-indicator v-if="scope.row.status === 1" pulse type="success"></status-indicator>
|
|
|
- <status-indicator v-else pulse type="danger"></status-indicator>
|
|
|
- </template>
|
|
|
-
|
|
|
- <template #actionSlot="scope">
|
|
|
- <el-tooltip content="编辑" placement="bottom" effect="light">
|
|
|
- <el-icon class="ibt0" @click="table_edit(scope.row)">
|
|
|
- <Edit />
|
|
|
- </el-icon>
|
|
|
- </el-tooltip>
|
|
|
- <el-divider direction="vertical"></el-divider>
|
|
|
- <el-tooltip content="复制" placement="bottom" effect="light">
|
|
|
- <el-icon class="ibt0">
|
|
|
- <CopyDocument />
|
|
|
- </el-icon>
|
|
|
- </el-tooltip>
|
|
|
- <el-divider direction="vertical"></el-divider>
|
|
|
- <el-popconfirm title="确定删除吗?" @confirm="table_del(scope.row)">
|
|
|
- <template #reference>
|
|
|
- <el-icon class="ibt0">
|
|
|
- <Delete />
|
|
|
- </el-icon>
|
|
|
- </template>
|
|
|
- </el-popconfirm>
|
|
|
- </template>
|
|
|
- </LeTable>
|
|
|
- </div>
|
|
|
-
|
|
|
- <LeFormConfigDialog
|
|
|
- v-if="visible"
|
|
|
- ref="dialogDictRef"
|
|
|
- v-model="visible"
|
|
|
- :title="`${isCreate ? '新增' : '编辑'}项`"
|
|
|
- width="600px"
|
|
|
- :form-data="activeData"
|
|
|
- :form-options="formOptions"
|
|
|
- @submit="submitHandler"
|
|
|
- />
|
|
|
+ <el-container>
|
|
|
+ <el-header>
|
|
|
+ <el-input placeholder="输入关键字进行过滤" clearable style="margin-top: 10px" />
|
|
|
+ </el-header>
|
|
|
+ <el-main> </el-main>
|
|
|
+ </el-container>
|
|
|
</div>
|
|
|
</template>
|
|
|
-<script lang="tsx" setup>
|
|
|
-import dict from '@/api/system/dict'
|
|
|
-import { computed, nextTick, ref, watch } from 'vue'
|
|
|
-import { ElMessage, ElTree, ElMessageBox } from 'element-plus'
|
|
|
-import { useTablePage } from '@/hooks/useTablePage'
|
|
|
-import { Plus, Delete, Edit, CopyDocument } from '@element-plus/icons-vue'
|
|
|
-import StatusIndicator from '@/components/StatusIndicator'
|
|
|
-
|
|
|
-const visible = ref(false) // 弹窗显示隐藏
|
|
|
-const isCreate = ref(true)
|
|
|
-const activeData = ref({})
|
|
|
-const current_mode = ref('') // 当前模式 (tree | table)
|
|
|
-const formsDialog = [
|
|
|
- {
|
|
|
- prop: 'pid',
|
|
|
- label: '所属字典',
|
|
|
- itemType: 'select',
|
|
|
- filterable: true,
|
|
|
- options: [],
|
|
|
- rules: [{ required: true, message: '请选择所属字典', trigger: 'blur' }]
|
|
|
- },
|
|
|
- {
|
|
|
- prop: 'name',
|
|
|
- label: '项名称',
|
|
|
- itemType: 'input',
|
|
|
- rules: [{ required: true, message: '请输入项名称', trigger: 'blur' }]
|
|
|
- },
|
|
|
- {
|
|
|
- prop: 'code',
|
|
|
- label: '编码',
|
|
|
- itemType: 'input',
|
|
|
- rules: [{ required: true, message: '请输入编码', trigger: 'blur' }]
|
|
|
- },
|
|
|
- {
|
|
|
- prop: 'status',
|
|
|
- label: '状态',
|
|
|
- itemType: 'switch',
|
|
|
- activeText: '是',
|
|
|
- inactiveText: '否'
|
|
|
- },
|
|
|
- {
|
|
|
- prop: 'sort',
|
|
|
- label: '排序',
|
|
|
- itemType: 'inputNumber',
|
|
|
- rules: [{ required: true, message: '请输入排序', trigger: 'blur' }]
|
|
|
- },
|
|
|
- {
|
|
|
- prop: 'remark',
|
|
|
- label: '备注',
|
|
|
- itemType: 'input'
|
|
|
- }
|
|
|
-]
|
|
|
-// 新增的表单 和 编辑的表单
|
|
|
-const formOptions = computed(() => {
|
|
|
- // 去掉 formsDialog 下标为 0 的数据
|
|
|
- const { 0: pid, ...rest } = formsDialog
|
|
|
- let treeFormDialog = []
|
|
|
- for (let i in rest) {
|
|
|
- treeFormDialog.push(rest[i])
|
|
|
- }
|
|
|
-
|
|
|
- return {
|
|
|
- forms: current_mode.value === 'tree' ? treeFormDialog : formsDialog,
|
|
|
- labelWidth: 120,
|
|
|
- span: 30,
|
|
|
- showResetBtn: true,
|
|
|
- formConfig: {
|
|
|
- submitLoading: false
|
|
|
- }
|
|
|
- }
|
|
|
-})
|
|
|
-const showGroupLoading = ref(false)
|
|
|
-const groupFilterText = ref('')
|
|
|
-const treeRef = ref<InstanceType<typeof ElTree>>()
|
|
|
-
|
|
|
-const filterNode = (value: string, data: Tree) => {
|
|
|
- if (!value) return true
|
|
|
- return data.name.includes(value)
|
|
|
-}
|
|
|
-
|
|
|
-const treeData = ref([])
|
|
|
-
|
|
|
-// 获取左侧菜单数据
|
|
|
-const getGroup = async () => {
|
|
|
- showGroupLoading.value = true
|
|
|
- let data = await dict.dictListParentApi()
|
|
|
- formOptions.value.forms[0].options = data.map(item => {
|
|
|
- return { value: item.id, label: item.name }
|
|
|
- })
|
|
|
- showGroupLoading.value = false
|
|
|
- const data1 = [
|
|
|
- {
|
|
|
- "id": "1696539662002233345",
|
|
|
- "name": "分组1",
|
|
|
- "items": [
|
|
|
- {
|
|
|
- "flowId": "pzm1nggtdh0000000013",
|
|
|
- "rangeShow": "综合行政部",
|
|
|
- "name": "wewewe",
|
|
|
- "logo": "https://pro.cxygzl.com/wj//2023-08-30/94a982f4800644638373f91732da305a-WIN_20221017_15_35_20_Pro.jpg",
|
|
|
- "stop": false,
|
|
|
- "remark": "",
|
|
|
- "updated": "2023-08-30 16:50:53"
|
|
|
- },
|
|
|
- {
|
|
|
- "flowId": "p1kj39jcat0000000013",
|
|
|
- "rangeShow": "",
|
|
|
- "name": "Hier",
|
|
|
- "logo": "https://pro.cxygzl.com/wj//2023-08-29/b4845dd87e9743389fa09b9c812e03f4-cefc1e178a82b901024241fa778da9773812ef08.jfif",
|
|
|
- "stop": false,
|
|
|
- "remark": "",
|
|
|
- "updated": "2023-08-30 17:49:02"
|
|
|
- }
|
|
|
- ]
|
|
|
- },
|
|
|
- {
|
|
|
- "id": "1696764397248126978",
|
|
|
- "name": "行政",
|
|
|
- "items": [
|
|
|
- {
|
|
|
- "flowId": "pk8y13zwre0000000007",
|
|
|
- "rangeShow": "",
|
|
|
- "name": "请假流程",
|
|
|
- "logo": "https://pro.cxygzl.com/wj//2023-08-30/c5ce69ba37f64bceb4273da91247df2a-dd4a0447a8ed4b15915062cbc61a929c.jpg",
|
|
|
- "stop": false,
|
|
|
- "remark": "",
|
|
|
- "updated": "2023-08-30 14:25:58"
|
|
|
- }
|
|
|
- ]
|
|
|
- },
|
|
|
- {
|
|
|
- "id": "1696764414604156929",
|
|
|
- "name": "财务",
|
|
|
- "items": [
|
|
|
- {
|
|
|
- "flowId": "peast0rvfr0000000007",
|
|
|
- "rangeShow": "",
|
|
|
- "name": "报销申请",
|
|
|
- "logo": "https://pro.cxygzl.com/wj//2023-08-30/39bc32dd889f44189e8b1b95db1481c5-Capture001.png",
|
|
|
- "stop": false,
|
|
|
- "remark": "",
|
|
|
- "updated": "2023-08-30 13:59:53"
|
|
|
- }
|
|
|
- ]
|
|
|
- },
|
|
|
- {
|
|
|
- "id": "1696802661602500609",
|
|
|
- "name": "出差申请",
|
|
|
- "items": []
|
|
|
- }
|
|
|
- ]
|
|
|
- data1.unshift({ id: '', name: '所有' })
|
|
|
- treeData.value = data1 // console.log('获取左侧菜单数据')
|
|
|
-}
|
|
|
-
|
|
|
-// 左侧菜单点击
|
|
|
-const leftTreeClick = data => {
|
|
|
- console.log(data.id, 'data.id')
|
|
|
- // 修改search参数 watch 变更 自动刷新 列表
|
|
|
- searchData.value = { ...searchData.value, data: { pid: data.id ? data.id : null } }
|
|
|
-}
|
|
|
-
|
|
|
-// table列表数据请求
|
|
|
-const queryList = async () => {
|
|
|
- const { options, searchParams } = tableOpts
|
|
|
- options.loading = true
|
|
|
- console.log('搜索参数: ', JSON.stringify(tableOpts.searchParams))
|
|
|
- try {
|
|
|
- const { records: list, total } = await dict.dictPageApi(searchParams)
|
|
|
- tableOpts.total = total
|
|
|
- tableOpts.list = list
|
|
|
- } catch {
|
|
|
- console.log('获取列表数据失败')
|
|
|
- tableOpts.total = 0
|
|
|
- tableOpts.list = []
|
|
|
- options.loading = false // 更改加载中的 loading值
|
|
|
- } finally {
|
|
|
- options.loading = false
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// table 参数
|
|
|
-const columns = [
|
|
|
- {
|
|
|
- prop: 'name',
|
|
|
- label: '流程图标',
|
|
|
- minWidth: 80
|
|
|
- },
|
|
|
- {
|
|
|
- prop: 'code',
|
|
|
- label: '流程名字',
|
|
|
- minWidth: 100
|
|
|
- },
|
|
|
- {
|
|
|
- prop: 'content',
|
|
|
- label: '流程说明',
|
|
|
- minWidth: 150
|
|
|
- },
|
|
|
- {
|
|
|
- prop: 'remark',
|
|
|
- label: '流程发起人',
|
|
|
- minWidth: 100
|
|
|
- },
|
|
|
- {
|
|
|
- prop: 'action',
|
|
|
- label: '操作',
|
|
|
- width: 100,
|
|
|
- fixed: 'right',
|
|
|
- slots: {
|
|
|
- default: 'actionSlot'
|
|
|
- }
|
|
|
- }
|
|
|
-]
|
|
|
-
|
|
|
-const { searchData, tableOpts, checkedColumns, activeColumns, curSelectionRows, updateParams } = useTablePage(
|
|
|
- {
|
|
|
- options: {
|
|
|
- showIndex: false
|
|
|
- },
|
|
|
- // 需要展示的列
|
|
|
- columns,
|
|
|
- // 控制列配置
|
|
|
- columnsConfig: {
|
|
|
- columns
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- queryList,
|
|
|
- fetchImmediate: false
|
|
|
- }
|
|
|
-)
|
|
|
-
|
|
|
-// 删除
|
|
|
-const deleteItem = async ids => {
|
|
|
- try {
|
|
|
- await dict.dictDeleteApi(ids)
|
|
|
- if (current_mode.value === 'tree') {
|
|
|
- getGroup()
|
|
|
- }
|
|
|
- updateParams()
|
|
|
- ElMessage({
|
|
|
- type: 'success',
|
|
|
- message: '操作成功'
|
|
|
- })
|
|
|
- } catch (e) {
|
|
|
- console.log('删除失败')
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 单个删除
|
|
|
-const table_del = row => {
|
|
|
- deleteItem([row.id])
|
|
|
-}
|
|
|
-
|
|
|
-//批量删除
|
|
|
-const batch_del = () => {
|
|
|
- const ids = curSelectionRows.value.map(item => item.id) // 多选数据
|
|
|
- deleteItem(ids)
|
|
|
-}
|
|
|
-
|
|
|
-const table_edit = async row => {
|
|
|
- isCreate.value = false
|
|
|
- activeData.value = { ...row, status: row.status ? true : false }
|
|
|
- visible.value = true
|
|
|
-}
|
|
|
-
|
|
|
-// 弹窗事件
|
|
|
-const submitHandler = async params => {
|
|
|
- formOptions.value.formConfig.submitLoading = true
|
|
|
- try {
|
|
|
- params.status = params.status ? 1 : 0
|
|
|
- params.id = activeData.value.id ? activeData.value.id : null
|
|
|
- await dict.dictAddOrEditSaveApi(params)
|
|
|
- ElMessage.success(`${isCreate.value ? '新增' : '修改'}成功~`)
|
|
|
- visible.value = false
|
|
|
- if (current_mode.value === 'tree') {
|
|
|
- getGroup()
|
|
|
- }
|
|
|
- updateParams()
|
|
|
- formOptions.value.formConfig.submitLoading = false
|
|
|
- } catch (e) {
|
|
|
- console.log(e)
|
|
|
- formOptions.value.formConfig.submitLoading = false
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-const addHandler = () => {
|
|
|
- isCreate.value = true
|
|
|
- activeData.value = {}
|
|
|
- visible.value = true
|
|
|
-}
|
|
|
-
|
|
|
-// 删除左侧树
|
|
|
-const dictDel = (node, data) => {
|
|
|
- current_mode.value = 'tree'
|
|
|
- ElMessageBox.confirm(`确定删除 ${data.name} 项吗?`, '提示')
|
|
|
- .then(async () => {
|
|
|
- try {
|
|
|
- deleteItem([data.id])
|
|
|
- } catch (e) {
|
|
|
- ElMessage({
|
|
|
- type: 'error',
|
|
|
- message: '操作失败'
|
|
|
- })
|
|
|
- }
|
|
|
- })
|
|
|
- .catch(() => {})
|
|
|
-}
|
|
|
-
|
|
|
-const dicEdit = data => {
|
|
|
- current_mode.value = 'tree'
|
|
|
- table_edit(data)
|
|
|
-}
|
|
|
-
|
|
|
-const addDicTree = () => {
|
|
|
- current_mode.value = 'tree'
|
|
|
- addHandler()
|
|
|
-}
|
|
|
-
|
|
|
-nextTick(() => {
|
|
|
- getGroup()
|
|
|
- queryList()
|
|
|
-})
|
|
|
-
|
|
|
-watch(groupFilterText, val => {
|
|
|
- console.log(val, '====value');
|
|
|
- treeRef.value!.filter(val)
|
|
|
-})
|
|
|
-</script>
|
|
|
+<script lang="tsx" setup></script>
|
|
|
<style scoped lang="scss">
|
|
|
.pageWrap {
|
|
|
flex: 1;
|
|
@@ -440,83 +16,4 @@ watch(groupFilterText, val => {
|
|
|
height: 100%;
|
|
|
//background: #fff;
|
|
|
}
|
|
|
-.content-warp {
|
|
|
- flex: 1;
|
|
|
- //width: calc(100% - 250px);
|
|
|
- width: calc(100% - 210px);
|
|
|
-}
|
|
|
-// 单独自己写的
|
|
|
-/*:deep(.box-card) {
|
|
|
- height: 100%;
|
|
|
- .el-card__body {
|
|
|
- padding: 0;
|
|
|
- }
|
|
|
-}*/
|
|
|
-
|
|
|
-// 角色的树结构样式
|
|
|
-:deep(.menu-tree) {
|
|
|
- .el-tree-node {
|
|
|
- &:first-child {
|
|
|
- .custom-tree-node {
|
|
|
- .do {
|
|
|
- display: none !important;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- .el-tree-node__content {
|
|
|
- height: 36px;
|
|
|
- }
|
|
|
- .el-tree-node__content .el-tree-node__label .icon {
|
|
|
- margin-right: 5px;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.nopadding {
|
|
|
- padding: 0px;
|
|
|
-}
|
|
|
-
|
|
|
-.custom-tree-node {
|
|
|
- display: flex;
|
|
|
- flex: 1;
|
|
|
- align-items: center;
|
|
|
- justify-content: space-between;
|
|
|
- font-size: 14px;
|
|
|
- padding-right: 24px;
|
|
|
- height: 100%;
|
|
|
-}
|
|
|
-
|
|
|
-.custom-tree-node .code {
|
|
|
- font-size: 12px;
|
|
|
- color: #999;
|
|
|
-}
|
|
|
-
|
|
|
-.custom-tree-node {
|
|
|
- .do {
|
|
|
- display: none;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.custom-tree-node .do i {
|
|
|
- margin-left: 5px;
|
|
|
- color: #999;
|
|
|
- padding: 5px;
|
|
|
- font-size: 20px;
|
|
|
-}
|
|
|
-
|
|
|
-.custom-tree-node .do i:hover {
|
|
|
- color: #333;
|
|
|
-}
|
|
|
-
|
|
|
-.custom-tree-node {
|
|
|
- &:hover {
|
|
|
- .code {
|
|
|
- display: none;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.custom-tree-node:hover .do {
|
|
|
- display: inline-block;
|
|
|
-}
|
|
|
</style>
|