v3.15.0【新增】升级SaToken到最新版本;【新增】重磅优化 数据字典;【新增】升级wangEditor-next;【新增】优化缓存实现redis与caffeine

This commit is contained in:
zhuoda
2025-03-31 23:19:41 +08:00
parent 7ef9000c62
commit 4683e31290
347 changed files with 4203 additions and 3792 deletions

View File

@@ -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="GOODS_PLACE" v-model:value="form.place" mode="tags" />
<DictSelect width="100%" :dict-code="DICT_CODE_ENUM.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">
@@ -65,6 +65,7 @@
import { smartSentry } from '/@/lib/smart-sentry';
import SmartEnumSelect from '/@/components/framework/smart-enum-select/index.vue';
import DictSelect from '/@/components/support/dict-select/index.vue';
import { DICT_CODE_ENUM } from '/@/constants/support/dict-const';
// emit
const emit = defineEmits(['reloadList']);

View File

@@ -25,7 +25,7 @@
</a-form-item>
<a-form-item label="产地" name="place" class="smart-query-form-item">
<DictSelect key-code="GOODS_PLACE" v-model:value="queryForm.place" width="120px" />
<DictSelect :dictCode="DICT_CODE_ENUM.GOODS_PLACE" v-model:value="queryForm.place" width="120px" />
</a-form-item>
<a-form-item label="商品状态" name="goodsStatus" class="smart-query-form-item">
@@ -44,13 +44,13 @@
<a-button-group>
<a-button type="primary" @click="onSearch" v-privilege="'goods:query'">
<template #icon>
<ReloadOutlined />
<SearchOutlined />
</template>
查询
</a-button>
<a-button @click="resetQuery" v-privilege="'goods:query'">
<template #icon>
<SearchOutlined />
<ReloadOutlined />
</template>
重置
</a-button>
@@ -93,7 +93,7 @@
</a-button>
</div>
<div class="smart-table-setting-block">
<TableOperator v-model="columns" :tableId="TABLE_ID_CONST.BUSINESS.ERP.GOODS" :refresh="queryData" />
<TableOperator v-model="columns" :tableId="TABLE_ID_CONST.BUSINESS.ERP.GOODS" :refresh="queryData"/>
</div>
</a-row>
<!---------- 表格操作行 end ----------->
@@ -120,7 +120,7 @@
{{ text }}
</template>
<template v-if="column.dataIndex === 'place'">
<DictPreview :options="descList.GOODS_PLACE" :value="text" />
<DictLabel :dict-code="DICT_CODE_ENUM.GOODS_PLACE" :dataValue="text" />
</template>
<template v-if="column.dataIndex === 'remark'">
<span>{{ text ? text : '' }}</span>
@@ -203,11 +203,10 @@
import DictSelect from '/@/components/support/dict-select/index.vue';
import SmartEnumSelect from '/@/components/framework/smart-enum-select/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';
import SmartHeaderCell from '/@/components/support/table-header-cell/index.vue';
import { DICT_CODE_ENUM } from '/@/constants/support/dict-const.js';
import DictLabel from '/@/components/support/dict-label/index.vue';
const descList = useDict('GOODS_PLACE');
// ---------------------------- 表格列 ----------------------------
const columns = ref([
@@ -249,7 +248,7 @@
resizable: true,
filterOptions: {
type: 'dict-select',
keyCode: 'GOODS_PLACE',
dictCode: DICT_CODE_ENUM.GOODS_PLACE,
},
width: 150,
},

View File

@@ -25,13 +25,13 @@
<a-button-group>
<a-button type="primary" @click="onSearch">
<template #icon>
<ReloadOutlined />
<SearchOutlined />
</template>
查询
</a-button>
<a-button @click="resetQuery" class="smart-margin-left10">
<template #icon>
<SearchOutlined />
<ReloadOutlined />
</template>
重置
</a-button>

View File

@@ -19,13 +19,13 @@
<a-button-group>
<a-button type="primary" @click="onSearch">
<template #icon>
<ReloadOutlined />
<SearchOutlined />
</template>
查询
</a-button>
<a-button @click="resetQuery">
<template #icon>
<SearchOutlined />
<ReloadOutlined />
</template>
重置
</a-button>

View File

@@ -1,18 +1,18 @@
<!--
* 代码生成 配置信息
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-09-22 21:50:41
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-09-22 21:50:41
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
-->
<template>
<a-alert :closable="true" message="请务必将每一个字段的 “ 字段名词 ” 填写完整!!!" type="success" show-icon>
<template #icon><smile-outlined /></template>
</a-alert>
<!-- 为了方便再配置时中途新增字典后 可以重新刷新字典下拉 (需要先随便选择一个字典后才能看到最新的字典) -->
<div style="float: right; padding: 10px 0px">
<div style="float: right; padding: 10px 0">
<a-button type="primary" @click="refreshDict">刷新字典</a-button>
</div>
<a-table
@@ -68,7 +68,7 @@
</template>
<template v-if="column.dataIndex === 'dict'">
<DictKeySelect ref="dictRef" v-model:value="record.dict" />
<DictCodeSelect ref="dictRef" v-model:value="record.dict" />
</template>
<template v-if="column.dataIndex === 'enumName'">
@@ -81,7 +81,7 @@
<script setup>
import { inject, ref } from 'vue';
import { checkExistEnum, convertJavaEnumName, getJavaType, getJsType, JavaTypeList, JsTypeList } from '../../code-generator-util';
import DictKeySelect from '/@/components/support/dict-key-select/index.vue';
import DictCodeSelect from '/@/components/support/dict-code-select/index.vue';
import { convertUpperCamel, convertLowerCamel } from '/@/utils/str-util';
import _ from 'lodash';

View File

@@ -19,13 +19,13 @@
<a-button-group>
<a-button type="primary" @click="onSearch" v-privilege="'support:config:query'">
<template #icon>
<ReloadOutlined />
<SearchOutlined />
</template>
查询
</a-button>
<a-button @click="resetQuery" v-privilege="'support:config:query'">
<template #icon>
<SearchOutlined />
<ReloadOutlined />
</template>
重置
</a-button>

View File

@@ -1,23 +1,24 @@
<!--
* 字典 value 弹窗
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-06-08 21:50:41
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
* 字典 数据 表单 弹窗
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2025-03-21 21:50:41
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
-->
<template>
<a-modal :open="visible" :title="form.dictValueId ? '编辑' : '添加'" ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }" :wrapper-col="{ span: 12 }">
<a-form-item label="编码" name="valueCode">
<a-input v-model:value="form.valueCode" placeholder="请输入编码" />
<a-modal :open="visible" :title="form.dictDataId ? '编辑字典值' : '添加字典值'" ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
<br/>
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }" :wrapper-col="{ span: 16 }">
<a-form-item label="字典项名称" name="dataLabel">
<a-input v-model:value="form.dataLabel" placeholder="请输入 字典项名称" />
</a-form-item>
<a-form-item label="名称" name="valueName">
<a-input v-model:value="form.valueName" placeholder="请输入名称" />
<a-form-item label="字典项值" name="dataValue">
<a-input v-model:value="form.dataValue" placeholder="请输入 字典项值" />
</a-form-item>
<a-form-item label="排序" name="sort">
<a-input-number v-model:value="form.sort" :min="0" :max="1000" />
<a-form-item label="排序" name="sort" help="值越大越靠前">
<a-input-number style="width: 100%" v-model:value="form.sortOrder" :min="0" :max="1000" />
</a-form-item>
<a-form-item label="备注" name="remark">
<textarea v-model="form.remark" style="width: 100%; height: 100px; outline: none"></textarea>
@@ -39,28 +40,30 @@
const formRef = ref();
const formDefault = {
dictValueId: undefined,
dictKeyId: undefined,
sort: 1,
valueCode: '',
valueName: '',
dictId: undefined,
dictCode: undefined,
dictDataId: undefined,
sortOrder: 0,
dataValue: '',
dataLabel: '',
remark: '',
};
let form = reactive({ ...formDefault });
const rules = {
valueCode: [{ required: true, message: '请输入编码' }],
valueName: [{ required: true, message: '请输入名称' }],
sort: [{ required: true, message: '请输入排序' }],
dataValue: [{ required: true, message: '请输入 字典项值' }],
dataLabel: [{ required: true, message: '请输入 字典项名称' }],
sortOrder: [{ required: true, message: '请输入排序' }],
};
//
const visible = ref(false);
function showModal(rowData, dictKeyId) {
function showModal(rowData, dictId, dictCode) {
Object.assign(form, formDefault);
if (rowData) {
Object.assign(form, rowData);
}
form.dictKeyId = dictKeyId;
form.dictId = dictId;
form.dictCode = dictCode;
visible.value = true;
}
@@ -75,12 +78,12 @@
.then(async () => {
SmartLoading.show();
try {
if (form.dictValueId) {
await dictApi.valueEdit(form);
if (form.dictDataId) {
await dictApi.updateDictData(form);
} else {
await dictApi.valueAdd(form);
await dictApi.addDictData(form);
}
message.success(`${form.dictKeyId ? '修改' : '添加'}成功`);
message.success(`${form.dictDataId ? '修改' : '添加'}成功`);
emit('reloadList');
onClose();
} catch (error) {

View File

@@ -0,0 +1,247 @@
<!--
* 字典数据 弹窗
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2025-03-08 21:50:41
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
-->
<template>
<a-drawer :width="1000" :open="visible" :body-style="{ paddingBottom: '80px' }" title="字典值" @close="onClose">
<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: 300px" v-model:value="keywords" @change="search" placeholder="关键字" />
</a-form-item>
<a-form-item label="禁用" class="smart-query-form-item">
<BooleanSelect v-model:value="disabledFlag" @change="search" style="width: 150px" />
</a-form-item>
<a-form-item class="smart-query-form-item smart-margin-left10">
<a-button type="primary" @click="queryData">
<template #icon> <SearchOutlined /> </template>
查询
</a-button>
<a-button @click="resetQuery" class="smart-margin-left10">
<template #icon> <ReloadOutlined /> </template>
重置
</a-button>
</a-form-item>
</a-row>
</a-form>
<a-row class="smart-table-btn-block">
<div class="smart-table-operate-block">
<a-button @click="addOrUpdateData" type="primary">
<template #icon>
<PlusOutlined />
</template>
新建
</a-button>
<a-button @click="confirmBatchDelete" type="primary" danger :disabled="selectedRowKeyList.length === 0">
<template #icon>
<DeleteOutlined />
</template>
批量删除
</a-button>
</div>
<div class="smart-table-setting-block"></div>
</a-row>
<a-table
size="small"
:dataSource="tableData"
:columns="columns"
rowKey="dictDataId"
:pagination="false"
:row-selection="{ selectedRowKeys: selectedRowKeyList, onChange: onSelectChange }"
bordered
>
<template #bodyCell="{ record, column }">
<template v-if="column.dataIndex === 'disabledFlag'">
<a-switch
@change="(checked) => handleChangeDisabled(checked, record)"
v-model:checked="record.enabled"
checked-children="启用中"
un-checked-children="已禁用"
/>
</template>
<template v-if="column.dataIndex === 'action'">
<a-button @click="addOrUpdateData(record)" type="link">编辑</a-button>
</template>
</template>
</a-table>
<div class="smart-query-table-page">共计 {{ tableData.length }} </div>
<DictDataFormModal ref="dictDataFormModalRef" @reloadList="queryData" />
</a-drawer>
</template>
<script setup>
import { reactive, ref } from 'vue';
import DictDataFormModal from './dict-data-form-modal.vue';
import { dictApi } from '/@/api/support/dict-api';
import { SmartLoading } from '/@/components/framework/smart-loading';
import { Modal } from 'ant-design-vue';
import { message } from 'ant-design-vue';
import { smartSentry } from '/@/lib/smart-sentry';
import BooleanSelect from '/@/components/framework/boolean-select/index.vue';
import _ from 'lodash';
// 是否展示抽屉
const visible = ref(false);
const dictId = ref(undefined);
const dictCode = ref(undefined);
function showModal(id, code) {
dictId.value = id;
dictCode.value = code;
visible.value = true;
queryData();
}
function onClose() {
visible.value = false;
dictId.value = undefined;
dictCode.value = undefined;
}
const columns = reactive([
{
title: '值',
dataIndex: 'dataValue',
},
{
title: '名称',
dataIndex: 'dataLabel',
},
{
title: '状态',
width: 90,
dataIndex: 'disabledFlag',
},
{
title: '排序',
width: 50,
dataIndex: 'sortOrder',
},
{
title: '备注',
width: 200,
ellipsis: true,
dataIndex: 'remark',
},
{
title: '更新时间',
width: 150,
dataIndex: 'updateTime',
},
{
title: '操作',
width: 70,
dataIndex: 'action',
},
]);
// ----------------------- 表格 查询 ------------------------
const keywords = ref(undefined);
const disabledFlag = ref(null);
const selectedRowKeyList = ref([]);
const tableLoading = ref(false);
const dictDataList = ref([]);
const tableData = ref([]);
function onSelectChange(selectedRowKeys) {
selectedRowKeyList.value = selectedRowKeys;
}
function search() {
tableData.value = dictDataList.value.filter((item) => {
let keywordsFilterFlag = true;
if (keywords.value) {
keywordsFilterFlag =
_.includes(item.dataValue.toLowerCase(), keywords.value.toLowerCase()) ||
_.includes(item.dataLabel.toLowerCase(), keywords.value.toLowerCase()) ||
_.includes(item.remark.toLowerCase(), keywords.value.toLowerCase());
}
let disabledFilterFlag = _.isNull(disabledFlag.value) ? true : item.disabledFlag === disabledFlag.value;
return disabledFilterFlag && keywordsFilterFlag;
});
}
function resetQuery() {
keywords.value = null;
disabledFlag.value = null;
queryData();
}
async function queryData() {
try {
tableLoading.value = true;
let responseData = await dictApi.queryDictData(dictId.value);
responseData.data.map((e) => (e.enabled = !e.disabledFlag));
dictDataList.value = responseData.data;
search();
} catch (e) {
smartSentry.captureError(e);
} finally {
tableLoading.value = false;
}
}
// ----------------------- 启用/禁用 ------------------------
async function handleChangeDisabled(disabledFlag, dictData) {
SmartLoading.show();
try {
await dictApi.updateDictDataDisabled(dictData.dictDataId);
dictData.disabledFlag = !disabledFlag;
message.success('操作成功');
} catch (e) {
smartSentry.captureError(e);
} finally {
SmartLoading.hide();
}
}
// ----------------------- 批量 删除 ------------------------
function confirmBatchDelete() {
Modal.confirm({
title: '提示',
content: '确定要删除选中值吗?',
okText: '删除',
okType: 'danger',
onOk() {
batchDelete();
},
cancelText: '取消',
onCancel() {},
});
}
async function batchDelete() {
try {
SmartLoading.show();
await dictApi.batchDeleteDictData(selectedRowKeyList.value);
message.success('删除成功');
await queryData();
} catch (e) {
smartSentry.captureError(e);
} finally {
SmartLoading.hide();
}
}
// ----------------------- 弹窗表单操作 ------------------------
const dictDataFormModalRef = ref();
function addOrUpdateData(rowData) {
dictDataFormModalRef.value.showModal(rowData, dictId.value, dictCode.value);
}
defineExpose({
showModal,
});
</script>

View File

@@ -1,20 +1,21 @@
<!--
* 字典key 弹窗
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-06-08 21:50:41
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
* 字典表单 弹窗
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2025-03-08 21:50:41
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
-->
<template>
<a-modal :open="visible" :title="form.dictKeyId ? '编辑' : '添加'" ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }" :wrapper-col="{ span: 12 }">
<a-form-item label="编码" name="keyCode">
<a-input v-model:value="form.keyCode" placeholder="请输入编码" />
<a-modal :open="visible" :title="form.dictId ? '编辑字典' : '添加字典'" ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
<br/>
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }" :wrapper-col="{ span: 19 }">
<a-form-item label="字典编码" name="dictCode">
<a-input v-model:value="form.dictCode" placeholder="请输入编码" />
</a-form-item>
<a-form-item label="名称" name="keyName">
<a-input v-model:value="form.keyName" placeholder="请输入名称" />
<a-form-item label="字典名称" name="dictName">
<a-input v-model:value="form.dictName" placeholder="请输入名称" />
</a-form-item>
<a-form-item label="备注" name="remark">
@@ -37,15 +38,15 @@
const formRef = ref();
const formDefault = {
dictKeyId: undefined,
keyCode: '',
keyName: '',
dictId: undefined,
dictCode: '',
dictName: '',
remark: '',
};
let form = reactive({ ...formDefault });
const rules = {
keyCode: [{ required: true, message: '请输入编码' }],
keyName: [{ required: true, message: '请输入名称' }],
dictCode: [{ required: true, message: '请输入编码' }],
dictName: [{ required: true, message: '请输入名称' }],
};
//
const visible = ref(false);
@@ -69,12 +70,12 @@
.then(async () => {
SmartLoading.show();
try {
if (form.dictKeyId) {
await dictApi.keyEdit(form);
if (form.dictId) {
await dictApi.updateDict(form);
} else {
await dictApi.keyAdd(form);
await dictApi.addDict(form);
}
message.success(`${form.dictKeyId ? '修改' : '添加'}成功`);
message.success(`${form.dictName ? '修改' : '添加'}成功`);
emit('reloadList');
onClose();
} catch (error) {

View File

@@ -1,221 +0,0 @@
<!--
* 字典 value 弹窗
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-06-08 21:50:41
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
-->
<template>
<a-drawer :width="800" :open="visible" :body-style="{ paddingBottom: '80px' }" title="字典值" @close="onClose">
<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: 300px" v-model:value="queryForm.searchWord" placeholder="关键字" />
</a-form-item>
<a-form-item class="smart-query-form-item smart-margin-left10">
<a-button type="primary" @click="ajaxQuery">
<template #icon>
<ReloadOutlined />
</template>
查询
</a-button>
<a-button @click="resetQuery">
<template #icon>
<SearchOutlined />
</template>
重置
</a-button>
</a-form-item>
</a-row>
</a-form>
<a-card size="small" :bordered="false">
<a-row class="smart-table-btn-block">
<div class="smart-table-operate-block">
<a-button @click="addOrUpdateValue" type="primary" size="small">
<template #icon>
<PlusOutlined />
</template>
新建
</a-button>
<a-button @click="confirmBatchDelete" type="text" danger size="small" :disabled="selectedRowKeyList.length == 0">
<template #icon>
<DeleteOutlined />
</template>
批量删除
</a-button>
</div>
<div class="smart-table-setting-block"></div>
</a-row>
<a-table
size="small"
:dataSource="tableData"
:columns="columns"
rowKey="dictValueId"
:pagination="false"
:row-selection="{ selectedRowKeys: selectedRowKeyList, onChange: onSelectChange }"
bordered
>
<template #bodyCell="{ record, column }">
<template v-if="column.dataIndex === 'action'">
<a-button @click="addOrUpdateValue(record)" type="link">编辑</a-button>
</template>
</template>
</a-table>
<div class="smart-query-table-page">
<a-pagination
showSizeChanger
showQuickJumper
show-less-items
:pageSizeOptions="PAGE_SIZE_OPTIONS"
:defaultPageSize="queryForm.pageSize"
v-model:current="queryForm.pageNum"
v-model:pageSize="queryForm.pageSize"
:total="total"
@change="ajaxQuery"
@showSizeChange="ajaxQuery"
:show-total="(total) => `${total}`"
/>
</div>
</a-card>
<DictValueOperateModal ref="operateModal" @reloadList="ajaxQuery" />
</a-drawer>
</template>
<script setup>
import { reactive, ref } from 'vue';
import DictValueOperateModal from './dict-value-operate-modal.vue';
import { PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
import { dictApi } from '/@/api/support/dict-api';
import { SmartLoading } from '/@/components/framework/smart-loading';
import { Modal } from 'ant-design-vue';
import { message } from 'ant-design-vue';
import { smartSentry } from '/@/lib/smart-sentry';
// 是否展示抽屉
const visible = ref(false);
const dictKeyId = ref(undefined);
function showModal(keyId) {
dictKeyId.value = keyId;
visible.value = true;
ajaxQuery();
}
function onClose() {
visible.value = false;
dictKeyId.value = undefined;
}
const columns = reactive([
{
title: 'ID',
width: 80,
dataIndex: 'dictValueId',
},
{
title: '编码',
dataIndex: 'valueCode',
},
{
title: '名称',
dataIndex: 'valueName',
},
{
title: '排序',
width: 80,
dataIndex: 'sort',
},
{
title: '备注',
dataIndex: 'remark',
},
{
title: '操作',
dataIndex: 'action',
fixed: 'right',
},
]);
// ----------------------- 表格 查询 ------------------------
const queryFormState = {
dictKeyId: undefined,
searchWord: '',
pageNum: 1,
pageSize: 10,
};
const queryForm = reactive({ ...queryFormState });
const selectedRowKeyList = ref([]);
const tableLoading = ref(false);
const tableData = ref([]);
const total = ref(0);
function onSelectChange(selectedRowKeys) {
selectedRowKeyList.value = selectedRowKeys;
}
function resetQuery() {
Object.assign(queryForm, queryFormState);
ajaxQuery();
}
async function ajaxQuery() {
try {
tableLoading.value = true;
queryForm.dictKeyId = dictKeyId.value;
let responseModel = await dictApi.valueQuery(queryForm);
const list = responseModel.data.list;
total.value = responseModel.data.total;
tableData.value = list;
} catch (e) {
smartSentry.captureError(e);
} finally {
tableLoading.value = false;
}
}
// ----------------------- 批量 删除 ------------------------
function confirmBatchDelete() {
Modal.confirm({
title: '提示',
content: '确定要删除选中值吗?',
okText: '删除',
okType: 'danger',
onOk() {
batchDelete();
},
cancelText: '取消',
onCancel() {},
});
}
const batchDelete = async () => {
try {
SmartLoading.show();
await dictApi.valueDelete(selectedRowKeyList.value);
message.success('删除成功');
ajaxQuery();
} catch (e) {
smartSentry.captureError(e);
} finally {
SmartLoading.hide();
}
};
// ----------------------- 弹窗表单操作 ------------------------
const operateModal = ref();
function addOrUpdateValue(rowData) {
operateModal.value.showModal(rowData, dictKeyId.value);
}
defineExpose({
showModal,
});
</script>

View File

@@ -2,7 +2,7 @@
* 数据 字典
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-06-08 21:50:41
* @Date: 2025-03-26 21:50:41
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
@@ -11,20 +11,22 @@
<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: 300px" v-model:value="queryForm.searchWord" placeholder="关键字" />
<a-input style="width: 300px" v-model:value="queryForm.keywords" placeholder="编码/名称/备注" />
</a-form-item>
<a-form-item label="禁用" class="smart-query-form-item">
<BooleanSelect v-model:value="queryForm.disabledFlag" style="width: 150px" />
</a-form-item>
<a-form-item class="smart-query-form-item smart-margin-left10">
<a-button-group>
<a-button type="primary" @click="onSearch">
<template #icon>
<ReloadOutlined />
<SearchOutlined />
</template>
查询
</a-button>
<a-button @click="resetQuery">
<template #icon>
<SearchOutlined />
<ReloadOutlined />
</template>
重置
</a-button>
@@ -36,26 +38,25 @@
<a-card size="small" :bordered="false" :hoverable="true">
<a-row class="smart-table-btn-block">
<div class="smart-table-operate-block">
<a-button @click="addOrUpdateKey" v-privilege="'support:dict:add'" type="primary">
<a-button @click="addOrUpdateDict" v-privilege="'support:dict:add'" type="primary">
<template #icon>
<PlusOutlined />
</template>
新建
</a-button>
<a-button @click="confirmBatchDelete" v-privilege="'support:dict:batchDelete'" type="primary" 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>
批量删除
</a-button>
<a-button @click="cacheRefresh" v-privilege="'support:dict:refresh'" type="primary">
<template #icon>
<cloud-sync-outlined />
</template>
缓存刷新
</a-button>
</div>
<div class="smart-table-setting-block">
<TableOperator class="smart-margin-bottom5" v-model="columns" :tableId="TABLE_ID_CONST.SUPPORT.DICT" :refresh="ajaxQuery" />
@@ -73,12 +74,20 @@
:row-selection="{ selectedRowKeys: selectedRowKeyList, onChange: onSelectChange }"
>
<template #bodyCell="{ record, column }">
<template v-if="column.dataIndex === 'keyCode'">
<a @click="showValueList(record.dictKeyId)">{{ record.keyCode }}</a>
<template v-if="column.dataIndex === 'dictCode'">
<a @click="showDictData(record)">{{ record.dictCode }}</a>
</template>
<template v-if="column.dataIndex === 'disabledFlag'">
<a-switch
@change="(checked) => handleChangeDisabled(checked, record)"
v-model:checked="record.enabled"
checked-children="启用中"
un-checked-children="已禁用"
/>
</template>
<template v-else-if="column.dataIndex === 'action'">
<div class="smart-table-operate">
<a-button @click="addOrUpdateKey(record)" v-privilege="'support:dict:edit'" type="link">编辑</a-button>
<a-button @click="addOrUpdateDict(record)" v-privilege="'support:dict:edit'" type="link">编辑</a-button>
</div>
</template>
</template>
@@ -100,15 +109,15 @@
/>
</div>
<DictKeyOperateModal ref="operateModal" @reloadList="ajaxQuery" />
<DictFormModal ref="dictFormModalRef" @reloadList="ajaxQuery" />
<!-- 值列表 -->
<DictValueModal ref="dictValueModal" />
<DictDataModal ref="dictDataModalRef" />
</a-card>
</template>
<script setup>
import DictKeyOperateModal from './components/dict-key-operate-modal.vue';
import DictValueModal from './components/dict-value-modal.vue';
import { reactive, ref, onMounted } from 'vue';
import DictFormModal from './components/dict-form-modal.vue';
import DictDataModal from './components/dict-data-modal.vue';
import { onMounted, reactive, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { SmartLoading } from '/@/components/framework/smart-loading';
import { dictApi } from '/@/api/support/dict-api';
@@ -116,25 +125,36 @@
import { smartSentry } from '/@/lib/smart-sentry';
import TableOperator from '/@/components/support/table-operator/index.vue';
import { TABLE_ID_CONST } from '/@/constants/support/table-id-const';
import BooleanSelect from '/@/components/framework/boolean-select/index.vue';
const columns = ref([
{
title: 'ID',
width: 90,
dataIndex: 'dictKeyId',
dataIndex: 'dictId',
},
{
title: '编码',
dataIndex: 'keyCode',
dataIndex: 'dictCode',
},
{
title: '名称',
dataIndex: 'keyName',
dataIndex: 'dictName',
},
{
title: '备注',
dataIndex: 'remark',
},
{
title: '状态',
width: 90,
dataIndex: 'disabledFlag',
},
{
title: '更新时间',
width: 160,
dataIndex: 'updateTime',
},
{
title: '操作',
dataIndex: 'action',
@@ -146,7 +166,8 @@
// ---------------- 查询数据 -----------------
const queryFormState = {
searchWord: '',
keywords: '',
disabledFlag: null,
pageNum: 1,
pageSize: 10,
};
@@ -155,12 +176,12 @@
const selectedRowKeyList = ref([]);
const tableData = ref([]);
const total = ref(0);
const operateModal = ref();
const dictValueModal = ref();
const dictFormModalRef = ref();
const dictDataModalRef = ref();
// 显示操作记录弹窗
function showValueList(dictKeyId) {
dictValueModal.value.showModal(dictKeyId);
function showDictData(dict) {
dictDataModalRef.value.showModal(dict.dictId, dict.dictCode);
}
function onSelectChange(selectedRowKeys) {
@@ -178,9 +199,12 @@
async function ajaxQuery() {
try {
tableLoading.value = true;
let responseModel = await dictApi.keyQuery(queryForm);
const list = responseModel.data.list;
total.value = responseModel.data.total;
let responseData = await dictApi.queryDict(queryForm);
const list = responseData.data.list;
for (let item of list) {
item.enabled = !item.disabledFlag;
}
total.value = responseData.data.total;
tableData.value = list;
} catch (e) {
smartSentry.captureError(e);
@@ -189,14 +213,14 @@
}
}
// ---------------- 刷新缓存 -----------------
async function cacheRefresh() {
// ----------------------- 启用/禁用 ------------------------
async function handleChangeDisabled(disabledFlag, dict) {
SmartLoading.show();
try {
SmartLoading.show();
await dictApi.cacheRefresh();
message.success('缓存刷新成功');
ajaxQuery();
await dictApi.updateDisabled(dict.dictId);
dict.disabledFlag = !disabledFlag;
message.success('操作成功');
onSearch();
} catch (e) {
smartSentry.captureError(e);
} finally {
@@ -209,7 +233,7 @@
function confirmBatchDelete() {
Modal.confirm({
title: '提示',
content: '确定要删除选中Key吗?',
content: '确定要删除选中的字典吗?',
okText: '删除',
okType: 'danger',
onOk() {
@@ -220,23 +244,23 @@
});
}
const batchDelete = async () => {
async function batchDelete() {
try {
SmartLoading.show();
await dictApi.keyDelete(selectedRowKeyList.value);
await dictApi.batchDeleteDict(selectedRowKeyList.value);
message.success('删除成功');
ajaxQuery();
await ajaxQuery();
} catch (e) {
smartSentry.captureError(e);
} finally {
SmartLoading.hide();
}
};
}
// ---------------- 添加/更新 -----------------
function addOrUpdateKey(rowData) {
operateModal.value.showModal(rowData);
function addOrUpdateDict(rowData) {
dictFormModalRef.value.showModal(rowData);
}
onMounted(ajaxQuery);

View File

@@ -31,13 +31,13 @@
<a-button-group>
<a-button type="primary" @click="queryData">
<template #icon>
<ReloadOutlined />
<SearchOutlined />
</template>
查询
</a-button>
<a-button @click="resetQuery">
<template #icon>
<SearchOutlined />
<ReloadOutlined />
</template>
重置
</a-button>

View File

@@ -41,13 +41,13 @@
<a-button-group>
<a-button type="primary" @click="onSearch">
<template #icon>
<ReloadOutlined />
<SearchOutlined />
</template>
查询
</a-button>
<a-button @click="resetQuery">
<template #icon>
<SearchOutlined />
<ReloadOutlined />
</template>
重置
</a-button>

View File

@@ -28,13 +28,13 @@
<a-button-group>
<a-button type="primary" @click="onSearch" v-privilege="'support:job:query'">
<template #icon>
<ReloadOutlined />
<SearchOutlined />
</template>
查询
</a-button>
<a-button @click="resetQuery" v-privilege="'support:job:query'">
<template #icon>
<SearchOutlined />
<ReloadOutlined />
</template>
重置
</a-button>

View File

@@ -26,13 +26,13 @@
<a-button-group>
<a-button type="primary" @click="onSearch">
<template #icon>
<ReloadOutlined />
<SearchOutlined />
</template>
查询
</a-button>
<a-button @click="resetQuery">
<template #icon>
<SearchOutlined />
<ReloadOutlined />
</template>
重置
</a-button>

View File

@@ -31,13 +31,13 @@
<a-button-group>
<a-button type="primary" @click="onSearch" v-privilege="'support:job:query'">
<template #icon>
<ReloadOutlined />
<SearchOutlined />
</template>
查询
</a-button>
<a-button @click="resetQuery" v-privilege="'support:job:query'">
<template #icon>
<SearchOutlined />
<ReloadOutlined />
</template>
重置
</a-button>

View File

@@ -33,7 +33,7 @@
<a-button-group>
<a-button type="primary" @click="onSearch">
<template #icon>
<ReloadOutlined />
<SearchOutlined />
</template>
查询
</a-button>

View File

@@ -36,13 +36,13 @@
<a-button-group>
<a-button type="primary" @click="ajaxQuery">
<template #icon>
<ReloadOutlined />
<SearchOutlined />
</template>
查询
</a-button>
<a-button @click="resetQuery">
<template #icon>
<SearchOutlined />
<ReloadOutlined />
</template>
重置
</a-button>

View File

@@ -19,8 +19,8 @@
原理内部有三种实现方式 1) 基于内存锁实现 不支持分布式和集群 2) 基于redis锁实现 3) 基于Mysql 锁for update 实现
- 支持随机生成和查询生成记录
- 支持动态配置
</pre
>
</pre>
<div style="color:red">系统默认使用内存锁类型若修改请将后端代码 @Service 注解加到对应的实现类上SerialNumberInternServiceSerialNumberMysqlServiceSerialNumberRedisService</div>
</template>
</a-alert>

View File

@@ -26,13 +26,13 @@
<a-button-group>
<a-button type="primary" @click="ajaxQuery">
<template #icon>
<ReloadOutlined />
<SearchOutlined />
</template>
查询
</a-button>
<a-button @click="resetQuery">
<template #icon>
<SearchOutlined />
<ReloadOutlined />
</template>
重置
</a-button>

View File

@@ -9,13 +9,13 @@
<a-button-group>
<a-button v-privilege="'support:department:query'" type="primary" @click="onSearch">
<template #icon>
<ReloadOutlined />
<SearchOutlined />
</template>
查询
</a-button>
<a-button v-privilege="'support:department:query'" @click="resetQuery">
<template #icon>
<SearchOutlined />
<ReloadOutlined />
</template>
重置
</a-button>

View File

@@ -131,6 +131,8 @@
import { h } from 'vue';
import { localSave } from '/@/utils/local-util.js';
import LocalStorageKeyConst from '/@/constants/local-storage-key-const.js';
import { useDictStore } from '/@/store/modules/system/dict.js';
import {dictApi} from "/@/api/support/dict-api.js";
//--------------------- 登录表单 ---------------------------------
@@ -198,6 +200,9 @@
message.success('登录成功');
//更新用户信息到pinia
useUserStore().setUserLoginInfo(res.data);
// 初始化数据字典
const dictRes = await dictApi.getAllDictData();
useDictStore().initData(dictRes.data);
//构建系统的路由
buildRoutes();
router.push('/home');

View File

@@ -92,6 +92,8 @@
import { encryptData } from '/@/lib/encrypt';
import { localSave } from '/@/utils/local-util.js';
import LocalStorageKeyConst from '/@/constants/local-storage-key-const.js';
import { useDictStore } from '/@/store/modules/system/dict.js';
import { dictApi } from '/@/api/support/dict-api.js';
//--------------------- 登录表单 ---------------------------------
@@ -140,6 +142,9 @@
message.success('登录成功');
//更新用户信息到pinia
useUserStore().setUserLoginInfo(res.data);
// 初始化数据字典
const dictRes = await dictApi.getAllDictData();
useDictStore().initData(dictRes.data);
//构建系统的路由
buildRoutes();
router.push('/home');

View File

@@ -94,6 +94,8 @@
import { encryptData } from '/@/lib/encrypt';
import { localSave } from '/@/utils/local-util.js';
import LocalStorageKeyConst from '/@/constants/local-storage-key-const.js';
import { useDictStore } from '/@/store/modules/system/dict.js';
import { dictApi } from '/@/api/support/dict-api.js';
//--------------------- 登录表单 ---------------------------------
@@ -142,6 +144,9 @@
message.success('登录成功');
//更新用户信息到pinia
useUserStore().setUserLoginInfo(res.data);
// 初始化数据字典
const dictRes = await dictApi.getAllDictData();
useDictStore().initData(dictRes.data);
//构建系统的路由
buildRoutes();
router.push('/home');