205 lines
5.6 KiB
TypeScript
205 lines
5.6 KiB
TypeScript
import { computed, ref } from 'vue';
|
||
import { cloneDeep } from 'lodash-es';
|
||
import { FormSchema } from '@/components/Form';
|
||
import { useDictStore } from '@/store/modules/dict';
|
||
import { List as TenantList } from '@/api/imTenant';
|
||
|
||
const dict = useDictStore();
|
||
|
||
export const tenantOptions = ref<any[]>([]);
|
||
export const departmentOptions = ref<any[]>([]);
|
||
|
||
export class DepartmentState {
|
||
public tenantId = 0;
|
||
public tenantName = '';
|
||
public id = 0;
|
||
public departmentId = '';
|
||
public name = '';
|
||
public parentId = 'root';
|
||
public sortOrder = 0;
|
||
public version = 1;
|
||
public state = 'active';
|
||
public childCount = 0;
|
||
public memberCount = 0;
|
||
public createdAt = '';
|
||
public updatedAt = '';
|
||
|
||
constructor(state?: Partial<DepartmentState>) {
|
||
if (state) Object.assign(this, state);
|
||
}
|
||
}
|
||
|
||
export class MemberState {
|
||
public tenantId = 0;
|
||
public tenantName = '';
|
||
public id = 0;
|
||
public departmentId = '';
|
||
public departmentName = '';
|
||
public userId = '';
|
||
public displayName = '';
|
||
public position = '';
|
||
public avatarFileId = '';
|
||
public mobile = '';
|
||
public email = '';
|
||
public employmentState = 'active';
|
||
public contactable = 1;
|
||
public sortOrder = 0;
|
||
public version = 1;
|
||
public createdAt = '';
|
||
public updatedAt = '';
|
||
|
||
constructor(state?: Partial<MemberState>) {
|
||
if (state) Object.assign(this, state);
|
||
}
|
||
}
|
||
|
||
export function newDepartmentState(state: DepartmentState | Record<string, any> | null) {
|
||
if (state !== null) {
|
||
if (state instanceof DepartmentState) return cloneDeep(state);
|
||
return new DepartmentState(state);
|
||
}
|
||
return new DepartmentState();
|
||
}
|
||
|
||
export function newMemberState(state: MemberState | Record<string, any> | null) {
|
||
if (state !== null) {
|
||
if (state instanceof MemberState) return cloneDeep(state);
|
||
return new MemberState(state);
|
||
}
|
||
return new MemberState();
|
||
}
|
||
|
||
export const departmentSchemas = ref<FormSchema[]>([
|
||
{
|
||
field: 'tenantId',
|
||
component: 'NSelect',
|
||
label: '租户',
|
||
componentProps: {
|
||
clearable: false,
|
||
options: computed(() => tenantOptions.value),
|
||
placeholder: '请选择租户',
|
||
},
|
||
},
|
||
{
|
||
field: 'name',
|
||
component: 'NInput',
|
||
label: '部门名称',
|
||
componentProps: { placeholder: '请输入部门名称' },
|
||
},
|
||
{
|
||
field: 'state',
|
||
component: 'NSelect',
|
||
label: '状态',
|
||
componentProps: {
|
||
clearable: true,
|
||
options: dict.getOption('ImOrgDepartmentStateOptions'),
|
||
placeholder: '请选择状态',
|
||
},
|
||
},
|
||
]);
|
||
|
||
export const memberSchemas = ref<FormSchema[]>([
|
||
{
|
||
field: 'query',
|
||
component: 'NInput',
|
||
label: '关键词',
|
||
componentProps: { placeholder: '姓名/手机号/邮箱/用户ID' },
|
||
},
|
||
{
|
||
field: 'employmentState',
|
||
component: 'NSelect',
|
||
label: '在职状态',
|
||
componentProps: {
|
||
clearable: true,
|
||
options: dict.getOption('ImOrgEmploymentStateOptions'),
|
||
placeholder: '请选择在职状态',
|
||
},
|
||
},
|
||
]);
|
||
|
||
export const departmentColumns = [
|
||
{ title: '部门ID', key: 'departmentId', align: 'left', width: 170 },
|
||
{ title: '部门名称', key: 'name', align: 'left', width: 160 },
|
||
{ title: '上级部门', key: 'parentId', align: 'left', width: 130 },
|
||
{
|
||
title: '状态',
|
||
key: 'state',
|
||
align: 'left',
|
||
width: 90,
|
||
render(row: DepartmentState) {
|
||
return dict.getLabel('ImOrgDepartmentStateOptions', row.state);
|
||
},
|
||
},
|
||
{ title: '子部门', key: 'childCount', align: 'left', width: 80 },
|
||
{ title: '成员', key: 'memberCount', align: 'left', width: 80 },
|
||
{ title: '排序', key: 'sortOrder', align: 'left', width: 80 },
|
||
{ title: '更新时间', key: 'updatedAt', align: 'left', width: 180 },
|
||
];
|
||
|
||
export const memberColumns = [
|
||
{ title: '用户ID', key: 'userId', align: 'left', width: 110 },
|
||
{ title: '姓名', key: 'displayName', align: 'left', width: 130 },
|
||
{ title: '部门', key: 'departmentName', align: 'left', width: 130 },
|
||
{ title: '岗位', key: 'position', align: 'left', width: 130 },
|
||
{ title: '手机号', key: 'mobile', align: 'left', width: 140 },
|
||
{ title: '邮箱', key: 'email', align: 'left', width: 180 },
|
||
{
|
||
title: '在职状态',
|
||
key: 'employmentState',
|
||
align: 'left',
|
||
width: 100,
|
||
render(row: MemberState) {
|
||
return dict.getLabel('ImOrgEmploymentStateOptions', row.employmentState);
|
||
},
|
||
},
|
||
{
|
||
title: '可联系',
|
||
key: 'contactable',
|
||
align: 'left',
|
||
width: 90,
|
||
render(row: MemberState) {
|
||
return dict.getLabel('ImOrgContactableOptions', row.contactable);
|
||
},
|
||
},
|
||
{ title: '排序', key: 'sortOrder', align: 'left', width: 80 },
|
||
{ title: '更新时间', key: 'updatedAt', align: 'left', width: 180 },
|
||
];
|
||
|
||
export const departmentRules = {
|
||
name: { required: true, trigger: ['blur', 'input'], type: 'string', message: '请输入部门名称' },
|
||
state: { required: true, trigger: ['blur', 'change'], type: 'string', message: '请选择状态' },
|
||
};
|
||
|
||
export const memberRules = {
|
||
departmentId: {
|
||
required: true,
|
||
trigger: ['blur', 'change'],
|
||
type: 'string',
|
||
message: '请选择部门',
|
||
},
|
||
userId: { required: true, trigger: ['blur', 'input'], type: 'string', message: '请输入用户ID' },
|
||
employmentState: {
|
||
required: true,
|
||
trigger: ['blur', 'change'],
|
||
type: 'string',
|
||
message: '请选择在职状态',
|
||
},
|
||
};
|
||
|
||
export function loadOptions() {
|
||
dict.loadOptions([
|
||
'ImOrgDepartmentStateOptions',
|
||
'ImOrgEmploymentStateOptions',
|
||
'ImOrgContactableOptions',
|
||
]);
|
||
}
|
||
|
||
export async function loadTenantOptions() {
|
||
const res = await TenantList({ page: 1, perPage: 100 });
|
||
tenantOptions.value = (res?.list || []).map((item) => ({
|
||
label: `${item.name}(${item.code})`,
|
||
value: item.id,
|
||
}));
|
||
return tenantOptions.value;
|
||
}
|