Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -3,7 +3,7 @@ ENV = 'development'
|
||||
|
||||
# 本地环境接口地址
|
||||
#`VITE_API_URL = 'https://demo.dvadmin.com/api'
|
||||
VITE_API_URL = 'http://192.168.1.160:8003'
|
||||
VITE_API_URL = 'http://192.168.1.94:10000'
|
||||
|
||||
# 是否启用按钮权限
|
||||
VITE_PM_ENABLED = true
|
||||
|
||||
@@ -34,8 +34,8 @@ const route = useRoute();
|
||||
const stores = useTagsViewRoutes();
|
||||
const storesThemeConfig = useThemeConfig();
|
||||
const { themeConfig } = storeToRefs(storesThemeConfig);
|
||||
import websocket from "/@/utils/websocket";
|
||||
import { ElNotification } from "element-plus";
|
||||
import websocket from '/@/utils/websocket';
|
||||
import { ElNotification } from 'element-plus';
|
||||
// 获取版本号
|
||||
const getVersion = computed(() => {
|
||||
let isVersion = false;
|
||||
@@ -61,11 +61,10 @@ onBeforeMount(() => {
|
||||
setIntroduction.jsCdn();
|
||||
//websockt 模块
|
||||
try {
|
||||
websocket.init(wsReceive)
|
||||
//websocket.init(wsReceive)
|
||||
} catch (e) {
|
||||
console.log("websocket错误")
|
||||
console.log('websocket错误');
|
||||
}
|
||||
|
||||
});
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
@@ -87,7 +86,7 @@ onMounted(() => {
|
||||
});
|
||||
// 页面销毁时,关闭监听布局配置/i18n监听
|
||||
onUnmounted(() => {
|
||||
mittBus.off('openSetingsDrawer', () => { });
|
||||
mittBus.off('openSetingsDrawer', () => {});
|
||||
});
|
||||
// 监听路由的变化,设置网站标题
|
||||
watch(
|
||||
@@ -101,11 +100,11 @@ watch(
|
||||
);
|
||||
|
||||
// websocket相关代码
|
||||
import { messageCenterStore } from "/@/stores/messageCenter";
|
||||
import { messageCenterStore } from '/@/stores/messageCenter';
|
||||
const wsReceive = (message: any) => {
|
||||
const data = JSON.parse(message.data)
|
||||
const { unread } = data
|
||||
const messageCenter = messageCenterStore()
|
||||
const data = JSON.parse(message.data);
|
||||
const { unread } = data;
|
||||
const messageCenter = messageCenterStore();
|
||||
messageCenter.setUnread(unread);
|
||||
if (data.contentType === 'SYSTEM') {
|
||||
ElNotification({
|
||||
@@ -113,14 +112,12 @@ const wsReceive = (message: any) => {
|
||||
message: data.content,
|
||||
type: 'success',
|
||||
position: 'bottom-right',
|
||||
duration: 5000
|
||||
})
|
||||
duration: 5000,
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
onBeforeUnmount(() => {
|
||||
// 关闭连接
|
||||
websocket.close()
|
||||
})
|
||||
|
||||
websocket.close();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :rules="rules" :model="deptFormData" label-width="100px" label-position="right" class="dept-form-com">
|
||||
<el-form-item label="父级部门" prop="parent">
|
||||
<el-select v-model="deptFormData.parent" style="width: 100%">
|
||||
<el-option v-for="item in deptAllList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
<el-tree-select
|
||||
v-model="deptFormData.parent"
|
||||
:props="defaultTreeProps"
|
||||
:data="deptDefaultList"
|
||||
lazy
|
||||
check-strictly
|
||||
:load="handleTreeLoad"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item required label="部门名称" prop="name">
|
||||
<el-input v-model="deptFormData.name" />
|
||||
@@ -11,14 +17,14 @@
|
||||
<el-form-item required label="部门标识" prop="key">
|
||||
<el-input v-model="deptFormData.key" />
|
||||
</el-form-item>
|
||||
<el-form-item label="负责人" prop="owner">
|
||||
<el-form-item label="负责人">
|
||||
<el-input v-model="deptFormData.owner" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="deptFormData.remark" maxlength="200" show-word-limit type="textarea" />
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="deptFormData.description" maxlength="200" show-word-limit type="textarea" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="handleUpdateMenu" type="primary" :disabled="deptBtnLoading">
|
||||
<el-button @click="handleUpdateMenu" type="primary" :loading="deptBtnLoading">
|
||||
{{ deptFormData.id ? '保存' : '新增' }}
|
||||
</el-button>
|
||||
<el-button @click="handleClose">取消 </el-button>
|
||||
@@ -29,14 +35,29 @@
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref, onMounted } from 'vue';
|
||||
import { ElForm, FormRules } from 'element-plus';
|
||||
import { getAllDeptList, AddObj, UpdateObj } from '../api';
|
||||
import { lazyLoadDept, AddObj, UpdateObj } from '../api';
|
||||
import { successNotification } from '../../../../utils/message';
|
||||
import { DeptFormDataType, TreeItemType, DeptListType } from '../types';
|
||||
import { DeptFormDataType, TreeItemType, APIResponseData } from '../types';
|
||||
import type Node from 'element-plus/es/components/tree/src/model/node';
|
||||
|
||||
interface IProps {
|
||||
initFormData: TreeItemType | null;
|
||||
treeData: TreeItemType[];
|
||||
}
|
||||
|
||||
const defaultTreeProps: any = {
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id',
|
||||
isLeaf: (data: TreeItemType[], node: Node) => {
|
||||
if (node?.data.hasChild) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const formRef = ref<InstanceType<typeof ElForm>>();
|
||||
const rules = reactive<FormRules>({
|
||||
name: [{ required: true, message: '部门名称必填', trigger: 'blur' }],
|
||||
@@ -45,27 +66,20 @@ const rules = reactive<FormRules>({
|
||||
|
||||
const props = withDefaults(defineProps<IProps>(), {
|
||||
initFormData: () => null,
|
||||
treeData: () => [],
|
||||
});
|
||||
const emit = defineEmits(['drawerClose']);
|
||||
|
||||
let deptAllList = ref<DeptListType[]>([]);
|
||||
let deptDefaultList = ref<TreeItemType[]>([]);
|
||||
let deptFormData = reactive<DeptFormDataType>({
|
||||
key: '',
|
||||
parent: '',
|
||||
name: '',
|
||||
owner: '',
|
||||
remark: '',
|
||||
is_catalog: true,
|
||||
description: '',
|
||||
});
|
||||
let deptBtnLoading = ref(false);
|
||||
|
||||
const getData = async () => {
|
||||
const res = await getAllDeptList();
|
||||
if (res?.code === 2000) {
|
||||
deptAllList.value = res.data;
|
||||
}
|
||||
};
|
||||
|
||||
const setDeptFormData = () => {
|
||||
if (props.initFormData?.id) {
|
||||
deptFormData.id = props.initFormData?.id;
|
||||
@@ -73,6 +87,15 @@ const setDeptFormData = () => {
|
||||
deptFormData.parent = props.initFormData.parent || '';
|
||||
deptFormData.name = props.initFormData.name || '';
|
||||
deptFormData.owner = props.initFormData.owner || '';
|
||||
deptFormData.description = props.initFormData.description || '';
|
||||
}
|
||||
};
|
||||
|
||||
const handleTreeLoad = (node: Node, resolve: Function) => {
|
||||
if (node.level !== 0) {
|
||||
lazyLoadDept({ parent: node.data.id }).then((res: APIResponseData) => {
|
||||
resolve(res.data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -103,7 +126,9 @@ const handleClose = (type: string = '') => {
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
await getData();
|
||||
props.treeData.map((item) => {
|
||||
deptDefaultList.value.push(item);
|
||||
});
|
||||
setDeptFormData();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -12,6 +12,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
|
||||
* 处理crud警告:Invalid prop: type check failed for prop "name". Expected String with value "2", got Number with value 2.
|
||||
*/
|
||||
res.data.forEach((item: any) => {
|
||||
item.dept = String(item.dept);
|
||||
if (item.role && Array.isArray(item.role) && item.role.length > 0) {
|
||||
item.role = item.role.map((r: number) => String(r));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<el-input v-model="filterVal" :prefix-icon="Search" placeholder="请输入部门名称" />
|
||||
<div class="tree-com">
|
||||
<div class="dept-tree-com">
|
||||
<div class="tc-head">
|
||||
<el-icon size="16" color="#606266" class="tc-head-icon">
|
||||
<HomeFilled />
|
||||
@@ -15,22 +15,21 @@
|
||||
<el-tree
|
||||
ref="treeRef"
|
||||
:data="treeData"
|
||||
:props="treeProps"
|
||||
:props="defaultTreeProps"
|
||||
:filter-node-method="handleFilterTreeNode"
|
||||
:load="handleLoadNode"
|
||||
lazy
|
||||
:indent="38"
|
||||
@node-click="handleNodeClick"
|
||||
highlight-current
|
||||
default-expand-all
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<element-tree-line :node="node" :showLabelLine="false" :indent="32">
|
||||
<span v-if="data.status" class="text-center font-black font-normal">
|
||||
<SvgIcon name="iconfont icon-shouye" /> {{ node.label }}
|
||||
<span v-show="showTotalNum">(10人)</span>
|
||||
<SvgIcon name="iconfont icon-shouye" color="var(--el-color-primary)" /> {{ node.label }}
|
||||
<span v-show="showTotalNum">({{ data.dept_user_count }}人)</span>
|
||||
</span>
|
||||
<span v-else class="text-center font-black font-normal text-red-700"> <SvgIcon name="iconfont icon-shouye" /> {{ node.label }} </span>
|
||||
<span v-else color="var(--el-color-primary)"> <SvgIcon name="iconfont icon-shouye" /> {{ node.label }} </span>
|
||||
</element-tree-line>
|
||||
</template>
|
||||
</el-tree>
|
||||
@@ -85,9 +84,16 @@ interface IProps {
|
||||
|
||||
const ElementTreeLine = getElementLabelLine(h);
|
||||
|
||||
const treeProps = {
|
||||
const defaultTreeProps: any = {
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
isLeaf: (data: TreeItemType[], node: Node) => {
|
||||
if (node.data.hasChild) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
withDefaults(defineProps<IProps>(), {
|
||||
@@ -233,7 +239,7 @@ const handleSort = async (type: string) => {
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
.tree-com {
|
||||
.dept-tree-com {
|
||||
height: calc(100% - 60px);
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
@@ -257,7 +263,7 @@ const handleSort = async (type: string) => {
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
margin-right: 5px;
|
||||
margin-left: 18px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.el-tree .el-tree-node__expand-icon.expanded {
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
<el-row class="dept-el-row">
|
||||
<el-col :span="6">
|
||||
<div class="dept-box dept-left">
|
||||
<TreeCom :treeData="deptTreeData" @treeClick="handleTreeClick" @updateDept="handleUpdateMenu"
|
||||
@deleteDept="handleDeleteMenu" />
|
||||
<TreeCom :treeData="deptTreeData" @treeClick="handleTreeClick" @updateDept="handleUpdateMenu" @deleteDept="handleDeleteMenu" />
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
@@ -15,9 +14,8 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-drawer v-model="drawerVisible" title="部门配置" direction="rtl" size="500px" :close-on-click-modal="false"
|
||||
:before-close="handleDrawerClose">
|
||||
<DeptFormCom v-if="drawerVisible" :initFormData="drawerFormData" @drawerClose="handleDrawerClose" />
|
||||
<el-drawer v-model="drawerVisible" title="部门配置" direction="rtl" size="500px" :close-on-click-modal="false" :before-close="handleDrawerClose">
|
||||
<DeptFormCom v-if="drawerVisible" :initFormData="drawerFormData" :treeData="deptTreeData" @drawerClose="handleDrawerClose" />
|
||||
</el-drawer>
|
||||
</fs-page>
|
||||
</template>
|
||||
@@ -34,9 +32,9 @@ import { successNotification } from '../../../utils/message';
|
||||
import { APIResponseData, TreeItemType } from './types';
|
||||
|
||||
let deptTreeData = ref([]);
|
||||
let drawerVisible = ref(false)
|
||||
let drawerFormData = ref<Partial<TreeItemType>>({})
|
||||
let deptUserRef = ref<InstanceType<typeof DeptUserCom> | null>(null)
|
||||
let drawerVisible = ref(false);
|
||||
let drawerFormData = ref<Partial<TreeItemType>>({});
|
||||
let deptUserRef = ref<InstanceType<typeof DeptUserCom> | null>(null);
|
||||
|
||||
const getData = async () => {
|
||||
let res: APIResponseData = await GetList({});
|
||||
@@ -56,30 +54,26 @@ const getData = async () => {
|
||||
* 部门的点击事件
|
||||
*/
|
||||
const handleTreeClick = (id: string) => {
|
||||
deptUserRef.value?.handleDoRefreshUser(id)
|
||||
}
|
||||
deptUserRef.value?.handleDoRefreshUser(id);
|
||||
};
|
||||
|
||||
/**
|
||||
* 部门的删除事件
|
||||
*/
|
||||
const handleDeleteMenu = (id: string, callback: Function) => {
|
||||
ElMessageBox.confirm(
|
||||
'您确认删除该部门吗?',
|
||||
'温馨提示',
|
||||
{
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
).then(async () => {
|
||||
const res: APIResponseData = await DelObj(id)
|
||||
callback()
|
||||
ElMessageBox.confirm('您确认删除该部门吗?', '温馨提示', {
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}).then(async () => {
|
||||
const res: APIResponseData = await DelObj(id);
|
||||
callback();
|
||||
if (res?.code === 2000) {
|
||||
successNotification(res.msg as string);
|
||||
getData();
|
||||
deptUserRef.value?.handleDoRefreshUser('')
|
||||
deptUserRef.value?.handleDoRefreshUser('');
|
||||
}
|
||||
})
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -87,18 +81,17 @@ const handleDeleteMenu = (id: string, callback: Function) => {
|
||||
*/
|
||||
const handleUpdateMenu = (type: string, record?: TreeItemType) => {
|
||||
if (type === 'update' && record) {
|
||||
drawerFormData.value = record
|
||||
drawerFormData.value = record;
|
||||
}
|
||||
drawerVisible.value = true
|
||||
|
||||
drawerVisible.value = true;
|
||||
};
|
||||
const handleDrawerClose = (type?: string) => {
|
||||
if (type === 'submit') {
|
||||
getData()
|
||||
getData();
|
||||
}
|
||||
drawerVisible.value = false
|
||||
drawerFormData.value = {}
|
||||
}
|
||||
drawerVisible.value = false;
|
||||
drawerFormData.value = {};
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getData();
|
||||
@@ -137,4 +130,4 @@ onMounted(() => {
|
||||
border-radius: 8px 0 0 8px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -45,8 +45,7 @@ export interface DeptFormDataType {
|
||||
parent: string | number;
|
||||
name: string;
|
||||
owner: string;
|
||||
remark: string;
|
||||
is_catalog?: boolean;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface DeptListType {
|
||||
|
||||
Reference in New Issue
Block a user