mirror of
https://gitee.com/lab1024/smart-admin.git
synced 2026-02-08 18:54:25 +08:00
v3.14.0 更新;【新增】EasyExcel重磅升级为FastExcel;【新增】使用最强Argon2算法作为密码存储;【新增】大家吐槽的数据字典改为可重复;【新增】前端布局再增加多种样式;【优化】升级SaToken到最新版本;【优化】token使用Sa-Token的Bearer类型;【优化】优化其他
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
</a-modal>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, reactive } from 'vue';
|
||||
import { ref, reactive, nextTick } from 'vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import _ from 'lodash';
|
||||
@@ -43,6 +43,21 @@
|
||||
Object.assign(form, rowData);
|
||||
}
|
||||
visible.value = true;
|
||||
nextTick(() => {
|
||||
// 解决弹窗错误信息显示,没有可忽略
|
||||
const domArr = document.getElementsByClassName('ant-modal');
|
||||
if (domArr && domArr.length > 0) {
|
||||
Array.from(domArr).forEach((item) => {
|
||||
if (item.childNodes && item.childNodes.length > 0) {
|
||||
Array.from(item.childNodes).forEach((child) => {
|
||||
if (child.setAttribute) {
|
||||
child.setAttribute('aria-hidden', 'false');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onClose() {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<SmartEnumSelect enum-name="GOODS_STATUS_ENUM" v-model:value="form.goodsStatus" />
|
||||
</a-form-item>
|
||||
<a-form-item label="产地" name="place">
|
||||
<DictSelect width="100%" key-code="GODOS_PLACE" v-model:value="form.place" mode="tags" />
|
||||
<DictSelect width="100%" key-code="GOODS_PLACE" v-model:value="form.place" mode="tags" />
|
||||
</a-form-item>
|
||||
<a-form-item label="上架状态" name="shelvesFlag">
|
||||
<a-radio-group v-model:value="form.shelvesFlag">
|
||||
@@ -107,7 +107,7 @@
|
||||
Object.assign(form, rowData);
|
||||
}
|
||||
if (form.place && form.place.length > 0) {
|
||||
form.place = form.place.map((e) => e.valueCode);
|
||||
form.place = form.place.split(',');
|
||||
}
|
||||
visible.value = true;
|
||||
nextTick(() => {
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="产地" name="place" class="smart-query-form-item">
|
||||
<DictSelect key-code="GODOS_PLACE" v-model:value="queryForm.place" width="120px" />
|
||||
<DictSelect key-code="GOODS_PLACE" v-model:value="queryForm.place" width="120px" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="商品状态" name="goodsStatus" class="smart-query-form-item">
|
||||
@@ -35,8 +35,8 @@
|
||||
<a-form-item label="快速筛选" class="smart-query-form-item">
|
||||
<a-radio-group v-model:value="queryForm.shelvesFlag" @change="onSearch">
|
||||
<a-radio-button :value="undefined">全部</a-radio-button>
|
||||
<a-radio-button :value="true">上架</a-radio-button>
|
||||
<a-radio-button :value="false">下架</a-radio-button>
|
||||
<a-radio-button :value="'true'">上架</a-radio-button>
|
||||
<a-radio-button :value="'false'">下架</a-radio-button>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
|
||||
@@ -102,15 +102,28 @@
|
||||
:dataSource="tableData"
|
||||
:columns="columns"
|
||||
rowKey="goodsId"
|
||||
:scroll="{ x: 1000 }"
|
||||
bordered
|
||||
:pagination="false"
|
||||
:showSorterTooltip="false"
|
||||
:row-selection="{ selectedRowKeys: selectedRowKeyList, onChange: onSelectChange }"
|
||||
@change="onChange"
|
||||
@resizeColumn="handleResizeColumn"
|
||||
>
|
||||
<!-- main.js中有全局表格高度配置,也可单独配置 -->
|
||||
<!-- :scroll="{ y: 300 }" -->
|
||||
<template #headerCell="{ column }">
|
||||
<SmartHeaderCell v-model:value="queryForm[column.filterOptions?.key || column.dataIndex]" :column="column" @change="queryData" />
|
||||
</template>
|
||||
<template #bodyCell="{ text, record, column }">
|
||||
<template v-if="column.dataIndex === 'goodsName'">
|
||||
{{ text }}
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'place'">
|
||||
<span>{{ text && text.length > 0 ? text.map((e) => e.valueName).join(',') : '' }}</span>
|
||||
<DictPreview :options="descList.GOODS_PLACE" :value="text" />
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'remark'">
|
||||
<span>{{ text ? text : '' }}</span>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'goodsStatus'">
|
||||
<span>{{ $smartEnumPlugin.getDescByValue('GOODS_STATUS_ENUM', text) }}</span>
|
||||
@@ -176,7 +189,7 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import GoodsFormModal from './components/goods-form-modal.vue';
|
||||
import { reactive, ref, onMounted } from 'vue';
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { message, Modal } from 'ant-design-vue';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import { goodsApi } from '/@/api/business/goods/goods-api';
|
||||
@@ -189,52 +202,88 @@
|
||||
import { GOODS_STATUS_ENUM } from '/@/constants/business/erp/goods-const';
|
||||
import DictSelect from '/@/components/support/dict-select/index.vue';
|
||||
import SmartEnumSelect from '/@/components/framework/smart-enum-select/index.vue';
|
||||
import { FILE_FOLDER_TYPE_ENUM } from '/@/constants/support/file-const.js';
|
||||
import FileUpload from '/@/components/support/file-upload/index.vue';
|
||||
import _ from 'lodash';
|
||||
import SmartHeaderCell from '/@/components/smart-table-header-cell/index.vue';
|
||||
import DictPreview from '/@/components/dict-preview/index.vue';
|
||||
import { useDict } from '/@/utils/dict';
|
||||
|
||||
const descList = useDict('GOODS_PLACE');
|
||||
// ---------------------------- 表格列 ----------------------------
|
||||
|
||||
const columns = ref([
|
||||
{
|
||||
title: '商品分类',
|
||||
dataIndex: 'categoryName',
|
||||
resizable: true,
|
||||
filterOptions: {
|
||||
type: 'category-tree',
|
||||
key: 'categoryId',
|
||||
categoryType: CATEGORY_TYPE_ENUM.GOODS.value,
|
||||
},
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '商品名称',
|
||||
dataIndex: 'goodsName',
|
||||
resizable: true,
|
||||
filterOptions: {
|
||||
type: 'input',
|
||||
key: 'searchWord',
|
||||
},
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '商品状态',
|
||||
dataIndex: 'goodsStatus',
|
||||
sorter: true
|
||||
resizable: true,
|
||||
sorter: true,
|
||||
filterOptions: {
|
||||
type: 'enum-select',
|
||||
enumName: 'GOODS_STATUS_ENUM',
|
||||
},
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '产地',
|
||||
dataIndex: 'place',
|
||||
resizable: true,
|
||||
filterOptions: {
|
||||
type: 'dict-select',
|
||||
keyCode: 'GOODS_PLACE',
|
||||
},
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '商品价格',
|
||||
title: '价格',
|
||||
dataIndex: 'price',
|
||||
sorter: true
|
||||
resizable: true,
|
||||
sorter: true,
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '上架状态',
|
||||
title: '状态',
|
||||
dataIndex: 'shelvesFlag',
|
||||
sorter: true
|
||||
resizable: true,
|
||||
sorter: true,
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: '备注',
|
||||
dataIndex: 'remark',
|
||||
ellipsis: true,
|
||||
resizable: true,
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createTime',
|
||||
resizable: true,
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
resizable: true,
|
||||
fixed: 'right',
|
||||
width: 100,
|
||||
},
|
||||
@@ -251,7 +300,7 @@
|
||||
goodsType: undefined,
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
sortItemList: []
|
||||
sortItemList: [],
|
||||
};
|
||||
// 查询表单form
|
||||
const queryForm = reactive(_.cloneDeep(queryFormState));
|
||||
@@ -261,7 +310,15 @@
|
||||
const tableData = ref([]);
|
||||
// 总数
|
||||
const total = ref(0);
|
||||
|
||||
function handleResizeColumn(w, col) {
|
||||
columns.value.forEach((item) => {
|
||||
if (item.dataIndex === col.dataIndex) {
|
||||
item.width = Math.floor(w);
|
||||
// 拖动宽度标识
|
||||
item.dragAndDropFlag = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
// 重置查询条件
|
||||
function resetQuery() {
|
||||
let pageSize = queryForm.pageSize;
|
||||
@@ -421,11 +478,11 @@
|
||||
await goodsApi.exportGoods();
|
||||
}
|
||||
|
||||
function onChange(pagination, filters, sorter, { action }){
|
||||
function onChange(pagination, filters, sorter, { action }) {
|
||||
if (action === 'sort') {
|
||||
const { order, field } = sorter;
|
||||
let column = camelToUnderscore(field);
|
||||
let findIndex = queryForm.sortItemList.findIndex(e => e.column === column);
|
||||
let findIndex = queryForm.sortItemList.findIndex((e) => e.column === column);
|
||||
if (findIndex !== -1) {
|
||||
queryForm.sortItemList.splice(findIndex, 1);
|
||||
}
|
||||
@@ -433,7 +490,7 @@
|
||||
let isAsc = order !== 'ascend';
|
||||
queryForm.sortItemList.push({
|
||||
column,
|
||||
isAsc
|
||||
isAsc,
|
||||
});
|
||||
}
|
||||
queryData();
|
||||
@@ -441,6 +498,6 @@
|
||||
}
|
||||
|
||||
function camelToUnderscore(str) {
|
||||
return str.replace(/([A-Z])/g, "_$1").toLowerCase();
|
||||
return str.replace(/([A-Z])/g, '_$1').toLowerCase();
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -85,6 +85,21 @@
|
||||
detail(enterpriseId);
|
||||
}
|
||||
visible.value = true;
|
||||
nextTick(() => {
|
||||
// 解决弹窗错误信息显示,没有可忽略
|
||||
const domArr = document.getElementsByClassName('ant-modal');
|
||||
if (domArr && domArr.length > 0) {
|
||||
Array.from(domArr).forEach((item) => {
|
||||
if (item.childNodes && item.childNodes.length > 0) {
|
||||
Array.from(item.childNodes).forEach((child) => {
|
||||
if (child.setAttribute) {
|
||||
child.setAttribute('aria-hidden', 'false');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onClose() {
|
||||
|
||||
@@ -60,102 +60,102 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import { noticeApi } from '/@/api/business/oa/notice-api';
|
||||
import { PAGE_SIZE, PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
|
||||
import DepartmentTreeSelect from '/@/components/system/department-tree-select/index.vue';
|
||||
import uaparser from 'ua-parser-js';
|
||||
import { reactive, ref } from 'vue';
|
||||
import { noticeApi } from '/@/api/business/oa/notice-api';
|
||||
import { PAGE_SIZE, PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
|
||||
import DepartmentTreeSelect from '/@/components/system/department-tree-select/index.vue';
|
||||
import uaparser from 'ua-parser-js';
|
||||
|
||||
const props = defineProps({
|
||||
noticeId: {
|
||||
type: [Number, String],
|
||||
},
|
||||
});
|
||||
const props = defineProps({
|
||||
noticeId: {
|
||||
type: [Number, String],
|
||||
},
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
onSearch,
|
||||
});
|
||||
defineExpose({
|
||||
onSearch,
|
||||
});
|
||||
|
||||
const tableColumns = [
|
||||
{
|
||||
title: '姓名',
|
||||
dataIndex: 'employeeName',
|
||||
},
|
||||
{
|
||||
title: '查看次数',
|
||||
dataIndex: 'pageViewCount',
|
||||
},
|
||||
{
|
||||
title: '首次查看设备',
|
||||
dataIndex: 'firstIp',
|
||||
},
|
||||
{
|
||||
title: '首次查看时间',
|
||||
dataIndex: 'createTime',
|
||||
},
|
||||
{
|
||||
title: '最后一次查看设备',
|
||||
dataIndex: 'lastIp',
|
||||
},
|
||||
{
|
||||
title: '最后一次查看时间',
|
||||
dataIndex: 'updateTime',
|
||||
with: 80,
|
||||
},
|
||||
];
|
||||
const tableColumns = [
|
||||
{
|
||||
title: '姓名',
|
||||
dataIndex: 'employeeName',
|
||||
},
|
||||
{
|
||||
title: '查看次数',
|
||||
dataIndex: 'pageViewCount',
|
||||
},
|
||||
{
|
||||
title: '首次查看设备',
|
||||
dataIndex: 'firstIp',
|
||||
},
|
||||
{
|
||||
title: '首次查看时间',
|
||||
dataIndex: 'createTime',
|
||||
},
|
||||
{
|
||||
title: '最后一次查看设备',
|
||||
dataIndex: 'lastIp',
|
||||
},
|
||||
{
|
||||
title: '最后一次查看时间',
|
||||
dataIndex: 'updateTime',
|
||||
with: 80,
|
||||
},
|
||||
];
|
||||
|
||||
const tableData = ref([]);
|
||||
const total = ref(0);
|
||||
const tableLoading = ref(false);
|
||||
const tableData = ref([]);
|
||||
const total = ref(0);
|
||||
const tableLoading = ref(false);
|
||||
|
||||
const defaultQueryForm = {
|
||||
noticeId: props.noticeId,
|
||||
departmentId: null,
|
||||
keywords: '',
|
||||
pageNum: 1,
|
||||
pageSize: PAGE_SIZE,
|
||||
};
|
||||
const defaultQueryForm = {
|
||||
noticeId: props.noticeId,
|
||||
departmentId: null,
|
||||
keywords: '',
|
||||
pageNum: 1,
|
||||
pageSize: PAGE_SIZE,
|
||||
};
|
||||
|
||||
const queryForm = reactive({ ...defaultQueryForm });
|
||||
const queryForm = reactive({ ...defaultQueryForm });
|
||||
|
||||
function buildDeviceInfo(userAgent) {
|
||||
if (!userAgent) {
|
||||
return '';
|
||||
}
|
||||
|
||||
let ua = uaparser(userAgent);
|
||||
let browser = ua.browser.name;
|
||||
let os = ua.os.name;
|
||||
return browser + '/' + os + '/' + (ua.device.vendor ? ua.device.vendor + ua.device.model : '');
|
||||
}
|
||||
|
||||
async function queryViewRecord() {
|
||||
try {
|
||||
tableLoading.value = true;
|
||||
const result = await noticeApi.queryViewRecord(queryForm);
|
||||
|
||||
for (const e of result.data.list) {
|
||||
e.firstDevice = buildDeviceInfo(e.firstUserAgent);
|
||||
e.lastDevice = buildDeviceInfo(e.lastUserAgent);
|
||||
function buildDeviceInfo(userAgent) {
|
||||
if (!userAgent) {
|
||||
return '';
|
||||
}
|
||||
|
||||
tableData.value = result.data.list;
|
||||
total.value = result.data.total;
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
} finally {
|
||||
tableLoading.value = false;
|
||||
let ua = uaparser(userAgent);
|
||||
let browser = ua.browser.name;
|
||||
let os = ua.os.name;
|
||||
return browser + '/' + os + '/' + (ua.device.vendor ? ua.device.vendor + ua.device.model : '');
|
||||
}
|
||||
}
|
||||
// 点击查询
|
||||
function onSearch() {
|
||||
queryForm.pageNum = 1;
|
||||
queryViewRecord();
|
||||
}
|
||||
|
||||
// 点击重置
|
||||
function resetQuery() {
|
||||
Object.assign(queryForm, defaultQueryForm);
|
||||
queryViewRecord();
|
||||
}
|
||||
async function queryViewRecord() {
|
||||
try {
|
||||
tableLoading.value = true;
|
||||
const result = await noticeApi.queryViewRecord(queryForm);
|
||||
|
||||
for (const e of result.data.list) {
|
||||
e.firstDevice = buildDeviceInfo(e.firstUserAgent);
|
||||
e.lastDevice = buildDeviceInfo(e.lastUserAgent);
|
||||
}
|
||||
|
||||
tableData.value = result.data.list;
|
||||
total.value = result.data.total;
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
} finally {
|
||||
tableLoading.value = false;
|
||||
}
|
||||
}
|
||||
// 点击查询
|
||||
function onSearch() {
|
||||
queryForm.pageNum = 1;
|
||||
queryViewRecord();
|
||||
}
|
||||
|
||||
// 点击重置
|
||||
function resetQuery() {
|
||||
Object.assign(queryForm, defaultQueryForm);
|
||||
queryViewRecord();
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
新建
|
||||
</a-button>
|
||||
|
||||
<a-button @click="confirmBatchDelete" v-privilege="'support:dict:batchDelete'" type="text" danger :disabled="selectedRowKeyList.length === 0">
|
||||
<a-button @click="confirmBatchDelete" v-privilege="'support:dict:batchDelete'" type="primary" danger :disabled="selectedRowKeyList.length === 0">
|
||||
<template #icon>
|
||||
<DeleteOutlined />
|
||||
</template>
|
||||
|
||||
@@ -165,7 +165,7 @@
|
||||
import JobFormModal from './components/job-form-modal.vue';
|
||||
import JobLogListModal from './components/job-log-list-modal.vue';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading/index.js';
|
||||
|
||||
const activeKey = ref('1');
|
||||
const columns = ref([
|
||||
{
|
||||
title: 'id',
|
||||
@@ -242,8 +242,6 @@
|
||||
},
|
||||
]);
|
||||
|
||||
const activeKey = ref('1');
|
||||
|
||||
// ---------------- 查询数据 -----------------------
|
||||
|
||||
const queryFormState = {
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
list-type="picture-card"
|
||||
class="avatar-uploader"
|
||||
:show-upload-list="false"
|
||||
:headers="{ 'x-access-token': useUserStore().getToken }"
|
||||
:headers="{ Authorization: 'Bearer ' + useUserStore().getToken }"
|
||||
:customRequest="customRequest"
|
||||
:before-upload="beforeUpload"
|
||||
>
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
<div class="password-form-area">
|
||||
<a-form ref="formRef" :model="form" :rules="rules" layout="vertical">
|
||||
<a-form-item label="原密码" name="oldPassword">
|
||||
<a-input-password class="form-item" v-model:value.trim="form.oldPassword" type="password" placeholder="请输入原密码" />
|
||||
<a-input-password class="form-item" v-model:value.trim="form.oldPassword" type="password" placeholder="请输入原密码" autocomplete="off" />
|
||||
</a-form-item>
|
||||
<a-form-item label="新密码" name="newPassword" :help="tips">
|
||||
<a-input-password class="form-item" v-model:value.trim="form.newPassword" type="password" placeholder="请输入新密码" />
|
||||
<a-input-password class="form-item" v-model:value.trim="form.newPassword" type="password" placeholder="请输入新密码" autocomplete="off" />
|
||||
</a-form-item>
|
||||
<a-form-item label="确认密码" name="confirmPwd" :help="tips">
|
||||
<a-input-password class="form-item" v-model:value.trim="form.confirmPwd" type="password" placeholder="请输入确认密码" />
|
||||
<a-input-password class="form-item" v-model:value.trim="form.confirmPwd" type="password" placeholder="请输入确认密码" autocomplete="off" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<a-button type="primary" style="margin: 20px 0 0 250px" @click="onSubmit">修改密码</a-button>
|
||||
|
||||
@@ -31,9 +31,13 @@
|
||||
});
|
||||
// 选中的菜单
|
||||
let selectedMenu = ref({ menuId: 0 });
|
||||
let selectedKeys = computed(() => {
|
||||
return _.isEmpty(selectedMenu.value) ? [] : [selectedMenu.value.menuId];
|
||||
});
|
||||
let selectedKeys = ref([]);
|
||||
watch(
|
||||
() => selectedMenu.value,
|
||||
(newQuery, oldQuery) => {
|
||||
selectedKeys.value = _.isEmpty(selectedMenu.value) ? [] : [selectedMenu.value.menuId];
|
||||
}
|
||||
);
|
||||
|
||||
function selectMenu(menuId) {
|
||||
selectedMenu.value = menuList.value.find((e) => e.menuId === menuId);
|
||||
|
||||
@@ -28,13 +28,13 @@
|
||||
</a-modal>
|
||||
</template>
|
||||
<script setup>
|
||||
import message from 'ant-design-vue/lib/message';
|
||||
import { reactive, ref } from 'vue';
|
||||
import { departmentApi } from '/@/api/system/department-api';
|
||||
import DepartmentTreeSelect from '/@/components/system/department-tree-select/index.vue';
|
||||
import EmployeeSelect from '/@/components/system/employee-select/index.vue';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import message from 'ant-design-vue/lib/message';
|
||||
import { nextTick, reactive, ref } from 'vue';
|
||||
import { departmentApi } from '/@/api/system/department-api';
|
||||
import DepartmentTreeSelect from '/@/components/system/department-tree-select/index.vue';
|
||||
import EmployeeSelect from '/@/components/system/employee-select/index.vue';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
|
||||
// ----------------------- 对外暴漏 ---------------------
|
||||
|
||||
@@ -45,27 +45,42 @@ defineExpose({
|
||||
// ----------------------- modal 的显示与隐藏 ---------------------
|
||||
const emits = defineEmits(['refresh']);
|
||||
|
||||
const visible = ref(false);
|
||||
function showModal(data) {
|
||||
visible.value = true;
|
||||
updateFormData(data);
|
||||
}
|
||||
function closeModal() {
|
||||
visible.value = false;
|
||||
resetFormData();
|
||||
}
|
||||
const visible = ref(false);
|
||||
function showModal(data) {
|
||||
visible.value = true;
|
||||
updateFormData(data);
|
||||
nextTick(() => {
|
||||
// 解决弹窗错误信息显示,没有可忽略
|
||||
const domArr = document.getElementsByClassName('ant-modal');
|
||||
if (domArr && domArr.length > 0) {
|
||||
Array.from(domArr).forEach((item) => {
|
||||
if (item.childNodes && item.childNodes.length > 0) {
|
||||
Array.from(item.childNodes).forEach((child) => {
|
||||
if (child.setAttribute) {
|
||||
child.setAttribute('aria-hidden', 'false');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function closeModal() {
|
||||
visible.value = false;
|
||||
resetFormData();
|
||||
}
|
||||
|
||||
// ----------------------- form 表单操作 ---------------------
|
||||
const formRef = ref();
|
||||
const departmentTreeSelect = ref();
|
||||
const defaultDepartmentForm = {
|
||||
id: undefined,
|
||||
managerId: undefined, //部门负责人
|
||||
name: undefined,
|
||||
parentId: undefined,
|
||||
sort: 0,
|
||||
};
|
||||
const employeeSelect = ref();
|
||||
// ----------------------- form 表单操作 ---------------------
|
||||
const formRef = ref();
|
||||
const departmentTreeSelect = ref();
|
||||
const defaultDepartmentForm = {
|
||||
id: undefined,
|
||||
managerId: undefined, //部门负责人
|
||||
name: undefined,
|
||||
parentId: undefined,
|
||||
sort: 0,
|
||||
};
|
||||
const employeeSelect = ref();
|
||||
|
||||
let formState = reactive({
|
||||
...defaultDepartmentForm,
|
||||
@@ -91,49 +106,49 @@ function resetFormData() {
|
||||
Object.assign(formState, defaultDepartmentForm);
|
||||
}
|
||||
|
||||
async function handleOk() {
|
||||
try {
|
||||
await formRef.value.validate();
|
||||
if (formState.departmentId) {
|
||||
updateDepartment();
|
||||
} else {
|
||||
addDepartment();
|
||||
async function handleOk() {
|
||||
try {
|
||||
await formRef.value.validate();
|
||||
if (formState.departmentId) {
|
||||
updateDepartment();
|
||||
} else {
|
||||
addDepartment();
|
||||
}
|
||||
} catch (error) {
|
||||
message.error('参数验证错误,请仔细填写表单数据!');
|
||||
}
|
||||
} catch (error) {
|
||||
message.error('参数验证错误,请仔细填写表单数据!');
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------- form 表单 ajax 操作 ---------------------
|
||||
//添加部门ajax请求
|
||||
async function addDepartment() {
|
||||
SmartLoading.show();
|
||||
try {
|
||||
await departmentApi.addDepartment(formState);
|
||||
emits('refresh');
|
||||
closeModal();
|
||||
} catch (error) {
|
||||
smartSentry.captureError(error);
|
||||
} finally {
|
||||
SmartLoading.hide();
|
||||
}
|
||||
}
|
||||
|
||||
//更新部门ajax请求
|
||||
async function updateDepartment() {
|
||||
SmartLoading.show();
|
||||
try {
|
||||
if (formState.parentId == formState.departmentId) {
|
||||
message.warning('上级部门不能为自己');
|
||||
return;
|
||||
// ----------------------- form 表单 ajax 操作 ---------------------
|
||||
//添加部门ajax请求
|
||||
async function addDepartment() {
|
||||
SmartLoading.show();
|
||||
try {
|
||||
await departmentApi.addDepartment(formState);
|
||||
emits('refresh');
|
||||
closeModal();
|
||||
} catch (error) {
|
||||
smartSentry.captureError(error);
|
||||
} finally {
|
||||
SmartLoading.hide();
|
||||
}
|
||||
}
|
||||
|
||||
//更新部门ajax请求
|
||||
async function updateDepartment() {
|
||||
SmartLoading.show();
|
||||
try {
|
||||
if (formState.parentId == formState.departmentId) {
|
||||
message.warning('上级菜单不能为自己');
|
||||
return;
|
||||
}
|
||||
await departmentApi.updateDepartment(formState);
|
||||
emits('refresh');
|
||||
closeModal();
|
||||
} catch (error) {
|
||||
smartSentry.captureError(error);
|
||||
} finally {
|
||||
SmartLoading.hide();
|
||||
}
|
||||
await departmentApi.updateDepartment(formState);
|
||||
emits('refresh');
|
||||
closeModal();
|
||||
} catch (error) {
|
||||
smartSentry.captureError(error);
|
||||
} finally {
|
||||
SmartLoading.hide();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
>
|
||||
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 6 }">
|
||||
<a-form-item label="职务名称" name="positionName">
|
||||
<a-input style="width: 100%" v-model:value="form.positionName" placeholder="职务名称"/>
|
||||
<a-input style="width: 100%" v-model:value="form.positionName" placeholder="职务名称" />
|
||||
</a-form-item>
|
||||
<a-form-item label="职级" name="level">
|
||||
<a-input style="width: 100%" v-model:value="form.level" placeholder="职级"/>
|
||||
<a-input style="width: 100%" v-model:value="form.level" placeholder="职级" />
|
||||
</a-form-item>
|
||||
<a-form-item label="排序" name="sort">
|
||||
<a-input-number :min="0" :step="1" :precision="0" style="width: 100%" v-model:value="form.sort" placeholder="排序"/>
|
||||
<a-input-number :min="0" :step="1" :precision="0" style="width: 100%" v-model:value="form.sort" placeholder="排序" />
|
||||
</a-form-item>
|
||||
<a-form-item label="备注" name="remark">
|
||||
<a-input style="width: 100%" v-model:value="form.remark" placeholder="备注"/>
|
||||
<a-input style="width: 100%" v-model:value="form.remark" placeholder="备注" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
@@ -39,86 +39,100 @@
|
||||
</a-modal>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref, nextTick } from 'vue';
|
||||
import _ from 'lodash';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import { positionApi } from '/@/api/system/position-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import { reactive, ref, nextTick } from 'vue';
|
||||
import _ from 'lodash';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import { positionApi } from '/@/api/system/position-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
// ------------------------ 事件 ------------------------
|
||||
// ------------------------ 事件 ------------------------
|
||||
|
||||
const emits = defineEmits(['reloadList']);
|
||||
const emits = defineEmits(['reloadList']);
|
||||
|
||||
// ------------------------ 显示与隐藏 ------------------------
|
||||
// 是否显示
|
||||
const visibleFlag = ref(false);
|
||||
// ------------------------ 显示与隐藏 ------------------------
|
||||
// 是否显示
|
||||
const visibleFlag = ref(false);
|
||||
|
||||
function show (rowData) {
|
||||
Object.assign(form, formDefault);
|
||||
if (rowData && !_.isEmpty(rowData)) {
|
||||
Object.assign(form, rowData);
|
||||
}
|
||||
visibleFlag.value = true;
|
||||
nextTick(() => {
|
||||
formRef.value.clearValidate();
|
||||
});
|
||||
}
|
||||
|
||||
function onClose () {
|
||||
Object.assign(form, formDefault);
|
||||
visibleFlag.value = false;
|
||||
}
|
||||
|
||||
// ------------------------ 表单 ------------------------
|
||||
|
||||
// 组件ref
|
||||
const formRef = ref();
|
||||
|
||||
const formDefault = {
|
||||
positionId: undefined,
|
||||
positionName: undefined, //职务名称
|
||||
level: undefined,//职纪
|
||||
sort: 0,
|
||||
remark: undefined, //备注
|
||||
};
|
||||
|
||||
let form = reactive({ ...formDefault });
|
||||
|
||||
const rules = {
|
||||
positionName: [{ required: true, message: '请输入职务名称' }],
|
||||
};
|
||||
|
||||
// 点击确定,验证表单
|
||||
async function onSubmit () {
|
||||
try {
|
||||
await formRef.value.validateFields();
|
||||
save();
|
||||
} catch (err) {
|
||||
message.error('参数验证错误,请仔细填写表单数据!');
|
||||
}
|
||||
}
|
||||
|
||||
// 新建、编辑API
|
||||
async function save () {
|
||||
SmartLoading.show();
|
||||
try {
|
||||
if (form.positionId) {
|
||||
await positionApi.update(form);
|
||||
} else {
|
||||
await positionApi.add(form);
|
||||
function show(rowData) {
|
||||
Object.assign(form, formDefault);
|
||||
if (rowData && !_.isEmpty(rowData)) {
|
||||
Object.assign(form, rowData);
|
||||
}
|
||||
message.success('操作成功');
|
||||
emits('reloadList');
|
||||
onClose();
|
||||
} catch (err) {
|
||||
smartSentry.captureError(err);
|
||||
} finally {
|
||||
SmartLoading.hide();
|
||||
}
|
||||
}
|
||||
visibleFlag.value = true;
|
||||
nextTick(() => {
|
||||
formRef.value.clearValidate();
|
||||
|
||||
defineExpose({
|
||||
show,
|
||||
});
|
||||
// 解决弹窗错误信息显示,没有可忽略
|
||||
const domArr = document.getElementsByClassName('ant-modal');
|
||||
if (domArr && domArr.length > 0) {
|
||||
Array.from(domArr).forEach((item) => {
|
||||
if (item.childNodes && item.childNodes.length > 0) {
|
||||
Array.from(item.childNodes).forEach((child) => {
|
||||
if (child.setAttribute) {
|
||||
child.setAttribute('aria-hidden', 'false');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onClose() {
|
||||
Object.assign(form, formDefault);
|
||||
visibleFlag.value = false;
|
||||
}
|
||||
|
||||
// ------------------------ 表单 ------------------------
|
||||
|
||||
// 组件ref
|
||||
const formRef = ref();
|
||||
|
||||
const formDefault = {
|
||||
positionId: undefined,
|
||||
positionName: undefined, //职务名称
|
||||
level: undefined, //职纪
|
||||
sort: 0,
|
||||
remark: undefined, //备注
|
||||
};
|
||||
|
||||
let form = reactive({ ...formDefault });
|
||||
|
||||
const rules = {
|
||||
positionName: [{ required: true, message: '请输入职务名称' }],
|
||||
};
|
||||
|
||||
// 点击确定,验证表单
|
||||
async function onSubmit() {
|
||||
try {
|
||||
await formRef.value.validateFields();
|
||||
save();
|
||||
} catch (err) {
|
||||
message.error('参数验证错误,请仔细填写表单数据!');
|
||||
}
|
||||
}
|
||||
|
||||
// 新建、编辑API
|
||||
async function save() {
|
||||
SmartLoading.show();
|
||||
try {
|
||||
if (form.positionId) {
|
||||
await positionApi.update(form);
|
||||
} else {
|
||||
await positionApi.add(form);
|
||||
}
|
||||
message.success('操作成功');
|
||||
emits('reloadList');
|
||||
onClose();
|
||||
} catch (err) {
|
||||
smartSentry.captureError(err);
|
||||
} finally {
|
||||
SmartLoading.hide();
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show,
|
||||
});
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user