import { computed, h, ref } from 'vue'; import { NSwitch } from 'naive-ui'; import { cloneDeep } from 'lodash-es'; import { FormSchema } from '@/components/Form'; import { defRangeShortcuts } from '@/utils/dateUtil'; import { useDictStore } from '@/store/modules/dict'; import { List as TenantList } from '@/api/imTenant'; import { Status } from '@/api/imUser'; import { usePermission } from '@/hooks/web/usePermission'; const dict = useDictStore(); const { hasPermission } = usePermission(); const $message = window['$message']; export const tenantOptions = ref([]); export class State { public tenantId = 0; // 租户ID public tenantName = ''; // 租户名称 public userId = ''; // 用户ID public username = ''; // 登录账号 public phone = ''; // 手机号 public nickname = ''; // 昵称 public publicAccount = ''; // 公开账号 public gender = ''; // 性别 public region = ''; // 地区 public state = 0; // 账号状态 public authVersion = 0; // 认证版本 public passwordUpdatedAt = ''; // 密码更新时间 public authNames = ''; // 登录标识 public credentials = ''; // 凭证 public lastSeen = ''; // 最后在线时间 public userAgent = ''; // 客户端 public createdAt = ''; // 创建时间 public updatedAt = ''; // 修改时间 public signature = ''; // 个性签名 public avatarFileId = ''; // 头像文件ID public birthDate = ''; // 出生日期 public profileJson = ''; // Tinode Public资料 public trustedJson = ''; // Tinode Trusted资料 public accessJson = ''; // 访问权限 public profileVersion = 0; // 资料版本 constructor(state?: Partial) { if (state) { Object.assign(this, state); } } } export class DeviceState { public tenantId = 0; public tenantName = ''; public userId = ''; public deviceId = ''; public platform = ''; public lang = ''; public lastSeen = ''; public pushProvider = ''; public pushPlatform = ''; public pushAppVersion = ''; public pushTokenConfigured = false; public pushUpdatedAt = ''; } export function newState(state: State | Record | null): State { if (state !== null) { if (state instanceof State) { return cloneDeep(state); } return new State(state); } return new State(); } // 表格搜索表单 export const schemas = ref([ { field: 'tenantId', component: 'NSelect', label: '租户', componentProps: { clearable: false, options: computed(() => tenantOptions.value), placeholder: '请选择租户', }, }, { field: 'userId', component: 'NInput', label: '用户ID', componentProps: { placeholder: '请输入用户ID', }, }, { field: 'nickname', component: 'NInput', label: '昵称', componentProps: { placeholder: '请输入昵称', }, }, { field: 'authName', component: 'NInput', label: '登录标识', componentProps: { placeholder: '请输入登录名/手机号/邮箱', }, }, { field: 'state', component: 'NSelect', label: '状态', componentProps: { clearable: true, options: computed(() => dict.getOptions('ImUserStateOptions')), placeholder: '请选择状态', }, }, { field: 'createdAt', component: 'NDatePicker', label: '创建时间', componentProps: { type: 'datetimerange', clearable: true, shortcuts: defRangeShortcuts(), }, }, { field: 'lastSeen', component: 'NDatePicker', label: '最后在线', componentProps: { type: 'datetimerange', clearable: true, shortcuts: defRangeShortcuts(), }, }, ]); // 表格列 export const columns = [ { title: '用户ID', key: 'userId', align: 'left', width: 120, }, { title: '昵称', key: 'nickname', align: 'left', width: 160, }, { title: '登录账号', key: 'username', align: 'left', width: 180, }, { title: '手机号', key: 'phone', align: 'left', width: 180, }, { title: '公开账号', key: 'publicAccount', align: 'left', width: 150, }, { title: '状态', key: 'state', align: 'left', width: 110, render(row: State) { if (row.state === 20) { return dict.getLabel('ImUserStateOptions', row.state); } return h(NSwitch, { value: row.state === 0, checked: '正常', unchecked: '停用', disabled: !hasPermission(['/imUser/status']), onUpdateValue: async (value) => { const oldState = row.state; row.state = value ? 0 : 10; try { await Status({ tenantId: row.tenantId, userId: row.userId, state: row.state }); $message.success('操作成功'); } catch { row.state = oldState; } }, }); }, }, { title: '登录标识', key: 'authNames', align: 'left', width: 240, }, { title: '凭证', key: 'credentials', align: 'left', width: 220, }, { title: '最后在线', key: 'lastSeen', align: 'left', width: 180, }, { title: '客户端', key: 'userAgent', align: 'left', width: 240, }, { title: '创建时间', key: 'createdAt', align: 'left', width: 180, }, { title: '修改时间', key: 'updatedAt', align: 'left', width: 180, }, ]; export const deviceColumns = [ { title: '设备ID', key: 'deviceId', align: 'left', width: 240 }, { title: '平台', key: 'platform', align: 'left', width: 120 }, { title: '语言', key: 'lang', align: 'left', width: 90 }, { title: '最后活跃', key: 'lastSeen', align: 'left', width: 180 }, { title: 'Push服务商', key: 'pushProvider', align: 'left', width: 120 }, { title: 'Push平台', key: 'pushPlatform', align: 'left', width: 120 }, { title: 'App版本', key: 'pushAppVersion', align: 'left', width: 120 }, { title: 'Push Token', key: 'pushTokenConfigured', align: 'left', width: 120, render(row: DeviceState) { return row.pushTokenConfigured ? '已配置' : '未配置'; }, }, { title: 'Push更新时间', key: 'pushUpdatedAt', align: 'left', width: 180 }, ]; // 加载字典数据选项 export function loadOptions() { dict.loadOptions(['ImUserStateOptions']); } export async function loadTenantOptions() { const res = await TenantList({ page: 1, perPage: 20 }); tenantOptions.value = (res?.list || []).map((item) => ({ label: `${item.name}(${item.code})`, value: item.id, })); return tenantOptions.value; }