Merge remote-tracking branch 'origin/master'

# Conflicts:
#	smart-admin-web-javascript/src/views/business/erp/goods/goods-list.vue
#	smart-admin-web-typescript/src/views/business/erp/goods/goods-list.vue
This commit is contained in:
zhoumingfa
2025-03-31 23:37:57 +08:00
343 changed files with 3789 additions and 3672 deletions

View File

@@ -1,5 +1,6 @@
node_modules
.DS_Store
**/.DS_Store
dist
dist-ssr
*.local

View File

@@ -18,8 +18,8 @@
"type": "module",
"dependencies": {
"@ant-design/icons-vue": "^7.0.1",
"@wangeditor/editor": "5.1.14",
"@wangeditor/editor-for-vue": "5.1.12",
"@wangeditor-next/editor": "5.6.34",
"@wangeditor-next/editor-for-vue": "5.1.14",
"ant-design-vue": "4.2.5",
"axios": "1.6.8",
"clipboard": "2.0.11",
@@ -43,8 +43,7 @@
"vue": "3.4.27",
"vue-i18n": "9.13.1",
"vue-router": "4.3.2",
"vue3-json-viewer": "2.2.2",
"vue3-tabs-chrome": "^0.3.3"
"vue3-json-viewer": "2.2.2"
},
"devDependencies": {
"@vitejs/plugin-vue": "5.0.4",

View File

@@ -51,7 +51,7 @@
import { theme } from 'ant-design-vue';
import { themeColors } from '/@/theme/color.js';
import { Popover } from 'ant-design-vue';
import SmartCopyIcon from '/@/components/smart-copy-icon/index.vue';
import SmartCopyIcon from '/@/components/framework/smart-copy-icon/index.vue';
const slots = useSlots();
const antdLocale = computed(() => messages[useAppConfigStore().language].antdLocale);

View File

@@ -10,50 +10,66 @@
import { postRequest, getRequest } from '/@/lib/axios';
export const dictApi = {
// 分页查询数据字典KEY - @author 卓大
keyQuery: (param) => {
return postRequest('/support/dict/key/query', param);
// 获取所有字典code @author 1024创新实验室-主任-卓大
getAllDict: () => {
return getRequest('/support/dict/getAllDict');
},
// 查询全部字典key - @author 卓大
queryAllKey: () => {
return getRequest('/support/dict/key/queryAll');
// 获取全部字典数据 @author 1024创新实验室-主任-卓大
getAllDictData: () => {
return getRequest('/support/dict/getAllDictData');
},
/**
* 分页查询数据字典value - @author 卓大
*/
valueQuery: (param) => {
return postRequest('/support/dict/value/query', param);
// 分页查询 @author 1024创新实验室-主任-卓大
queryDict: (param) => {
return postRequest('/support/dict/queryPage', param);
},
// 数据字典KEY-添加- @author 卓大
keyAdd: (param) => {
return postRequest('/support/dict/key/add', param);
// 添加 @author 1024创新实验室-主任-卓大
addDict: (param) => {
return postRequest('/support/dict/add', param);
},
// 分页查询数据字典value - @author 卓大
valueAdd: (param) => {
return postRequest('/support/dict/value/add', param);
// 更新 @author 1024创新实验室-主任-卓大
updateDict: (param) => {
return postRequest('/support/dict/update', param);
},
// 数据字典key-更新- @author 卓大
keyEdit: (param) => {
return postRequest('/support/dict/key/edit', param);
// 字典-删除- @author 卓大
batchDeleteDict: (dictIdList) => {
return postRequest('/support/dict/batchDelete', dictIdList);
},
// 数据字典Value-更新- @author 卓大
valueEdit: (param) => {
return postRequest('/support/dict/value/edit', param);
// 字典 启用 禁用 @author 1024创新实验室-主任-卓大
updateDisabled: (dictId) => {
return getRequest(`/support/dict/updateDisabled/${dictId}`);
},
// 数据字典key-删除- @author 卓大
keyDelete: (keyIdList) => {
return postRequest('/support/dict/key/delete', keyIdList);
// ------------- 查询字典数据 -------------
// 字典数据 分页查询 @author 1024创新实验室-主任-卓大
queryDictData: (dictId) => {
return getRequest(`/support/dict/dictData/queryDictData/${dictId}`);
},
// 数据字典Value-删除- @author 卓大
valueDelete: (valueIdList) => {
return postRequest('/support/dict/value/delete', valueIdList);
// 字典数据 添加 - @author 卓大
addDictData: (param) => {
return postRequest('/support/dict/dictData/add', param);
},
// 缓存刷新- @author 卓大
cacheRefresh: () => {
return getRequest('/support/dict/cache/refresh');
// 字典数据 更新- @author 卓大
updateDictData: (param) => {
return postRequest('/support/dict/dictData/update', param);
},
// 数据字典-值列表- @author 卓大
valueList: (keyCode) => {
return getRequest(`/support/dict/value/list/${keyCode}`);
// 字典数据-删除- @author 卓大
batchDeleteDictData: (dictDataIdList) => {
return postRequest('/support/dict/dictData/batchDelete', dictDataIdList);
},
// 字典数据 启用 禁用 @author 1024创新实验室-主任-卓大
updateDictDataDisabled: (dictDataId) => {
return getRequest(`/support/dict/dictData/updateDisabled/${dictDataId}`);
},
};

View File

@@ -1,26 +0,0 @@
<template>
<div>
<span>{{ dictValueName }}</span>
</div>
</template>
<script setup>
import { computed } from 'vue';
const props = defineProps({
// 数据
options: {
type: Array,
default: null,
},
// 当前的值
value: [Number, String, Array],
});
const dictValueName = computed(() => {
if (props.value === null || typeof props.value === 'undefined' || props.value === '') return '';
const valueCodeList = Array.isArray(props.value) ? props.value.map((item) => item.valueCode) : props.value.split(',');
const valueNameList = props.options.filter((item) => valueCodeList.includes(item.valueCode)).map((item) => item.valueName);
return valueNameList.join('');
});
</script>

View File

@@ -29,7 +29,7 @@
import { ref, watch } from 'vue';
const props = defineProps({
value: Number,
value: Boolean,
width: {
type: Number,
default: 100,

View File

@@ -24,7 +24,7 @@
import { onMounted, ref, nextTick } from 'vue';
import { Modal } from 'ant-design-vue';
import { v4 as uuid } from 'uuid';
import SmartCopyIcon from '/@/components/smart-copy-icon/index.vue';
import SmartCopyIcon from '/@/components/framework/smart-copy-icon/index.vue';
const props = defineProps({
text: {

View File

@@ -25,8 +25,8 @@
import { shallowRef, onBeforeUnmount, watch, ref } from 'vue';
import { FILE_FOLDER_TYPE_ENUM } from '/@/constants/support/file-const';
import { fileApi } from '/@/api/support/file-api';
import '@wangeditor/editor/dist/css/style.css';
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
import '@wangeditor-next/editor/dist/css/style.css';
import { Editor, Toolbar } from '@wangeditor-next/editor-for-vue';
import { smartSentry } from '/@/lib/smart-sentry';
//菜单

View File

@@ -20,8 +20,8 @@
@change="onChange"
:disabled="disabled"
>
<a-select-option v-for="item in dictKeyCodeList" :key="item.keyCode" :value="item.keyCode">
{{ item.keyName }}
<a-select-option v-for="item in dictList" :key="item.dictCode" :value="item.dictCode">
{{ item.dictName }}
</a-select-option>
</a-select>
</div>
@@ -58,10 +58,10 @@
// -------------------------- --------------------------
const dictKeyCodeList = ref([]);
const dictList = ref([]);
async function queryDict() {
let responseModel = await dictApi.queryAllKey();
dictKeyCodeList.value = responseModel.data;
let response = await dictApi.getAllDict();
dictList.value = response.data;
}
onMounted(queryDict);

View File

@@ -0,0 +1,16 @@
<template>
<span>{{ dataLabels }}</span>
</template>
<script setup>
import { computed } from 'vue';
import { useDictStore } from '/@/store/modules/system/dict.js';
const props = defineProps({
dictCode: String,
dataValue: String,
});
const dataLabels = computed(() => {
return useDictStore().getDataLabels(props.dictCode, props.dataValue);
});
</script>

View File

@@ -20,13 +20,8 @@
@change="onChange"
:disabled="disabled"
>
<a-select-option
v-for="item in dictValueList"
:key="item.valueCode"
:value="item.valueCode"
:disabled="disabledOption.includes(item.valueCode)"
>
{{ item.valueName }}
<a-select-option v-for="item in dictDataList" :key="item.dataValue" :value="item.dataValue" :disabled="disabledOption.includes(item.valueCode)">
{{ item.dataLabel }}
</a-select-option>
</a-select>
</div>
@@ -34,10 +29,10 @@
<script setup>
import { onMounted, ref, watch } from 'vue';
import { dictApi } from '/@/api/support/dict-api';
import { useDictStore } from '/@/store/modules/system/dict.js';
const props = defineProps({
keyCode: String,
dictCode: String,
value: [Array, String],
mode: {
type: String,
@@ -74,13 +69,13 @@
// -------------------------- 查询 字典数据 --------------------------
const dictValueList = ref([]);
async function queryDict() {
let res = await dictApi.valueList(props.keyCode);
dictValueList.value = res.data.filter((item) => !props.hiddenOption.includes(item.valueCode));
const dictDataList = ref([]);
function initDictData() {
let list = useDictStore().getDictData(props.dictCode);
dictDataList.value = list.filter((item) => !props.hiddenOption.includes(item.dataValue) && !item.disabledFlag);
}
onMounted(queryDict);
onMounted(initDictData);
// -------------------------- 选中 相关、事件 --------------------------

View File

@@ -47,7 +47,7 @@
width="100%"
v-model:value="modelValue"
:multiple="column.filterOptions.multiple"
:keyCode="column.filterOptions.keyCode"
:dictCode="column.filterOptions.dictCode"
:enumName="column.filterOptions.enumName"
:systemConfigKey="column.filterOptions.systemConfigKey"
:placeholder="column.placeholder"
@@ -78,12 +78,12 @@
});
const components = {
'enum-select': defineAsyncComponent(() => import('/@/components/framework/smart-enum-select/index.vue')),
'dict-select': defineAsyncComponent(() => import('/@/components/support/dict-select/index.vue')),
'employee-select': defineAsyncComponent(() => import('/@/components/system/employee-select/index.vue')),
'enterprise-select': defineAsyncComponent(() => import('/@/components/business/oa/enterprise-select/index.vue')),
'boolean-select': defineAsyncComponent(() => import('/@/components/framework/boolean-select/index.vue')),
'category-tree': defineAsyncComponent(() => import('/@/components/business/category-tree-select/index.vue')),
'enum-select': defineAsyncComponent(() => import('/src/components/framework/smart-enum-select/index.vue')),
'dict-select': defineAsyncComponent(() => import('/src/components/support/dict-select/index.vue')),
'employee-select': defineAsyncComponent(() => import('/src/components/system/employee-select/index.vue')),
'enterprise-select': defineAsyncComponent(() => import('/src/components/business/oa/enterprise-select/index.vue')),
'boolean-select': defineAsyncComponent(() => import('/src/components/framework/boolean-select/index.vue')),
'category-tree': defineAsyncComponent(() => import('/src/components/business/category-tree-select/index.vue')),
};
const componentsKey = Object.keys(components);

View File

@@ -61,16 +61,25 @@
type: Number,
require: true,
},
//如果开启表格scroll需要传递 scroll标识,由于main.js中设置的全局默认的表格高度所以scroll默认值设置为true
scroll: {
type: Boolean,
default: true,
},
});
const emit = defineEmits(['update:modelValue']);
// 原始表格列数据复制一份最原始的columns集合以供后续各个地方使用
let originalColumn = reactive(_.cloneDeep(props.modelValue));
// 存储最新的列数据
let newColumn = reactive(_.cloneDeep(props.modelValue));
// 用于监听表格拖拽后新的列数据
watch(
() => props.modelValue,
(value) => {
originalColumn = value;
newColumn = value;
},
{
deep: true,
@@ -170,13 +179,19 @@
const smartTableColumnModal = ref();
function showModal() {
smartTableColumnModal.value.show(originalColumn, props.tableId);
smartTableColumnModal.value.show(newColumn, props.tableId,props.scroll);
}
// 将弹窗修改的列数据,赋值给原表格 列数组
function updateColumn(changeColumnArray) {
let obj={}
// 如果为空数组代表恢复默认,使用原始表格数据
//合并列
let obj = mergeColumn(_.cloneDeep(originalColumn), changeColumnArray);
if(_.isEmpty(changeColumnArray)){
obj = mergeColumn(_.cloneDeep(originalColumn), changeColumnArray);
}else{
obj = mergeColumn(_.cloneDeep(newColumn), changeColumnArray);
}
const newColumns = obj.newColumns;
emit(
'update:modelValue',
@@ -190,6 +205,7 @@
(e) => {
if (e) {
originalColumn = _.cloneDeep(props.modelValue);
newColumn = _.cloneDeep(props.modelValue);
buildUserTableColumns();
}
},

View File

@@ -93,9 +93,11 @@
// ---------------- 显示 / 隐藏 --------------------
let tableId = null;
const visible = ref(false);
const scroll = ref(true);
//显示
function show(columns, showTableId) {
function show(columns, showTableId,scrollFlag) {
tableId = showTableId;
scroll.value = scrollFlag;
visible.value = true;
getUserTableColumns(tableId, _.cloneDeep(columns));
}
@@ -181,7 +183,12 @@
if (newIndex === oldIndex) {
return;
}
moveTableData(oldIndex, newIndex);
// 如果表格开启scroll会多一个虚拟列所以要减1
if(scroll.value){
moveTableData(oldIndex-1, newIndex-1);
}else{
moveTableData(oldIndex, newIndex);
}
},
});
}

View File

@@ -17,7 +17,7 @@ export const appDefaultConfig = {
// 表格高度
tableYHeight: 300,
//标签页位置
pageTagLocation: 'top',
pageTagLocation: 'center',
// 菜单主题
sideMenuTheme: 'dark',
// 主题颜色索引
@@ -28,7 +28,7 @@ export const appDefaultConfig = {
borderRadius: 6,
// 标签页
pageTagFlag: true,
// 标签页样式: default、 antd、naive
// 标签页样式: default、 antd、chrome
pageTagStyle: 'default',
// 面包屑
breadCrumbFlag: true,

View File

@@ -0,0 +1,21 @@
/**
* 字典key 编码 常量
*
* 该常量来自于 字典管理中的数据,写在该文件目的是为了统一引用,将来好修改
*
* @Author: 1024创新实验室-主任:卓大
* @Date: 2024-09-03 22:09:10
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
*/
export const DICT_SPLIT = ',';
export const DICT_CODE_ENUM = {
GOODS_PLACE: 'GOODS_PLACE',
};
export default {
DICT_CODE_ENUM,
};

View File

@@ -39,154 +39,154 @@
</div>
</template>
<script setup>
import { ref, computed, watch } from 'vue';
import { HOME_PAGE_NAME } from '/@/constants/system/home-const';
import SubMenu from './sub-menu.vue';
import { router } from '/@/router';
import { useRoute } from 'vue-router';
import _ from 'lodash';
import menuEmitter from './top-expand-menu-mitt';
import { useAppConfigStore } from '/@/store/modules/system/app-config';
import { useUserStore } from '/@/store/modules/system/user';
import logoImg from '/@/assets/images/logo/smart-admin-logo.png';
import { ref, computed, watch } from 'vue';
import { HOME_PAGE_NAME } from '/@/constants/system/home-const';
import SubMenu from './sub-menu.vue';
import { router } from '/@/router';
import { useRoute } from 'vue-router';
import _ from 'lodash';
import menuEmitter from './top-expand-menu-mitt';
import { useAppConfigStore } from '/@/store/modules/system/app-config';
import { useUserStore } from '/@/store/modules/system/user';
import logoImg from '/@/assets/images/logo/smart-admin-logo.png';
const websiteName = computed(() => useAppConfigStore().websiteName);
const theme = computed(() => useAppConfigStore().$state.sideMenuTheme);
const websiteName = computed(() => useAppConfigStore().websiteName);
const theme = computed(() => useAppConfigStore().$state.sideMenuTheme);
const props = defineProps({
collapsed: {
type: Boolean,
default: false,
},
});
const props = defineProps({
collapsed: {
type: Boolean,
default: false,
},
});
//菜单宽度
const sideMenuWidth = computed(() => useAppConfigStore().$state.sideMenuWidth);
//菜单宽度
const sideMenuWidth = computed(() => useAppConfigStore().$state.sideMenuWidth);
// 选中的顶级菜单
let topMenu = ref({});
menuEmitter.on('selectTopMenu', onSelectTopMenu);
// 选中的顶级菜单
let topMenu = ref({});
menuEmitter.on('selectTopMenu', onSelectTopMenu);
//动态通知顶部菜单栏侧边栏状态
watch(
topMenu,
(value) => {
let hasSideMenu = value.children && value.children.length > 0;
menuEmitter.emit('sideMenuChange', hasSideMenu);
},
{ immediate: true, deep: true }
);
//动态通知顶部菜单栏侧边栏状态
watch(
topMenu,
(value) => {
let hasSideMenu = value.children && value.children.length > 0;
menuEmitter.emit('sideMenuChange', hasSideMenu);
},
{ immediate: true, deep: true }
);
// 监听选中顶级菜单事件
function onSelectTopMenu(selectedTopMenu) {
topMenu.value = selectedTopMenu;
if (selectedTopMenu.children && selectedTopMenu.children.length > 0) {
openKeys.value = _.map(selectedTopMenu.children, 'menuId').map((e) => e.toString());
} else {
openKeys.value = [];
// 监听选中顶级菜单事件
function onSelectTopMenu(selectedTopMenu) {
topMenu.value = selectedTopMenu;
if (selectedTopMenu.children && selectedTopMenu.children.length > 0) {
openKeys.value = _.map(selectedTopMenu.children, 'menuId').map((e) => e.toString());
} else {
openKeys.value = [];
}
selectedKeys.value = [];
}
selectedKeys.value = [];
}
//展开的菜单
let currentRoute = useRoute();
const selectedKeys = ref([]);
const openKeys = ref([]);
//展开的菜单
let currentRoute = useRoute();
const selectedKeys = ref([]);
const openKeys = ref([]);
function updateSelectKeyAndOpenKey(parentList, currentSelectKey) {
if (!parentList) {
return;
function updateSelectKeyAndOpenKey(parentList, currentSelectKey) {
if (!parentList) {
return;
}
//获取需要展开的menu key集合
openKeys.value = _.map(parentList, 'name');
selectedKeys.value = [currentSelectKey];
}
//获取需要展开的menu key集合
openKeys.value = _.map(parentList, 'name');
selectedKeys.value = [currentSelectKey];
}
watch(
currentRoute,
(value) => {
selectedKeys.value = [value.name];
},
{
immediate: true,
watch(
currentRoute,
(value) => {
selectedKeys.value = [value.name];
},
{
immediate: true,
}
);
// 页面跳转
function turnToPage(route) {
useUserStore().deleteKeepAliveIncludes(route.menuId.toString());
router.push({ name: route.menuId.toString() });
}
);
// 页面跳转
function turnToPage(route) {
useUserStore().deleteKeepAliveIncludes(route.menuId.toString());
router.push({ name: route.menuId.toString() });
}
function onGoHome() {
router.push({ name: HOME_PAGE_NAME });
}
function onGoHome() {
router.push({ name: HOME_PAGE_NAME });
}
defineExpose({ updateSelectKeyAndOpenKey });
defineExpose({ updateSelectKeyAndOpenKey });
const isLight = computed(() => useAppConfigStore().$state.sideMenuTheme === 'light');
const color = computed(() => {
let isLight = useAppConfigStore().$state.sideMenuTheme === 'light';
return {
background: isLight ? '#FFFFFF' : '#001529',
};
});
const isLight = computed(() => useAppConfigStore().$state.sideMenuTheme === 'light');
const color = computed(() => {
let isLight = useAppConfigStore().$state.sideMenuTheme === 'light';
return {
background: isLight ? '#FFFFFF' : '#001529',
};
});
</script>
<style scoped lang="less">
.recursion-container {
height: 100%;
background-color: v-bind('color.background');
}
.min-logo {
height: @header-user-height;
line-height: @header-user-height;
padding: 0px 15px 0px 15px;
// background-color: v-bind('color.background');
width: 80px;
z-index: 21;
display: flex;
justify-content: center;
align-items: center;
.logo-img {
width: 30px;
height: 30px;
}
}
.top-menu {
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
height: @header-user-height;
font-size: 16px;
color: #515a6e;
border-bottom: 1px solid #f3f3f3;
border-right: 1px solid #f3f3f3;
}
.logo {
height: @header-user-height;
line-height: @header-user-height;
padding: 0px 15px 0px 15px;
width: 100%;
z-index: 100;
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
.logo-img {
width: 30px;
height: 30px;
.recursion-container {
height: 100%;
background-color: v-bind('color.background');
}
.title {
font-size: 16px;
font-weight: 600;
.min-logo {
height: @header-user-height;
line-height: @header-user-height;
padding: 0px 15px 0px 15px;
// background-color: v-bind('color.background');
width: 80px;
z-index: 21;
display: flex;
justify-content: center;
align-items: center;
.logo-img {
width: 30px;
height: 30px;
}
}
.top-menu {
overflow: hidden;
word-wrap: break-word;
white-space: nowrap;
color: v-bind('theme === "light" ? "#001529": "#ffffff"');
display: flex;
align-items: center;
justify-content: center;
height: @header-user-height;
font-size: 16px;
color: #515a6e;
border-bottom: 1px solid #f3f3f3;
border-right: 1px solid #f3f3f3;
}
.logo {
height: @header-user-height;
line-height: @header-user-height;
padding: 0px 15px 0px 15px;
width: 100%;
z-index: 100;
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
.logo-img {
width: 30px;
height: 30px;
}
.title {
font-size: 16px;
font-weight: 600;
overflow: hidden;
word-wrap: break-word;
white-space: nowrap;
color: v-bind('theme === "light" ? "#001529": "#ffffff"');
}
}
}
</style>

View File

@@ -40,7 +40,7 @@
};
</script>
<style scoped lang="less">
::v-deep(.ant-menu-item-selected) {
:deep(.ant-menu-item-selected) {
border-right: 3px !important;
}
</style>

View File

@@ -25,65 +25,64 @@
</div>
</template>
<script setup>
import _ from 'lodash';
import { computed, ref } from 'vue';
import { HOME_PAGE_NAME } from '/@/constants/system/home-const';
import { MENU_TYPE_ENUM } from '/@/constants/system/menu-const';
import { router } from '/@/router';
import { useAppConfigStore } from '/@/store/modules/system/app-config';
import { useUserStore } from '/@/store/modules/system/user';
import _ from 'lodash';
import { computed, ref } from 'vue';
import { MENU_TYPE_ENUM } from '/@/constants/system/menu-const';
import { router } from '/@/router';
import { useAppConfigStore } from '/@/store/modules/system/app-config';
import { useUserStore } from '/@/store/modules/system/user';
import menuEmitter from './top-expand-menu-mitt';
import menuEmitter from './top-expand-menu-mitt';
const websiteName = computed(() => useAppConfigStore().websiteName);
const theme = computed(() => useAppConfigStore().$state.sideMenuTheme);
const menuTree = computed(() => useUserStore().getMenuTree || []);
const websiteName = computed(() => useAppConfigStore().websiteName);
const theme = computed(() => useAppConfigStore().$state.sideMenuTheme);
const menuTree = computed(() => useUserStore().getMenuTree || []);
const props = defineProps({
collapsed: {
type: Boolean,
default: false,
},
});
// 展开菜单的顶级目录名字适配,只展示两个字为好
function menuNameAdapter(name) {
return name.substr(0, 2);
}
// 选中的顶级菜单
const selectedKeys = ref([]);
// 选中菜单,页面跳转
function onSelectMenu(menuItem) {
selectedKeys.value = [menuItem.menuId.toString()];
if (menuItem.menuType === MENU_TYPE_ENUM.MENU.value && (_.isEmpty(menuItem.children) || menuItem.children.every((e) => !e.visibleFlag))) {
useUserStore().deleteKeepAliveIncludes(menuItem.menuId.toString());
router.push({ name: menuItem.menuId.toString() });
const props = defineProps({
collapsed: {
type: Boolean,
default: false,
},
});
// 展开菜单的顶级目录名字适配,只展示两个字为好
function menuNameAdapter(name) {
return name.substr(0, 2);
}
menuEmitter.emit('selectTopMenu', menuItem);
}
// 更新选中的菜单
function updateSelectKey(key) {
selectedKeys.value = [key];
let selectMenu = _.find(menuTree.value, { menuId: Number(key) });
if (selectMenu) {
menuEmitter.emit('selectTopMenu', selectMenu);
// 选中的顶级菜单
const selectedKeys = ref([]);
// 选中菜单,页面跳转
function onSelectMenu(menuItem) {
selectedKeys.value = [menuItem.menuId.toString()];
if (menuItem.menuType === MENU_TYPE_ENUM.MENU.value && (_.isEmpty(menuItem.children) || menuItem.children.every((e) => !e.visibleFlag))) {
useUserStore().deleteKeepAliveIncludes(menuItem.menuId.toString());
router.push({ name: menuItem.menuId.toString() });
}
menuEmitter.emit('selectTopMenu', menuItem);
}
}
defineExpose({ updateSelectKey });
// 更新选中的菜单
function updateSelectKey(key) {
selectedKeys.value = [key];
let selectMenu = _.find(menuTree.value, { menuId: Number(key) });
if (selectMenu) {
menuEmitter.emit('selectTopMenu', selectMenu);
}
}
// 动态计算当前导航宽度
let hasSideMenu = ref(false);
menuEmitter.on('sideMenuChange', (data) => {
hasSideMenu.value = data;
});
defineExpose({ updateSelectKey });
const menuInfo = computed(() => {
let width = '100vw';
let right = '-100vw';
if (hasSideMenu.value) {
// 动态计算当前导航宽度
let hasSideMenu = ref(false);
menuEmitter.on('sideMenuChange', (data) => {
hasSideMenu.value = data;
});
const menuInfo = computed(() => {
let width = '100vw';
let right = '-100vw';
if (hasSideMenu.value) {
if (props.collapsed) {
width = 'calc(100vw - 80px)';
right = 'calc(-100vw + 80px)';
@@ -91,60 +90,62 @@ const menuInfo = computed(() => {
width = 'calc(100vw - 180px)';
right = 'calc(-100vw + 180px)';
}
}
return {
width,
right,
};
});
}
return {
width,
right,
};
});
</script>
<style scoped lang="less">
.top-menu {
position: absolute;
transition: all 0.2s, background 0s;
top: 0;
right: v-bind('menuInfo.right');
width: v-bind('menuInfo.width');
flex-shrink: 0;
}
.ant-menu-dark {
background: #1677ff;
color: #fff;
}
.ant-menu-light {
background: #1677ff;
color: #fff;
}
::v-deep(.ant-menu-item-selected) {
background: #0958d9 !important;
color: #fff !important;
}
.top-menu-container {
height: 100%;
}
.logo {
height: @header-user-height;
line-height: @header-user-height;
padding: 0px 15px 0px 15px;
width: 100%;
z-index: 100;
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
.logo-img {
width: 30px;
height: 30px;
.top-menu {
position: absolute;
transition:
all 0.2s,
background 0s;
top: 0;
right: v-bind('menuInfo.right');
width: v-bind('menuInfo.width');
flex-shrink: 0;
}
.title {
font-size: 16px;
font-weight: 600;
overflow: hidden;
word-wrap: break-word;
white-space: nowrap;
color: v-bind('theme === "light" ? "#001529": "#ffffff"');
.ant-menu-dark {
background: #1677ff;
color: #fff;
}
.ant-menu-light {
background: #1677ff;
color: #fff;
}
:deep(.ant-menu-item-selected){
background: #0958d9 !important;
color: #fff !important;
}
.top-menu-container {
height: 100%;
}
.logo {
height: @header-user-height;
line-height: @header-user-height;
padding: 0px 15px 0px 15px;
width: 100%;
z-index: 100;
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
.logo-img {
width: 30px;
height: 30px;
}
.title {
font-size: 16px;
font-weight: 600;
overflow: hidden;
word-wrap: break-word;
white-space: nowrap;
color: v-bind('theme === "light" ? "#001529": "#ffffff"');
}
}
}
</style>

View File

@@ -21,18 +21,20 @@ import constantsInfo from '/@/constants/index';
import { privilegeDirective } from '/@/directives/privilege';
import i18n from '/@/i18n/index';
import privilegePlugin from '/@/plugins/privilege-plugin';
import dictPlugin from '/@/plugins/dict-plugin';
import smartEnumPlugin from '/@/plugins/smart-enums-plugin';
import { buildRoutes, router } from '/@/router';
import { store } from '/@/store';
import { useUserStore } from '/@/store/modules/system/user';
import 'ant-design-vue/dist/reset.css';
import 'vue3-tabs-chrome/dist/vue3-tabs-chrome.css';
import '/@/theme/index.less';
import { localRead } from '/@/utils/local-util.js';
import LocalStorageKeyConst from '/@/constants/local-storage-key-const.js';
import { Table } from 'ant-design-vue';
import { useAppConfigStore } from '/@/store/modules/system/app-config';
import '/@/utils/ployfill';
import { useDictStore } from '/@/store/modules/system/dict.js';
import { dictApi } from '/@/api/support/dict-api.js';
/*
* -------------------- ※ 着重 解释说明下main.js的初始化逻辑 begin ※ --------------------
@@ -54,10 +56,13 @@ async function getLoginInfo() {
try {
//获取登录用户信息
const res = await loginApi.getLoginInfo();
const dictRes = await dictApi.getAllDictData();
//构建系统的路由
let menuRouterList = res.data.menuList.filter((e) => e.path || e.frameUrl);
buildRoutes(menuRouterList);
initVue();
// 初始化数据字典
useDictStore().initData(dictRes.data);
//更新用户信息到pinia
useUserStore().setUserLoginInfo(res.data);
} catch (e) {
@@ -69,7 +74,15 @@ async function getLoginInfo() {
async function initVue() {
let vueApp = createApp(App);
let app = vueApp.use(router).use(store).use(i18n).use(Antd).use(smartEnumPlugin, constantsInfo).use(privilegePlugin).use(JsonViewer);
let app = vueApp
.use(router)
.use(store)
.use(i18n)
.use(Antd)
.use(smartEnumPlugin, constantsInfo)
.use(privilegePlugin)
.use(dictPlugin)
.use(JsonViewer);
//注入权限
app.directive('privilege', {
mounted(el, binding) {

View File

@@ -0,0 +1,31 @@
/*
* 字典插件
* 此插件为 1024创新实验室 自创的插件
*
* @Author: 1024创新实验室-主任:卓大
* @Date: 2024-09-06 20:51:03
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
*/
import { useDictStore } from '/@/store/modules/system/dict.js';
export default {
install: (app) => {
const dictPlugin = {};
/**
* 根据枚举值获取描述
* @param {*} dictCode 字典编码
* @param {*} value 值
* @returns
*/
dictPlugin.getDataLabels = function (dictCode, value) {
return useDictStore().getDataLabels(dictCode, value);
};
app.config.globalProperties.$dictPlugin = dictPlugin;
app.provide('dictPlugin', dictPlugin);
},
};

View File

@@ -8,6 +8,7 @@
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
*/
import { useUserStore } from '/@/store/modules/system/user';
import _ from 'lodash';
const privilege = (value) => {
// 超级管理员

View File

@@ -1,53 +1,57 @@
import { defineStore } from 'pinia';
import { dictApi } from '/@/api/support/dict-api';
import { smartSentry } from '/@/lib/smart-sentry';
import { DICT_SPLIT } from '/@/constants/support/dict-const.js';
import _ from 'lodash';
export const useDictStore = defineStore({
id: 'dict',
state: () => ({
dict: new Array(),
// 字典集合
dictMap: new Map(),
}),
actions: {
// 获取字典
getDict(keyCode) {
if (keyCode == null && keyCode == '') {
return null;
// 获取字典数据
getDictData(dictCode) {
if (!dictCode) {
return [];
}
try {
for (let i = 0; i < this.dict.length; i++) {
if (this.dict[i].keyCode == keyCode) {
return this.dict[i].value;
}
let dictDataList = this.dictMap.get(dictCode);
return dictDataList ? dictDataList : [];
},
// 获取字典的值名称
getDataLabels(dictCode, dataValue) {
if (!dataValue) {
return '';
}
let dict = this.getDictData(dictCode);
if (dict.length === 0) {
return '';
}
let valueArray = dataValue.split(DICT_SPLIT);
let result = [];
for (let item of valueArray) {
let target = _.find(dict, { dataValue: item });
if (target) {
result.push(target.dataLabel);
}
} catch (e) {
return null;
}
return result.join(DICT_SPLIT);
},
// 设置字典
setDict(keyCode, value) {
if (keyCode !== null && keyCode !== '') {
this.dict.push({
key: keyCode,
value: value,
});
}
},
// 删除字典
removeDict(keyCode) {
let flag = false;
try {
for (let i = 0; i < this.dict.length; i++) {
if (this.dict[i].keyCode == keyCode) {
this.dict.splice(i, 1);
return true;
}
// 初始化字典
initData(dictDataList){
this.dictMap.clear();
for (let data of dictDataList) {
let dataArray = this.dictMap.get(data.dictCode);
if (!dataArray) {
dataArray = [];
this.dictMap.set(data.dictCode, dataArray);
}
} catch (e) {
flag = false;
dataArray.push(data);
}
return false;
},
// 清空字典
cleanDict() {
this.dict = new Array();
},
},
});

View File

@@ -124,6 +124,10 @@ export const useUserStore = defineStore({
localRemove(localKey.USER_TOKEN);
localRemove(localKey.USER_POINTS);
localRemove(localKey.USER_TAG_NAV);
localRemove(localKey.APP_CONFIG);
localRemove(localKey.HOME_QUICK_ENTRY);
localRemove(localKey.NOTICE_READ);
localRemove(localKey.TO_BE_DONE);
},
// 查询未读消息数量
async queryUnreadMessageCount() {
@@ -179,9 +183,11 @@ export const useUserStore = defineStore({
// 获取待办工作数
this.queryToBeDoneList();
},
setToken(token) {
this.token = token;
},
//设置标签页
setTagNav(route, from) {
if (_.isNull(this.tagNav)) {
@@ -206,7 +212,7 @@ export const useUserStore = defineStore({
// @ts-ignore
menuTitle: route.meta.title,
menuQuery: route.query,
menuIcon:route.meta?.icon,
menuIcon:route.meta?.icon,
// @ts-ignore
fromMenuName: from.name,
fromMenuQuery: from.query,

View File

@@ -1,11 +1,11 @@
/*
/*
* 默认样式的修改
*
* @Author: 1024创新实验室-主任:卓大
* @Date: 2022-09-12 14:41:59
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
*
* @Author: 1024创新实验室-主任:卓大
* @Date: 2022-09-12 14:41:59
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
*/
@import 'ant-design-vue/dist/reset.css';
@@ -63,6 +63,11 @@ body {
height: 100%;
}
/********************************** 富文本HTML样式 **********************************/
.ant-modal-root div[aria-hidden="true"] {
display: none !important;
}
/********************************** 富文本HTML样式 **********************************/
.html-content {
/* table 样式 */

View File

@@ -1,22 +0,0 @@
import { useDictStore } from '/@/store/modules/system/dict';
import { dictApi } from '/@/api/support/dict-api';
/**
* 获取字典数据
*/
export function useDict(...args) {
let res = {};
args.forEach(async (keyCode, index) => {
res[keyCode] = [];
const dicts = useDictStore().getDict(keyCode);
if (dicts) {
res[keyCode] = dicts;
} else {
let result = await dictApi.valueList(keyCode);
res[keyCode] = result.data;
useDictStore().setDict(keyCode, res[keyCode]);
}
});
return res;
}

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="dictList['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>
@@ -199,14 +199,14 @@
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 { 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 _ 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 dictList = useDict('GOODS_PLACE', 'GOODS_PLACE');
// ---------------------------- 表格列 ----------------------------
const columns = ref([
@@ -235,6 +235,7 @@
title: '商品状态',
dataIndex: 'goodsStatus',
resizable: true,
sorter: true,
filterOptions: {
type: 'enum-select',
enumName: 'GOODS_STATUS_ENUM',
@@ -247,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

@@ -56,7 +56,7 @@
row-key="employeeId"
bordered
>
<template #bodyCell="{ text, record, column }">
<template #bodyCell="{ text, record, index, column }">
<template v-if="column.dataIndex === 'administratorFlag'">
<a-tag color="error" v-if="text">超管</a-tag>
</template>

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');