fix: 完善IM用户状态与分组展示

This commit is contained in:
richjohnrambo
2026-09-08 22:16:51 +08:00
parent 7d54bf785a
commit 99307f1c98
4 changed files with 76 additions and 19 deletions
+10 -3
View File
@@ -12,6 +12,7 @@ import (
func init() { func init() {
dict.RegisterEnums("ImUserStateOptions", "IM用户状态选项", ImUserStateOptions) dict.RegisterEnums("ImUserStateOptions", "IM用户状态选项", ImUserStateOptions)
dict.RegisterEnums("ImUserListStateOptions", "IM用户列表状态选项", ImUserListStateOptions)
dict.RegisterEnums("ImUserRegisterTypeOptions", "IM用户注册方式选项", ImUserRegisterTypeOptions) dict.RegisterEnums("ImUserRegisterTypeOptions", "IM用户注册方式选项", ImUserRegisterTypeOptions)
} }
@@ -35,8 +36,14 @@ const (
) )
var ImUserStateOptions = []*model.Option{ var ImUserStateOptions = []*model.Option{
dict.GenSuccessOption(ImUserStateOk, "正常"), dict.GenSuccessOption(ImUserStateOk, "启用"),
dict.GenErrorOption(ImUserStateSuspended, "已停用"), dict.GenErrorOption(ImUserStateSuspended, "封禁"),
dict.GenDefaultOption(ImUserStateDeleted, "已删除"), dict.GenDefaultOption(ImUserStateDeleted, "已注销"),
dict.GenWarningOption(ImUserStateUndefined, "未定义"), dict.GenWarningOption(ImUserStateUndefined, "未定义"),
} }
var ImUserListStateOptions = []*model.Option{
dict.GenSuccessOption(ImUserStateOk, "启用"),
dict.GenErrorOption(ImUserStateSuspended, "封禁"),
dict.GenDefaultOption(ImUserStateDeleted, "已注销"),
}
@@ -0,0 +1,46 @@
-- Initialize assignable policy groups for every active IM tenant.
-- Safe to rerun: tenant_id + group_code is unique.
SET NAMES utf8mb4;
USE `hotgo`;
INSERT INTO `im_user_policy_groups`
(`tenant_id`, `group_code`, `group_name`, `priority`, `status`, `policy_json`, `ip_whitelist`, `ip_blacklist`, `version`, `remark`, `created_by`, `updated_by`)
SELECT
`id`, 'default_standard', '默认用户组', 100, 1,
JSON_OBJECT(
'allow_add_friend', TRUE, 'allow_join_group', TRUE, 'max_friend_count', 5000,
'allow_upload_file', TRUE, 'direct_add_friend', FALSE, 'allow_create_group', TRUE,
'allow_group_message', TRUE, 'allow_private_message', TRUE,
'allow_qrcode_add_friend', TRUE, 'allow_group_member_profile', TRUE,
'hide_profile_when_friend_disabled', TRUE
), JSON_ARRAY(), JSON_ARRAY(), 1, '系统初始化:默认用户权限', 0, 0
FROM `im_tenant` WHERE `state` = 1
ON DUPLICATE KEY UPDATE `group_name` = VALUES(`group_name`), `status` = 1, `updated_at` = CURRENT_TIMESTAMP(3);
INSERT INTO `im_user_policy_groups`
(`tenant_id`, `group_code`, `group_name`, `priority`, `status`, `policy_json`, `ip_whitelist`, `ip_blacklist`, `version`, `remark`, `created_by`, `updated_by`)
SELECT
`id`, 'default_trusted', '可信用户组', 90, 1,
JSON_OBJECT(
'allow_add_friend', TRUE, 'allow_join_group', TRUE, 'max_friend_count', 10000,
'allow_upload_file', TRUE, 'direct_add_friend', TRUE, 'allow_create_group', TRUE,
'allow_group_message', TRUE, 'allow_private_message', TRUE,
'allow_qrcode_add_friend', TRUE, 'allow_group_member_profile', TRUE,
'hide_profile_when_friend_disabled', TRUE
), JSON_ARRAY(), JSON_ARRAY(), 1, '系统初始化:可信用户权限', 0, 0
FROM `im_tenant` WHERE `state` = 1
ON DUPLICATE KEY UPDATE `group_name` = VALUES(`group_name`), `status` = 1, `updated_at` = CURRENT_TIMESTAMP(3);
INSERT INTO `im_user_policy_groups`
(`tenant_id`, `group_code`, `group_name`, `priority`, `status`, `policy_json`, `ip_whitelist`, `ip_blacklist`, `version`, `remark`, `created_by`, `updated_by`)
SELECT
`id`, 'default_guest', '访客用户组', 60, 1,
JSON_OBJECT(
'allow_add_friend', FALSE, 'allow_join_group', TRUE, 'max_friend_count', 0,
'allow_upload_file', FALSE, 'direct_add_friend', FALSE, 'allow_create_group', FALSE,
'allow_group_message', TRUE, 'allow_private_message', TRUE,
'allow_qrcode_add_friend', FALSE, 'allow_group_member_profile', FALSE,
'hide_profile_when_friend_disabled', TRUE
), JSON_ARRAY(), JSON_ARRAY(), 1, '系统初始化:访客用户权限', 0, 0
FROM `im_tenant` WHERE `state` = 1
ON DUPLICATE KEY UPDATE `group_name` = VALUES(`group_name`), `status` = 1, `updated_at` = CURRENT_TIMESTAMP(3);
+7 -4
View File
@@ -330,7 +330,7 @@
type: record.state === 0 ? 'error' : 'default', type: record.state === 0 ? 'error' : 'default',
onClick: handleBanToggle.bind(null, record), onClick: handleBanToggle.bind(null, record),
auth: [record.state === 0 ? '/imUser/ban' : '/imUser/unban'], auth: [record.state === 0 ? '/imUser/ban' : '/imUser/unban'],
ifShow: record.state !== 20, ifShow: record.state === 0 || record.state === 10,
}, },
{ {
label: '强制下线', label: '强制下线',
@@ -429,8 +429,9 @@
} }
} }
function openAdjustGroup(record: State) { async function openAdjustGroup(record: State) {
operationUser.value = record; operationUser.value = record;
await loadPolicyGroupOptions(record.tenantId);
adjustGroupId.value = record.policyGroupId || null; adjustGroupId.value = record.policyGroupId || null;
groupVisible.value = true; groupVisible.value = true;
} }
@@ -567,15 +568,17 @@
onMounted(async () => { onMounted(async () => {
loadOptions(); loadOptions();
let tenantId = currentTenantId();
if (isPlatformAdmin.value) { if (isPlatformAdmin.value) {
await loadTenantOptions(); await loadTenantOptions();
if (tenantOptions.value.length > 0) { if (tenantOptions.value.length > 0) {
await setFieldsValue({ tenantId: tenantOptions.value[0].value }); tenantId = Number(tenantOptions.value[0].value);
await setFieldsValue({ tenantId });
} else { } else {
message.warning('暂无可用租户'); message.warning('暂无可用租户');
} }
} }
await loadPolicyGroupOptions(currentTenantId()); await loadPolicyGroupOptions(tenantId);
reloadTable(); reloadTable();
}); });
</script> </script>
+13 -12
View File
@@ -1,10 +1,11 @@
import { computed, h, ref } from 'vue'; import { computed, h, ref } from 'vue';
import { NAvatar, NImage, NTag } from 'naive-ui'; import { NImage, NTag } from 'naive-ui';
import { cloneDeep } from 'lodash-es'; import { cloneDeep } from 'lodash-es';
import { FormSchema } from '@/components/Form'; import { FormSchema } from '@/components/Form';
import { useDictStore } from '@/store/modules/dict'; import { useDictStore } from '@/store/modules/dict';
import { List as TenantList } from '@/api/imTenant'; import { List as TenantList } from '@/api/imTenant';
import { List as PolicyGroupList } from '@/api/imUserPolicyGroup'; import { List as PolicyGroupList } from '@/api/imUserPolicyGroup';
import defaultAvatar from '@/assets/images/schoolboy.png';
const dict = useDictStore(); const dict = useDictStore();
@@ -110,7 +111,7 @@ export const schemas = ref<FormSchema[]>([
label: '状态', label: '状态',
componentProps: { componentProps: {
clearable: true, clearable: true,
options: dict.getOption('ImUserStateOptions'), options: dict.getOption('ImUserListStateOptions'),
placeholder: '全部', placeholder: '全部',
}, },
}, },
@@ -139,14 +140,14 @@ export const columns = [
align: 'left', align: 'left',
width: 80, width: 80,
render(row: State) { render(row: State) {
if (row.avatar) { return h(NImage, {
return h(NImage, { width: 40, height: 40, src: row.avatar, objectFit: 'cover' }); width: 40,
} height: 40,
return h( src: row.avatar || defaultAvatar,
NAvatar, fallbackSrc: defaultAvatar,
{ size: 40 }, objectFit: 'cover',
{ default: () => (row.nickname || row.username || '?').slice(0, 1) } previewDisabled: !row.avatar,
); });
}, },
}, },
{ {
@@ -243,7 +244,7 @@ export const deviceColumns = [
// 加载字典数据选项 // 加载字典数据选项
export function loadOptions() { export function loadOptions() {
dict.loadOptions(['ImUserStateOptions', 'ImUserRegisterTypeOptions']); dict.loadOptions(['ImUserStateOptions', 'ImUserListStateOptions', 'ImUserRegisterTypeOptions']);
} }
export async function loadTenantOptions() { export async function loadTenantOptions() {
@@ -256,7 +257,7 @@ export async function loadTenantOptions() {
} }
export async function loadPolicyGroupOptions(tenantId: number) { export async function loadPolicyGroupOptions(tenantId: number) {
const res = await PolicyGroupList({ tenantId, page: 1, pageSize: 200 }); const res = await PolicyGroupList({ tenantId, status: 1, page: 1, perPage: 200 });
policyGroupOptions.value = (res?.list || []).map((item) => ({ policyGroupOptions.value = (res?.list || []).map((item) => ({
label: item.groupName, label: item.groupName,
value: item.id, value: item.id,