😎1、修复在线用户redis模式报错 2、增加字典组件select模式过滤 3、升级依赖
This commit is contained in:
parent
72e699bbc0
commit
b2be0d3160
@ -28,9 +28,9 @@
|
|||||||
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
|
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
|
||||||
<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.2" Aliases="BouncyCastleV2" />
|
<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.2" Aliases="BouncyCastleV2" />
|
||||||
<PackageReference Include="Elastic.Clients.Elasticsearch" Version="9.1.4" />
|
<PackageReference Include="Elastic.Clients.Elasticsearch" Version="9.1.4" />
|
||||||
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.7.109" />
|
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.7.110" />
|
||||||
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.9.7.109" />
|
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.9.7.110" />
|
||||||
<PackageReference Include="Furion.Pure" Version="4.9.7.109" />
|
<PackageReference Include="Furion.Pure" Version="4.9.7.110" />
|
||||||
<PackageReference Include="Hardware.Info" Version="101.0.1.1" />
|
<PackageReference Include="Hardware.Info" Version="101.0.1.1" />
|
||||||
<PackageReference Include="Hashids.net" Version="1.7.0" />
|
<PackageReference Include="Hashids.net" Version="1.7.0" />
|
||||||
<PackageReference Include="IPTools.China" Version="1.6.0" />
|
<PackageReference Include="IPTools.China" Version="1.6.0" />
|
||||||
|
|||||||
@ -66,7 +66,7 @@ public class OnlineUserHub : Hub<IOnlineUserHub>
|
|||||||
await _onlineUserHubContext.Groups.AddToGroupAsync(Context.ConnectionId, groupName);
|
await _onlineUserHubContext.Groups.AddToGroupAsync(Context.ConnectionId, groupName);
|
||||||
|
|
||||||
// 更新在线用户列表
|
// 更新在线用户列表
|
||||||
var userList = SysCacheService.HashGetAll<OnlineUser>(CacheConst.KeyUserOnline).Where(u => u.Value.TenantId == tenantId).Select(u => u.Value).ToList();
|
var userList = SysCacheService.HashGetAll<OnlineUser>(CacheConst.KeyUserOnline).Values.Where(u => u.TenantId == tenantId).ToList();
|
||||||
await _onlineUserHubContext.Clients.Groups(groupName).OnlineUserList(new OnlineUserList
|
await _onlineUserHubContext.Clients.Groups(groupName).OnlineUserList(new OnlineUserList
|
||||||
{
|
{
|
||||||
RealName = user.RealName,
|
RealName = user.RealName,
|
||||||
@ -90,7 +90,7 @@ public class OnlineUserHub : Hub<IOnlineUserHub>
|
|||||||
SysCacheService.HashDel<OnlineUser>(CacheConst.KeyUserOnline, Context.ConnectionId);
|
SysCacheService.HashDel<OnlineUser>(CacheConst.KeyUserOnline, Context.ConnectionId);
|
||||||
|
|
||||||
// 更新在线用户列表
|
// 更新在线用户列表
|
||||||
var userList = SysCacheService.HashGetAll<OnlineUser>(CacheConst.KeyUserOnline).Where(u => u.Value.TenantId == user.TenantId).Select(u => u.Value).ToList();
|
var userList = SysCacheService.HashGetAll<OnlineUser>(CacheConst.KeyUserOnline).Values.Where(u => u.TenantId == user.TenantId).ToList();
|
||||||
await _onlineUserHubContext.Clients.Groups($"{GROUP_ONLINE}{user.TenantId}").OnlineUserList(new OnlineUserList
|
await _onlineUserHubContext.Clients.Groups($"{GROUP_ONLINE}{user.TenantId}").OnlineUserList(new OnlineUserList
|
||||||
{
|
{
|
||||||
RealName = user.RealName,
|
RealName = user.RealName,
|
||||||
|
|||||||
@ -47,11 +47,11 @@ public static class SqlSugarSetup
|
|||||||
// 初始化SqlSugar
|
// 初始化SqlSugar
|
||||||
SqlSugarScope sqlSugar = new(dbOptions.ConnectionConfigs.Adapt<List<ConnectionConfig>>(), db =>
|
SqlSugarScope sqlSugar = new(dbOptions.ConnectionConfigs.Adapt<List<ConnectionConfig>>(), db =>
|
||||||
{
|
{
|
||||||
dbOptions.ConnectionConfigs.ForEach(config =>
|
dbOptions.ConnectionConfigs.ForEach(dbConfig =>
|
||||||
{
|
{
|
||||||
var dbProvider = db.GetConnectionScope(config.ConfigId);
|
var dbProvider = db.GetConnectionScope(dbConfig.ConfigId);
|
||||||
SetDbAop(dbProvider, dbOptions.EnableConsoleSql);
|
SetDbAop(dbProvider, dbOptions.EnableConsoleSql);
|
||||||
SetDbDiffLog(dbProvider, config);
|
SetDbDiffLog(dbProvider, dbConfig);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
ITenant = sqlSugar;
|
ITenant = sqlSugar;
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
"name": "admin.net.pro",
|
"name": "admin.net.pro",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "2.4.33",
|
"version": "2.4.33",
|
||||||
"lastBuildTime": "2025.08.18",
|
"lastBuildTime": "2025.08.19",
|
||||||
"description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架",
|
"description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架",
|
||||||
"author": "zuohuaijun",
|
"author": "zuohuaijun",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -25,7 +25,7 @@
|
|||||||
"@vue-office/docx": "^1.6.3",
|
"@vue-office/docx": "^1.6.3",
|
||||||
"@vue-office/excel": "^1.7.14",
|
"@vue-office/excel": "^1.7.14",
|
||||||
"@vue-office/pdf": "^2.0.10",
|
"@vue-office/pdf": "^2.0.10",
|
||||||
"@vueuse/core": "^13.6.0",
|
"@vueuse/core": "^13.7.0",
|
||||||
"@vxe-ui/plugin-export-xlsx": "^4.3.0",
|
"@vxe-ui/plugin-export-xlsx": "^4.3.0",
|
||||||
"@vxe-ui/plugin-render-element": "^4.1.0",
|
"@vxe-ui/plugin-render-element": "^4.1.0",
|
||||||
"@wangeditor/editor": "^5.1.23",
|
"@wangeditor/editor": "^5.1.23",
|
||||||
@ -80,8 +80,8 @@
|
|||||||
"vue-router": "^4.5.1",
|
"vue-router": "^4.5.1",
|
||||||
"vue-signature-pad": "^3.0.2",
|
"vue-signature-pad": "^3.0.2",
|
||||||
"vue3-tree-org": "^4.2.2",
|
"vue3-tree-org": "^4.2.2",
|
||||||
"vxe-pc-ui": "^4.8.20",
|
"vxe-pc-ui": "^4.8.22",
|
||||||
"vxe-table": "^4.15.9",
|
"vxe-table": "^4.15.10",
|
||||||
"xe-utils": "^3.7.8",
|
"xe-utils": "^3.7.8",
|
||||||
"xlsx-js-style": "^1.2.0"
|
"xlsx-js-style": "^1.2.0"
|
||||||
},
|
},
|
||||||
@ -92,25 +92,25 @@
|
|||||||
"@types/node": "^22.17.2",
|
"@types/node": "^22.17.2",
|
||||||
"@types/nprogress": "^0.2.3",
|
"@types/nprogress": "^0.2.3",
|
||||||
"@types/sortablejs": "^1.15.8",
|
"@types/sortablejs": "^1.15.8",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.39.1",
|
"@typescript-eslint/eslint-plugin": "^8.40.0",
|
||||||
"@typescript-eslint/parser": "^8.39.1",
|
"@typescript-eslint/parser": "^8.40.0",
|
||||||
"@vitejs/plugin-vue": "^6.0.1",
|
"@vitejs/plugin-vue": "^6.0.1",
|
||||||
"@vitejs/plugin-vue-jsx": "^5.0.1",
|
"@vitejs/plugin-vue-jsx": "^5.0.1",
|
||||||
"@vue/compiler-sfc": "^3.5.18",
|
"@vue/compiler-sfc": "^3.5.18",
|
||||||
"cli-progress": "^3.12.0",
|
"cli-progress": "^3.12.0",
|
||||||
"code-inspector-plugin": "^1.2.1",
|
"code-inspector-plugin": "^1.2.2",
|
||||||
"colors": "^1.4.0",
|
"colors": "^1.4.0",
|
||||||
"dotenv": "^17.2.1",
|
"dotenv": "^17.2.1",
|
||||||
"eslint": "^9.33.0",
|
"eslint": "^9.33.0",
|
||||||
"eslint-plugin-vue": "^10.4.0",
|
"eslint-plugin-vue": "^10.4.0",
|
||||||
"globals": "^16.3.0",
|
"globals": "^16.3.0",
|
||||||
"less": "^4.4.0",
|
"less": "^4.4.1",
|
||||||
"prettier": "^3.6.2",
|
"prettier": "^3.6.2",
|
||||||
"rollup-plugin-visualizer": "^6.0.3",
|
"rollup-plugin-visualizer": "^6.0.3",
|
||||||
"sass": "^1.90.0",
|
"sass": "^1.90.0",
|
||||||
"terser": "^5.43.1",
|
"terser": "^5.43.1",
|
||||||
"typescript": "^5.9.2",
|
"typescript": "^5.9.2",
|
||||||
"vite": "^7.1.2",
|
"vite": "^7.1.3",
|
||||||
"vite-auto-i18n-plugin": "^1.1.7",
|
"vite-auto-i18n-plugin": "^1.1.7",
|
||||||
"vite-plugin-cdn-import": "^1.0.1",
|
"vite-plugin-cdn-import": "^1.0.1",
|
||||||
"vite-plugin-compression2": "^2.2.0",
|
"vite-plugin-compression2": "^2.2.0",
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
* @constant
|
* @constant
|
||||||
*/
|
*/
|
||||||
const RENDER_TYPES = ['tag', 'select', 'radio', 'checkbox', 'radio-button'] as const;
|
const RENDER_TYPES = ['tag', 'select', 'radio', 'checkbox', 'radio-button'] as const;
|
||||||
type RenderType = typeof RENDER_TYPES[number];
|
type RenderType = (typeof RENDER_TYPES)[number];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支持的标签类型常量
|
* 支持的标签类型常量
|
||||||
@ -24,7 +24,7 @@ type RenderType = typeof RENDER_TYPES[number];
|
|||||||
* @constant
|
* @constant
|
||||||
*/
|
*/
|
||||||
const TAG_TYPES = ['success', 'warning', 'info', 'primary', 'danger'] as const;
|
const TAG_TYPES = ['success', 'warning', 'info', 'primary', 'danger'] as const;
|
||||||
type TagType = typeof TAG_TYPES[number];
|
type TagType = (typeof TAG_TYPES)[number];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字典项数据结构
|
* 字典项数据结构
|
||||||
@ -218,9 +218,7 @@ const props = defineProps({
|
|||||||
* @returns {DictItem[]} - 过滤并格式化后的字典数据
|
* @returns {DictItem[]} - 过滤并格式化后的字典数据
|
||||||
*/
|
*/
|
||||||
const formattedDictData = computed(() => {
|
const formattedDictData = computed(() => {
|
||||||
return state.dictData
|
return state.dictData.filter(props.onItemFilter).map((item) => ({
|
||||||
.filter(props.onItemFilter)
|
|
||||||
.map(item => ({
|
|
||||||
...item,
|
...item,
|
||||||
label: item[props.propLabel],
|
label: item[props.propLabel],
|
||||||
value: item[props.propValue],
|
value: item[props.propValue],
|
||||||
@ -238,12 +236,10 @@ const currentDictItems = computed(() => {
|
|||||||
if (Array.isArray(state.value)) {
|
if (Array.isArray(state.value)) {
|
||||||
// 确保回显时也去重
|
// 确保回显时也去重
|
||||||
const uniqueValues = [...new Set(state.value)];
|
const uniqueValues = [...new Set(state.value)];
|
||||||
return formattedDictData.value.filter(item =>
|
return formattedDictData.value.filter((item) => uniqueValues.includes(item.value));
|
||||||
uniqueValues.includes(item.value)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return formattedDictData.value.find(item => item.value == state.value) || null;
|
return formattedDictData.value.find((item) => item.value == state.value) || null;
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -260,9 +256,7 @@ const getDataList = (): DictItem[] => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const source = props.isConst ? userStore.constList : userStore.dictList;
|
const source = props.isConst ? userStore.constList : userStore.dictList;
|
||||||
const data = props.isConst
|
const data = props.isConst ? (source?.find((x: any) => x.code === props.code)?.data?.result ?? []) : (source[props.code] ?? []);
|
||||||
? source?.find((x: any) => x.code === props.code)?.data?.result ?? []
|
|
||||||
: source[props.code] ?? [];
|
|
||||||
|
|
||||||
return data.map((item: any) => ({
|
return data.map((item: any) => ({
|
||||||
...item,
|
...item,
|
||||||
@ -282,7 +276,7 @@ const getDataList = (): DictItem[] => {
|
|||||||
*/
|
*/
|
||||||
const processNumericValues = (value: any) => {
|
const processNumericValues = (value: any) => {
|
||||||
if (typeof value === 'number' || (Array.isArray(value) && typeof value[0] === 'number')) {
|
if (typeof value === 'number' || (Array.isArray(value) && typeof value[0] === 'number')) {
|
||||||
state.dictData.forEach(item => {
|
state.dictData.forEach((item) => {
|
||||||
if (!isEmpty(item.value)) {
|
if (!isEmpty(item.value)) {
|
||||||
item.value = Number(item.value);
|
item.value = Number(item.value);
|
||||||
}
|
}
|
||||||
@ -324,11 +318,14 @@ const parseMultipleValue = (value: any): any => {
|
|||||||
// 处理逗号分隔格式
|
// 处理逗号分隔格式
|
||||||
if (props.multipleModel === MultipleModel.Comma && trimmedValue.includes(',')) {
|
if (props.multipleModel === MultipleModel.Comma && trimmedValue.includes(',')) {
|
||||||
// 去重处理
|
// 去重处理
|
||||||
return [...new Set(
|
return [
|
||||||
trimmedValue.split(',')
|
...new Set(
|
||||||
.map(item => item.trim())
|
trimmedValue
|
||||||
|
.split(',')
|
||||||
|
.map((item) => item.trim())
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
)];
|
),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理单个值情况
|
// 处理单个值情况
|
||||||
@ -353,7 +350,7 @@ const updateValue = (newValue: any) => {
|
|||||||
// 先对值进行去重处理
|
// 先对值进行去重处理
|
||||||
let processedValue = newValue;
|
let processedValue = newValue;
|
||||||
if (Array.isArray(newValue)) {
|
if (Array.isArray(newValue)) {
|
||||||
processedValue = [...new Set(newValue.filter(v => v !== null && v !== undefined && v !== ''))];
|
processedValue = [...new Set(newValue.filter((v) => v !== null && v !== undefined && v !== ''))];
|
||||||
}
|
}
|
||||||
|
|
||||||
let emitValue = processedValue;
|
let emitValue = processedValue;
|
||||||
@ -377,7 +374,7 @@ const updateValue = (newValue: any) => {
|
|||||||
* @returns {TagType} - 合法的标签类型
|
* @returns {TagType} - 合法的标签类型
|
||||||
*/
|
*/
|
||||||
const ensureTagType = (item: DictItem): TagType => {
|
const ensureTagType = (item: DictItem): TagType => {
|
||||||
return TAG_TYPES.includes(item.tagType as TagType) ? item.tagType as TagType : 'primary';
|
return TAG_TYPES.includes(item.tagType as TagType) ? (item.tagType as TagType) : 'primary';
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -416,9 +413,12 @@ const state = reactive({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 监听数据变化
|
// 监听数据变化
|
||||||
watch(() => props.modelValue, (newValue) => {
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(newValue) => {
|
||||||
state.value = parseMultipleValue(newValue);
|
state.value = parseMultipleValue(newValue);
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
watch(() => [userStore.dictList, userStore.constList], initData, { immediate: true });
|
watch(() => [userStore.dictList, userStore.constList], initData, { immediate: true });
|
||||||
</script>
|
</script>
|
||||||
@ -440,7 +440,7 @@ watch(() => [userStore.dictList, userStore.constList], initData, { immediate: tr
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 渲染选择器 -->
|
<!-- 渲染选择器 -->
|
||||||
<el-select v-else-if="props.renderAs === 'select'" v-model="state.value" v-bind="$attrs" :multiple="props.multiple" @change="updateValue" clearable>
|
<el-select v-else-if="props.renderAs === 'select'" v-model="state.value" v-bind="$attrs" :multiple="props.multiple" @change="updateValue" filterable clearable>
|
||||||
<el-option v-for="(item, index) in formattedDictData" :key="index" :label="getDisplayText(item)" :value="item.value" />
|
<el-option v-for="(item, index) in formattedDictData" :key="index" :label="getDisplayText(item)" :value="item.value" />
|
||||||
</el-select>
|
</el-select>
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user