v3.9.0【优化】typescript版本;【优化】App端消息;【优化】弹出层z-index;

This commit is contained in:
zhuoda
2024-11-04 20:15:49 +08:00
parent 17a3e1fd86
commit 69fa9088f5
1376 changed files with 10373 additions and 9712 deletions

View File

@@ -0,0 +1,58 @@
<!--
* 部门 树形选择框
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-09-12 23:05:43
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
*
-->
<template>
<a-tree-select
:value="props.value"
:treeData="treeData"
:fieldNames="{ label: 'name', key: 'departmentId', value: 'departmentId' }"
show-search
style="width: 100%"
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
placeholder="请选择部门"
allow-clear
tree-default-expand-all
:multiple="props.multiple"
@change="onChange"
/>
</template>
<script setup>
import { onMounted, ref } from 'vue';
import _ from 'lodash';
import { departmentApi } from '/@/api/system/department-api';
const props = defineProps({
// 绑定值
value: Number,
// 单选多选
multiple: {
type: Boolean,
default: false,
},
});
const emit = defineEmits(['update:value']);
let treeData = ref([]);
onMounted(queryDepartmentTree);
async function queryDepartmentTree() {
let res = await departmentApi.queryDepartmentTree();
treeData.value = res.data;
}
function onChange(e) {
emit('update:value', e);
}
defineExpose({
queryDepartmentTree,
});
</script>

View File

@@ -0,0 +1,97 @@
<!--
* 员工下拉选择框
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-09-12 15:09:02
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
-->
<template>
<a-select
v-model:value="selectValue"
:style="`width: ${width}`"
:placeholder="props.placeholder"
:showSearch="true"
:allowClear="true"
:size="size"
@change="onChange"
>
<a-select-option v-for="item in employeeList" :key="item.employeeId" :value="item.employeeId">
{{ item.actualName }}
<template v-if="item.departmentName"> {{ item.departmentName }} </template>
</a-select-option>
</a-select>
</template>
<script setup>
import { onMounted, ref, watch } from 'vue';
import { employeeApi } from '/@/api/system/employee-api';
import { smartSentry } from '/@/lib/smart-sentry';
// =========== 属性定义 和 事件方法暴露 =============
const props = defineProps({
value: [Number, Array],
placeholder: {
type: String,
default: '请选择',
},
width: {
type: String,
default: '100%',
},
size: {
type: String,
default: 'default',
},
// 角色ID可为空
roleId: {
type: Number,
default: null,
},
// 禁用标识
disabledFlag: {
type: Number,
default: null,
},
});
const emit = defineEmits(['update:value', 'change']);
// =========== 查询数据 =============
//员工列表数据
const employeeList = ref([]);
async function query() {
try {
let params = {};
if (props.roleId) {
params = { roleId: props.roleId };
}
if (null != props.disabledFlag) {
params.disabledFlag = props.disabledFlag;
}
let resp = await employeeApi.queryAll(params);
employeeList.value = resp.data;
} catch (e) {
smartSentry.captureError(e);
}
}
onMounted(query);
// =========== 选择 监听、事件 =============
const selectValue = ref(props.value);
watch(
() => props.value,
(newValue) => {
selectValue.value = newValue;
}
);
function onChange(value) {
emit('update:value', value);
emit('change', value);
}
</script>

View File

@@ -0,0 +1,199 @@
<!--
* 员工 表格 弹窗 选择框
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-08-19 23:09:02
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
-->
<template>
<a-modal v-model:open="visible" :width="900" title="选择人员" @cancel="closeModal" @ok="onSelectEmployee">
<a-form class="smart-query-form">
<a-row class="smart-query-form-row">
<a-form-item label="关键字" class="smart-query-form-item">
<a-input style="width: 150px" v-model:value="params.keyword" placeholder="关键字" />
</a-form-item>
<a-form-item label="部门" class="smart-query-form-item">
<DepartmentTreeSelect style="width: 200px" ref="departmentTreeSelect" v-model:value="params.departmentId" />
</a-form-item>
<a-form-item label="状态" class="smart-query-form-item">
<a-select style="width: 120px" v-model:value="params.disabledFlag" placeholder="请选择状态" allowClear>
<a-select-option :key="1"> 禁用 </a-select-option>
<a-select-option :key="0"> 启用 </a-select-option>
</a-select>
</a-form-item>
<a-form-item class="smart-query-form-item smart-margin-left10">
<a-button type="primary" @click="onSearch">
<template #icon>
<SearchOutlined />
</template>
查询
</a-button>
<a-button @click="reset" class="smart-margin-left10">
<template #icon>
<ReloadOutlined />
</template>
重置
</a-button>
</a-form-item>
</a-row>
</a-form>
<a-table
:row-selection="{ selectedRowKeys: selectedRowKeyList, onChange: onSelectChange, getCheckboxProps: getCheckboxProps }"
:loading="tableLoading"
size="small"
:columns="columns"
:data-source="tableData"
:pagination="false"
bordered
rowKey="employeeId"
:scroll="{ y: 300 }"
>
<template #bodyCell="{ text, column }">
<template v-if="column.dataIndex === 'disabledFlag'">
<a-tag :color="text ? 'error' : 'processing'">{{ text ? '禁用' : '启用' }}</a-tag>
</template>
<template v-if="column.dataIndex === 'gender'">
<span>{{ $smartEnumPlugin.getDescByValue('GENDER_ENUM', text) }}</span>
</template>
</template>
</a-table>
<div class="smart-query-table-page">
<a-pagination
showSizeChanger
showQuickJumper
show-less-items
:pageSizeOptions="PAGE_SIZE_OPTIONS"
:defaultPageSize="params.pageSize"
v-model:current="params.pageNum"
v-model:pageSize="params.pageSize"
:total="total"
@change="queryEmployee"
@showSizeChange="queryEmployee"
:show-total="(total) => `${total}`"
/>
</div>
</a-modal>
</template>
<script setup>
import { message } from 'ant-design-vue';
import { computed, reactive, ref } from 'vue';
import { employeeApi } from '/@/api/system/employee-api';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
import DepartmentTreeSelect from '/@/components/system/department-tree-select/index.vue';
import { smartSentry } from '/@/lib/smart-sentry';
// ----------------------- 以下是字段定义 emits props ---------------------
const emits = defineEmits(['selectData']);
defineExpose({
showModal,
});
// ----------------------- modal 显示与隐藏 ---------------------
const visible = ref(false);
async function showModal(selectEmployeeId) {
originalRowKeyList.value = selectEmployeeId || [];
selectedRowKeyList.value = selectEmployeeId || [];
visible.value = true;
onSearch();
}
function closeModal() {
Object.assign(params, defaultParams);
selectedRowKeyList.value = [];
visible.value = false;
}
// ----------------------- 员工查询表单与查询 ---------------------
const tableLoading = ref(false);
const departmentTreeSelect = ref();
const total = ref();
let defaultParams = {
departmentId: undefined,
disabledFlag: undefined,
employeeIdList: undefined,
keyword: undefined,
searchCount: undefined,
pageNum: 1,
pageSize: PAGE_SIZE,
sortItemList: undefined,
};
const params = reactive({ ...defaultParams });
function reset() {
Object.assign(params, defaultParams);
queryEmployee();
}
function onSearch() {
params.pageNum = 1;
queryEmployee();
}
async function queryEmployee() {
tableLoading.value = true;
try {
let res = await employeeApi.queryEmployee(params);
tableData.value = res.data.list;
total.value = res.data.total;
} catch (error) {
smartSentry.captureError(error);
} finally {
tableLoading.value = false;
}
}
// ----------------------- 员工表格选择 ---------------------
const originalRowKeyList = ref([]);
let selectedRowKeyList = ref([]);
const hasSelected = computed(() => selectedRowKeyList.value.length !== originalRowKeyList.value.length);
function onSelectChange(selectedRowKeys) {
selectedRowKeyList.value = selectedRowKeys;
}
function onSelectEmployee() {
if (!hasSelected.value) {
message.warning('请选择角色人员');
return;
}
// 过滤出新选择的人员id
const newEmployeeIdList = selectedRowKeyList.value.filter((id) => !originalRowKeyList.value.includes(id));
emits('selectData', newEmployeeIdList);
closeModal();
}
function getCheckboxProps(record) {
return {
// 角色员工列表的添加员工弹窗中 禁止添加选择已存在该角色的员工
disabled: originalRowKeyList.value.includes(record.employeeId),
};
}
// ----------------------- 员工表格渲染 ---------------------
const tableData = ref([]);
//字段
const columns = [
{
title: '姓名',
dataIndex: 'actualName',
},
{
title: '手机号',
dataIndex: 'phone',
},
{
title: '性别',
dataIndex: 'gender',
},
{
title: '登录账号',
dataIndex: 'loginName',
},
{
title: '状态',
dataIndex: 'disabledFlag',
},
];
</script>

View File

@@ -0,0 +1,76 @@
<!--
* 菜单 树形 下拉选择框
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-09-01 23:14:49
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
-->
<template>
<a-tree-select
:value="props.value"
:treeData="treeData"
:fieldNames="{ label: 'menuName', key: 'menuId', value: 'menuId' }"
show-search
tree-checkable
style="width: 100%"
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
placeholder="请选择菜单"
allow-clear
tree-default-expand-all
@change="onSelectChange"
/>
</template>
<script setup>
import { onMounted, ref } from 'vue';
import _ from 'lodash';
import { menuApi } from '/@/api/system/menu-api';
import { buildMenuTableTree } from '/@/views/system/menu/menu-data-handler';
import { MENU_TYPE_ENUM } from '/@/constants/system/menu-const';
const props = defineProps({
// 绑定值
value: Array,
// 单选多选
multiple: {
type: Boolean,
default: false,
},
});
const emit = defineEmits(['update:value']);
let treeData = ref([]);
onMounted(queryMenuTree);
// 外部调用初始化
let menuList = [];
async function queryMenuTree() {
let res = await menuApi.queryMenu();
menuList = res.data.filter((e) => e.menuType === MENU_TYPE_ENUM.MENU.value || e.menuType === MENU_TYPE_ENUM.CATALOG.value);
for (const item of menuList) {
if (item.menuType === MENU_TYPE_ENUM.CATALOG.value) {
item.disabled = true;
}
}
treeData.value = buildMenuTableTree(menuList);
}
/**
* 根据id集合获取菜单集合
*/
function getMenuListByIdList(menuIdList) {
return _.cloneDeep(menuList.filter((e) => menuIdList.indexOf(e.menuId) > -1));
}
function onSelectChange(e) {
emit('update:value', e);
}
// ----------------------- 以下是暴露的方法内容 ------------------------
defineExpose({
queryMenuTree,
getMenuListByIdList,
});
</script>

View File

@@ -0,0 +1,79 @@
<!--
* 职位
*
* @Author: 开云
* @Date: 2024-06-27 23:09:02
* @Wechat: kaiyun
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
-->
<template>
<a-select
v-model:value="selectValue"
:style="`width: ${width}`"
:placeholder="props.placeholder"
:showSearch="true"
:allowClear="true"
:size="size"
@change="onChange"
>
<a-select-option v-for="item in positionList" :key="item.positionId" :value="item.positionId">
{{ item.positionName }}
</a-select-option>
</a-select>
</template>
<script setup>
import { onMounted, ref, watch } from 'vue';
import { smartSentry } from '/@/lib/smart-sentry';
import { positionApi } from '/@/api/system/position-api.js';
// =========== 属性定义 和 事件方法暴露 =============
const props = defineProps({
value: [Number, Array],
placeholder: {
type: String,
default: '请选择',
},
width: {
type: String,
default: '100%',
},
size: {
type: String,
default: 'default',
},
});
const emit = defineEmits(['update:value', 'change']);
// =========== 查询数据 =============
//员工列表数据
const positionList = ref([]);
async function query() {
try {
let resp = await positionApi.queryList();
positionList.value = resp.data;
} catch (e) {
smartSentry.captureError(e);
}
}
onMounted(query);
// =========== 选择 监听、事件 =============
const selectValue = ref(props.value);
watch(
() => props.value,
(newValue) => {
selectValue.value = newValue;
}
);
function onChange(value) {
emit('update:value', value);
emit('change', value);
}
</script>