feat(@vben/web-antd): 实现部门列表的部门名称模糊搜索功能,优化代码结构

- 新增 fuzzyMatch 函数实现模糊匹配- 新增 filterDeptTree 函数实现部门树的过滤
- 修改部门列表的查询逻辑,支持模糊搜索
- 优化部分代码结构
This commit is contained in:
Kven 2025-06-29 00:30:10 +08:00
parent 2a94aad171
commit 91412b45cd
7 changed files with 80 additions and 136 deletions

View File

@ -28,12 +28,19 @@ export namespace RoleApi {
export interface RoleListRecord extends Role { export interface RoleListRecord extends Role {
name: string; name: string;
} }
export interface RoleListResult {
records: RoleListRecord[];
total: number;
}
} }
// 查询所有的角色列表、 // 查询所有的角色列表、
export function queryRoleList(data: RoleApi.RoleListParams) { export function queryRoleList(data: string) {
// return axios.get('/rest/role',data); // return axios.get('/rest/role',data);
return requestClient.get<Array<RoleApi.Role>>('/rest/role', { params: data }); return requestClient.get<RoleApi.RoleListResult>('/rest/role', {
params: data,
});
} }
// 切换启用状态 // 切换启用状态

View File

@ -105,6 +105,11 @@ export namespace UserApi {
address?: string; address?: string;
avatar?: string; avatar?: string;
} }
export interface UserInfoResult {
user: User;
permissions: string[];
}
} }
/** /**
@ -176,7 +181,7 @@ export function selfUpdate(data: UserApi.UserUpdateRecord) {
// 获取个人用户信息 // 获取个人用户信息
export function getUserInfo() { export function getUserInfo() {
return requestClient.get<UserApi.User>('/rest/user/self'); return requestClient.get<UserApi.UserInfoResult>('/rest/user/self');
} }
// 部门的审核员 // 部门的审核员

View File

@ -12,6 +12,37 @@ import { $t } from '#/locales';
const treeData = ref([]); const treeData = ref([]);
// utils.ts 或直接放在 data.ts 中
function fuzzyMatch(str: string, keyword: string): boolean {
if (!keyword) return true;
const reg = new RegExp([...keyword].join('.*'), 'i');
return reg.test(str);
}
export function filterDeptTree(
data: DeptApi.Dept[],
keyword: string,
): DeptApi.Dept[] {
if (!keyword) return data;
// 修改为 forEach 写法
const result: DeptApi.Dept[] = [];
data.forEach((node) => {
const match = fuzzyMatch(node.name, keyword);
const filteredChildren = node.children
? filterDeptTree(node.children, keyword)
: [];
if (match || filteredChildren.length > 0) {
result.push({
...node,
children: filteredChildren,
});
}
});
return result;
}
function transformToTreeData(data: any) { function transformToTreeData(data: any) {
return data.map((item) => ({ return data.map((item) => ({
value: item.id, value: item.id,
@ -78,28 +109,6 @@ export function useGridFormSchema(): VbenFormSchema[] {
fieldName: 'name', fieldName: 'name',
label: '部门名称', label: '部门名称',
}, },
// {
// component: 'Select',
// componentProps: {
// allowClear: true,
// options: [
// { label: $t('common.enabled'), value: true },
// { label: $t('common.disabled'), value: false },
// ],
// },
// fieldName: 'enable',
// label: '状态',
// },
// {
// component: 'Input',
// fieldName: 'remark',
// label: '备注',
// },
// {
// component: 'RangePicker',
// fieldName: 'createTime',
// label: '创建时间',
// },
]; ];
} }

View File

@ -5,6 +5,8 @@ import type {
} from '#/adapter/vxe-table'; } from '#/adapter/vxe-table';
import type { DeptApi } from '#/api'; import type { DeptApi } from '#/api';
import { ref } from 'vue';
import { Page, useVbenModal } from '@vben/common-ui'; import { Page, useVbenModal } from '@vben/common-ui';
import { Plus } from '@vben/icons'; import { Plus } from '@vben/icons';
@ -15,7 +17,7 @@ import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { getAllDeptTree, removeDept } from '#/api'; import { getAllDeptTree, removeDept } from '#/api';
import { $t } from '#/locales'; import { $t } from '#/locales';
import { useColumns, useGridFormSchema } from './data'; import { filterDeptTree, useColumns, useGridFormSchema } from './data';
// import AuthForm from './modules/auth-form.vue'; // import AuthForm from './modules/auth-form.vue';
import Form from './modules/form.vue'; import Form from './modules/form.vue';
@ -24,11 +26,6 @@ const [FormModal, formModalApi] = useVbenModal({
destroyOnClose: true, destroyOnClose: true,
}); });
// const [AuthFormModal, authFormModalApi] = useVbenModal({
// connectedComponent: AuthForm,
// destroyOnClose: true,
// });
/** /**
* 编辑部门 * 编辑部门
* @param row * @param row
@ -99,6 +96,15 @@ function onActionClick({ code, row }: OnActionClickParams<DeptApi.Dept>) {
} }
} }
const fullDeptData = ref<DeptApi.Dept[] | null>(null);
async function loadFullDeptData() {
if (!fullDeptData.value) {
fullDeptData.value = await getAllDeptTree(0);
}
return fullDeptData.value;
}
const [Grid, gridApi] = useVbenVxeGrid({ const [Grid, gridApi] = useVbenVxeGrid({
formOptions: { formOptions: {
// fieldMappingTime: [['createTime', ['startTime', 'endTime']]], // fieldMappingTime: [['createTime', ['startTime', 'endTime']]],
@ -114,10 +120,15 @@ const [Grid, gridApi] = useVbenVxeGrid({
}, },
proxyConfig: { proxyConfig: {
ajax: { ajax: {
query: async (_params) => { query: async (_, formValues) => {
const res = await getAllDeptTree(0); //
const allData = await loadFullDeptData();
// name
const { name } = formValues || {};
//
const filteredData = filterDeptTree(allData, name || '');
return { return {
items: res, items: filteredData,
}; };
}, },
}, },

View File

@ -8,7 +8,7 @@ import { getAllDeptTree, queryRoleList } from '#/api';
// import { $t } from '#/locales'; // import { $t } from '#/locales';
const treeData = ref([]); const treeData = ref([]);
const optionsRoleData = ref([]); const optionsRoleData = ref<object[]>([]);
queryRoleList('').then((res) => { queryRoleList('').then((res) => {
optionsRoleData.value = res.records.map((item) => ({ optionsRoleData.value = res.records.map((item) => ({
@ -29,93 +29,6 @@ function transformToTreeData(data: any) {
getAllDeptTree(1).then((res) => { getAllDeptTree(1).then((res) => {
treeData.value = transformToTreeData(res); treeData.value = transformToTreeData(res);
}); });
// export function useFormSchema(): VbenFormSchema[] {
// return [
// {
// component: 'Input',
// fieldName: 'username',
// label: '用户名称',
// rules: 'required',
// },
// {
// component: 'Input',
// fieldName: 'name',
// label: '昵称',
// rules: 'required',
// },
// {
// component: 'Input',
// fieldName: 'email',
// label: 'Email',
// rules: 'required',
// },
// {
// component: 'Input',
// fieldName: 'phone',
// label: '电话',
// rules: 'required',
// },
// {
// component: 'Input',
// fieldName: 'password',
// label: '密码',
// rules: 'required',
// },
// {
// component: 'Input',
// fieldName: 'address',
// label: '地址',
// },
// {
// component: 'RadioGroup',
// componentProps: {
// buttonStyle: 'solid',
// options: [
// { label: $t('common.enabled'), value: true },
// { label: $t('common.disabled'), value: false },
// ],
// optionType: 'button',
// },
// defaultValue: true,
// fieldName: 'enable',
// label: '状态',
// },
// {
// component: 'Textarea',
// fieldName: 'remark',
// label: '备注',
// },
// {
// component: 'Select',
// rules: 'required',
// componentProps: {
// allowClear: true,
// mode: 'multiple',
// // api: queryRoleList(''),
// options: optionsRoleData,
// class: 'w-full',
// labelField: 'name',
// valueField: 'id',
// },
// fieldName: 'roleIds',
// label: '所属角色',
// },
// {
// component: 'TreeSelect',
// componentProps: {
// allowClear: true,
// // api: getAllDeptTree(1),
// treeData,
// class: 'w-full',
// labelField: 'name',
// valueField: 'id',
// childrenField: 'children',
// },
// fieldName: 'deptId',
// label: '所属部门',
// },
// ];
// }
export function useGridFormSchema(): VbenFormSchema[] { export function useGridFormSchema(): VbenFormSchema[] {
return [ return [

View File

@ -14,9 +14,9 @@ import {
import { PptListView, PptWorkView } from './components'; import { PptListView, PptWorkView } from './components';
const temp = ref([]); const temp = ref<PPTTempItem[]>([]);
const hitsory = ref([]); const history = ref([]);
const loading = ref(true); const loading = ref(true);
const itemMessage = ref<ResultItem[]>([]); const itemMessage = ref<ResultItem[]>([]);
@ -26,8 +26,8 @@ const getLogs = async (appid: string, limit: number) => {
appid, appid,
limit, limit,
}); });
// hitsory // history
hitsory.value = res.reverse(); history.value = res.reverse();
loading.value = false; loading.value = false;
}; };
@ -42,7 +42,7 @@ const getTemp = async () => {
async function handleClick(item: PPTTempItem) { async function handleClick(item: PPTTempItem) {
// temp = item; // temp = item;
const res = await getWorkflowInfo({ const res = await getWorkflowInfo({
appid: item.appId, appid: item?.appId || '',
workflowRunId: item.workflowRunId, workflowRunId: item.workflowRunId,
}); });
itemMessage.value = []; itemMessage.value = [];
@ -67,7 +67,7 @@ function handleNewConversation() {
itemMessage.value = []; itemMessage.value = [];
} }
const currentTemp = ref<null | PPTTempItem>(null); const currentTemp = ref<PPTTempItem | undefined>();
async function handleClickMode(item: PPTTempItem) { async function handleClickMode(item: PPTTempItem) {
notification.success({ notification.success({
@ -90,7 +90,7 @@ onMounted(() => {
<PptListView <PptListView
title="选择模板" title="选择模板"
:temp="temp" :temp="temp"
:items="hitsory" :items="history"
:loading="loading" :loading="loading"
@click-mode="handleClickMode" @click-mode="handleClickMode"
@click="handleClick" @click="handleClick"

View File

@ -34,10 +34,12 @@ interface ResultItem {
} }
interface WorkflowContext { interface WorkflowContext {
userId: string;
conversationId: string; conversationId: string;
files: unknown[]; userId: string;
inputs: Record<string, unknown>; inputs: {
[key: string]: any;
};
files: [];
} }
interface WorkflowResult { interface WorkflowResult {
@ -56,10 +58,7 @@ interface WorkflowResult {
interface PropsWork { interface PropsWork {
itemMessage?: ResultItem[]; itemMessage?: ResultItem[];
item?: PPTTempItem; item?: PPTTempItem;
runWorkflow?: ( runWorkflow?: (appId: any, data: WorkflowContext) => Promise<WorkflowResult>;
appId: any,
context: WorkflowContext,
) => Promise<WorkflowResult>;
} }
interface MenuItem { interface MenuItem {