From 03ffdd67fc4c40f3e9443931a0aa55e508182873 Mon Sep 17 00:00:00 2001 From: wupengfei <834520024@qq.com> Date: 星期三, 06 八月 2025 17:00:06 +0800 Subject: [PATCH] feat: 字典 --- src/constants/user.ts | 4 src/views/DictionaryManage/DictionaryCategoryManage.vue | 165 +++++ src/constants/dic.ts | 23 src/hooks/dic.ts | 111 +++ src/views/DictionaryManage/components/AddOrEditDictionaryCategory.vue | 90 ++ .eslintrc-auto-import.json | 2 src/services/api/typings.d.ts | 429 +++++++++++++ src/views/DictionaryManage/DataDictionary.vue | 169 ++--- src/services/api/dictionary.ts | 118 +++ src/views/Permission/OperationUserManage.vue | 175 +++++ src/services/api/enterprise.ts | 18 types/api.d.ts | 12 /dev/null | 147 ---- src/services/api/index.ts | 8 src/services/api/role.ts | 45 + src/views/Permission/components/SetOperationUserRoleDialog.vue | 61 + src/services/api/userInfo.ts | 66 ++ src/views/System/ModuleManage.vue | 29 auto-imports.d.ts | 6 src/views/DictionaryManage/components/AddOrEditDictionaryDialog.vue | 142 ++++ src/constants/apiEnum.ts | 12 src/constants/index.ts | 2 src/utils/common/common.ts | 9 23 files changed, 1,569 insertions(+), 274 deletions(-) diff --git a/.eslintrc-auto-import.json b/.eslintrc-auto-import.json index 9e9f385..edae8cc 100644 --- a/.eslintrc-auto-import.json +++ b/.eslintrc-auto-import.json @@ -26,6 +26,8 @@ "EnumRoleWebApiDataPower": true, "EnumRoleWebApiDataPowerText": true, "EnumRoleWebApiDataPowerTextForFilter": true, + "EnumUserInfoStatus": true, + "EnumUserInfoStatusText": true, "EnumUserType": true, "EnumUserTypeText": true, "ExtractDefaultPropTypes": true, diff --git a/auto-imports.d.ts b/auto-imports.d.ts index 92e91a2..b150c9f 100644 --- a/auto-imports.d.ts +++ b/auto-imports.d.ts @@ -32,6 +32,8 @@ const EnumRoleWebApiDataPower: typeof import('./src/constants/apiEnum')['EnumRoleWebApiDataPower'] const EnumRoleWebApiDataPowerText: typeof import('./src/constants/apiEnumText')['EnumRoleWebApiDataPowerText'] const EnumRoleWebApiDataPowerTextForFilter: typeof import('./src/constants/apiEnumText')['EnumRoleWebApiDataPowerTextForFilter'] + const EnumUserInfoStatus: typeof import('./src/constants/apiEnum')['EnumUserInfoStatus'] + const EnumUserInfoStatusText: typeof import('./src/constants/user')['EnumUserInfoStatusText'] const EnumUserType: typeof import('./src/constants/apiEnum')['EnumUserType'] const EnumUserTypeText: typeof import('./src/constants/apiEnumText')['EnumUserTypeText'] const EnumWebApiMethod: typeof import('./src/constants/apiEnum')['EnumWebApiMethod'] @@ -163,7 +165,7 @@ export type { Component, Slot, Slots, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue' import('vue') // @ts-ignore - export type { EnumClientType, EnumMenuType, EnumMenuVisitLevel, EnumPagedListOrder, EnumResourceController, EnumResourceMethod, EnumRoleWebApiDataPower, EnumUserType, EnumClientType, EnumMenuType, EnumMenuVisitLevel, EnumPagedListOrder, EnumResourceController, EnumResourceMethod, EnumRoleWebApiDataPower, EnumUserType } from './src/constants/apiEnum' + export type { EnumClientType, EnumMenuType, EnumMenuVisitLevel, EnumPagedListOrder, EnumResourceController, EnumResourceMethod, EnumRoleWebApiDataPower, EnumUserInfoStatus, EnumUserType, EnumClientType, EnumMenuType, EnumMenuVisitLevel, EnumPagedListOrder, EnumResourceController, EnumResourceMethod, EnumRoleWebApiDataPower, EnumUserInfoStatus, EnumUserType } from './src/constants/apiEnum' import('./src/constants/apiEnum') // @ts-ignore export type { FlexWorkerEleSignEnum, FlexTaskWorkerHireEnum, FlexWorkerEleSignEnum, FlexTaskWorkerHireEnum } from './src/constants/cPerson' @@ -221,6 +223,8 @@ readonly EnumRoleWebApiDataPower: UnwrapRef<typeof import('./src/constants/apiEnum')['EnumRoleWebApiDataPower']> readonly EnumRoleWebApiDataPowerText: UnwrapRef<typeof import('./src/constants/apiEnumText')['EnumRoleWebApiDataPowerText']> readonly EnumRoleWebApiDataPowerTextForFilter: UnwrapRef<typeof import('./src/constants/apiEnumText')['EnumRoleWebApiDataPowerTextForFilter']> + readonly EnumUserInfoStatus: UnwrapRef<typeof import('./src/constants/apiEnum')['EnumUserInfoStatus']> + readonly EnumUserInfoStatusText: UnwrapRef<typeof import('./src/constants/user')['EnumUserInfoStatusText']> readonly EnumUserType: UnwrapRef<typeof import('./src/constants/apiEnum')['EnumUserType']> readonly EnumUserTypeText: UnwrapRef<typeof import('./src/constants/apiEnumText')['EnumUserTypeText']> readonly FastButtonMap: UnwrapRef<typeof import('./src/constants/module')['FastButtonMap']> diff --git a/src/constants/apiEnum.ts b/src/constants/apiEnum.ts index 87b2651..8069622 100644 --- a/src/constants/apiEnum.ts +++ b/src/constants/apiEnum.ts @@ -53,6 +53,10 @@ Resource = 3, /**鐢ㄦ埛瑙掕壊 */ Role = 4, + /**鐢ㄦ埛淇℃伅 */ + UserInfo = 5, + /**浼佷笟淇℃伅 */ + Enterprise = 6, } /** 璧勬簮璇锋眰鏂瑰紡 */ @@ -83,6 +87,14 @@ All = 999, } +/** 鐢ㄦ埛淇℃伅鐘舵�� */ +export enum EnumUserInfoStatus { + /**姝e父 */ + Normal = 10, + /**绂佺敤 */ + Disabled = 100, +} + /** 鐢ㄦ埛绫诲瀷 */ export enum EnumUserType { /**涓汉 */ diff --git a/src/constants/dic.ts b/src/constants/dic.ts index 3ad3406..534792d 100644 --- a/src/constants/dic.ts +++ b/src/constants/dic.ts @@ -1,23 +1,14 @@ -export enum SearchType { +export enum CategoryCode { /**韬唤 */ - Identity = 210, + Identity = '10', /**瀛﹀巻 */ - Education = 220, + Education = '20', /**宀椾綅 */ - Position = 230, + Position = '30', /**璇佷功绫诲瀷 */ - CertificateType = 240, + CertificateType = '40', /**绂忓埄 */ - Welfare = 250, + Welfare = '50', /**琛屼笟绫诲瀷 */ - IndustryCategory = 260, + IndustryCategory = '60', } - -export const SearchTypeText = { - [SearchType.Identity]: '韬唤', - [SearchType.Education]: '瀛﹀巻', - [SearchType.Position]: '宀椾綅', - [SearchType.CertificateType]: '璇佷功绫诲瀷', - [SearchType.Welfare]: '绂忓埄', - [SearchType.IndustryCategory]: '琛屼笟绫诲瀷', -}; diff --git a/src/constants/index.ts b/src/constants/index.ts index 1849c34..b179761 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -14,3 +14,5 @@ export * from './cPerson'; export * from './apiEnum'; export * from './apiEnumText'; +export * from './user'; +export * from './dic'; diff --git a/src/constants/user.ts b/src/constants/user.ts new file mode 100644 index 0000000..588b889 --- /dev/null +++ b/src/constants/user.ts @@ -0,0 +1,4 @@ +export const EnumUserInfoStatusText = { + [EnumUserInfoStatus.Normal]: '姝e父', + [EnumUserInfoStatus.Disabled]: '绂佺敤', +}; diff --git a/src/hooks/dic.ts b/src/hooks/dic.ts index 25dd1c8..8935320 100644 --- a/src/hooks/dic.ts +++ b/src/hooks/dic.ts @@ -1,8 +1,109 @@ import { useQuery, useQueryClient } from '@tanstack/vue-query'; -import { SearchType } from '@/constants'; +import * as dictionaryServices from '@/services/api/dictionary'; -type UseSearchSettingTypeOptions = { - searchType: number; - belongType?: number; - onSuccess?: (data: any[]) => any; +export function useGetDictionaryCategorySelect() { + const { data: dictionaryCategoryList, refetch } = useQuery({ + queryKey: ['dictionaryServices/getDictionaryCategorySelect'], + queryFn: async () => { + let res = await dictionaryServices.getDictionaryCategorySelect({}, { showLoading: false }); + return res.map((x) => ({ + ...x, + fieldNamesMap: x.data.fieldNames ? JSON.parse(x.data.fieldNames) : {}, + })); + }, + placeholderData: () => + [] as API.SelectQueryResultOptionGuidGetDictionaryCategorySelectQueryOption[], + }); + + const queryClient = useQueryClient(); + + function ensureQueryData() { + return queryClient.ensureQueryData< + API.SelectQueryResultOptionGuidGetDictionaryCategorySelectQueryOption[] + >({ + queryKey: ['dictionaryServices/getDictionaryCategorySelect'], + }); + } + + function getDictionaryCategoryById(id: string) { + return dictionaryCategoryList.value.find((x) => x.value === id); + } + + function getDictionaryCategoryByCode(code: string) { + return dictionaryCategoryList.value.find((x) => x.code === code); + } + + function getDictionaryCategoryNameByCode(code: string) { + return getDictionaryCategoryByCode(code)?.label ?? ''; + } + + return { + dictionaryCategoryList, + ensureQueryData, + getDictionaryCategoryById, + getDictionaryCategoryNameByCode, + getDictionaryCategoryByCode, + }; +} + +type UseDictionaryDataSelectOptions = { + categoryId?: MaybeRef<string>; + categoryCode?: MaybeRef<string>; }; + +export function useDictionaryDataSelect({ + categoryId, + categoryCode, +}: UseDictionaryDataSelectOptions) { + const { data: dictionaryDataList, refetch } = useQuery({ + queryKey: ['dictionaryServices/getDictionaryDataSelect'], + queryFn: async () => { + let res = await dictionaryServices.getDictionaryDataSelect( + { + categoryId: unref(categoryId), + categoryCode: unref(categoryCode), + }, + { showLoading: false } + ); + return res.map((x) => ({ + ...x, + code: x.data?.code ?? '', + })); + }, + placeholderData: () => + [] as API.SelectQueryResultOptionGuidGetDictionaryDataSelectQueryResultOption[], + + enabled: !!unref(categoryId) || !!unref(categoryCode), + }); + + function getDictionaryDataNameById(id: string) { + return dictionaryDataList.value?.find((x) => x.value === id)?.label; + } + + function getDictionaryDataByCode(code: string) { + return dictionaryDataList.value?.find((x) => x.code === code); + } + + function getDictionaryDataNameByCode(code: string) { + return getDictionaryDataByCode(code)?.label ?? ''; + } + + const queryClient = useQueryClient(); + + function ensureQueryData() { + return queryClient.ensureQueryData< + API.SelectQueryResultOptionGuidGetDictionaryDataSelectQueryResultOption[] + >({ + queryKey: ['dictionaryServices/getDictionaryDataSelect'], + }); + } + + return { + dictionaryDataList, + ensureQueryData, + refetch, + getDictionaryDataNameById, + getDictionaryDataNameByCode, + getDictionaryDataByCode, + }; +} diff --git a/src/services/api/dictionary.ts b/src/services/api/dictionary.ts index 961750b..22cee24 100644 --- a/src/services/api/dictionary.ts +++ b/src/services/api/dictionary.ts @@ -2,7 +2,60 @@ // @ts-ignore import { request } from '@/utils/request'; -/** 鑾峰彇瀛楀吀鏁版嵁鍒嗛〉鍒楄〃 POST /api/main/dictionary/getDictionaryDatas */ +/** 鍒犻櫎鏁版嵁瀛楀吀绫诲埆 DELETE /api/main/dictionary/deleteDictionaryCategory */ +export async function deleteDictionaryCategory( + body: API.DeleteDictionaryCategoryCommand, + options?: API.RequestConfig +) { + return request<number>('/api/main/dictionary/deleteDictionaryCategory', { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json-patch+json', + }, + data: body, + ...(options || {}), + }); +} + +/** 鑾峰彇鏁版嵁瀛楀吀绫诲埆鍒嗛〉鍒楄〃鏁版嵁 POST /api/main/dictionary/getDictionaryCategories */ +export async function getDictionaryCategories( + body: API.GetDictionaryCategoriesQuery, + options?: API.RequestConfig +) { + return request<API.PagedListQueryResultGetDictionaryCategoriesQueryResultItem>( + '/api/main/dictionary/getDictionaryCategories', + { + method: 'POST', + headers: { + 'Content-Type': 'application/json-patch+json', + }, + data: body, + ...(options || {}), + } + ); +} + +/** 鏌ヨ鏁版嵁瀛楀吀绫诲埆閫夋嫨鍣ㄦ暟鎹� GET /api/main/dictionary/getDictionaryCategorySelect */ +export async function getDictionaryCategorySelect( + // 鍙犲姞鐢熸垚鐨凱aram绫诲瀷 (闈瀊ody鍙傛暟swagger榛樿娌℃湁鐢熸垚瀵硅薄) + params: API.APIgetDictionaryCategorySelectParams, + options?: API.RequestConfig +) { + return request<API.SelectQueryResultOptionGuidGetDictionaryCategorySelectQueryOption[]>( + '/api/main/dictionary/getDictionaryCategorySelect', + { + method: 'GET', + params: { + ...params, + request: undefined, + ...params['request'], + }, + ...(options || {}), + } + ); +} + +/** 鑾峰彇鏁版嵁瀛楀吀鍒嗛〉鍒楄〃鏁版嵁 POST /api/main/dictionary/getDictionaryDatas */ export async function getDictionaryDatas( body: API.GetDictionaryDatasQuery, options?: API.RequestConfig @@ -19,3 +72,66 @@ } ); } + +/** 鏌ヨ鏁版嵁瀛楀吀閫夋嫨鍣� GET /api/main/dictionary/getDictionaryDataSelect */ +export async function getDictionaryDataSelect( + // 鍙犲姞鐢熸垚鐨凱aram绫诲瀷 (闈瀊ody鍙傛暟swagger榛樿娌℃湁鐢熸垚瀵硅薄) + params: API.APIgetDictionaryDataSelectParams, + options?: API.RequestConfig +) { + return request<API.SelectQueryResultOptionGuidGetDictionaryDataSelectQueryResultOption[]>( + '/api/main/dictionary/getDictionaryDataSelect', + { + method: 'GET', + params: { + ...params, + }, + ...(options || {}), + } + ); +} + +/** 淇濆瓨鏁版嵁瀛楀吀绫诲埆 POST /api/main/dictionary/saveDictionaryCategory */ +export async function saveDictionaryCategory( + body: API.SaveDictionaryCategoryCommand, + options?: API.RequestConfig +) { + return request<string>('/api/main/dictionary/saveDictionaryCategory', { + method: 'POST', + headers: { + 'Content-Type': 'application/json-patch+json', + }, + data: body, + ...(options || {}), + }); +} + +/** 淇濆瓨鏁版嵁瀛楀吀 POST /api/main/dictionary/saveDictionaryData */ +export async function saveDictionaryData( + body: API.SaveDictionaryDataCommand, + options?: API.RequestConfig +) { + return request<string>('/api/main/dictionary/saveDictionaryData', { + method: 'POST', + headers: { + 'Content-Type': 'application/json-patch+json', + }, + data: body, + ...(options || {}), + }); +} + +/** 璁剧疆鏁版嵁瀛楀吀鏄惁绂佺敤 PUT /api/main/dictionary/setDictionaryDataIsDisabled */ +export async function setDictionaryDataIsDisabled( + body: API.SetDictionaryDataIsDisabledCommand, + options?: API.RequestConfig +) { + return request<number>('/api/main/dictionary/setDictionaryDataIsDisabled', { + method: 'PUT', + headers: { + 'Content-Type': 'application/json-patch+json', + }, + data: body, + ...(options || {}), + }); +} diff --git a/src/services/api/enterprise.ts b/src/services/api/enterprise.ts new file mode 100644 index 0000000..820738d --- /dev/null +++ b/src/services/api/enterprise.ts @@ -0,0 +1,18 @@ +/* eslint-disable */ +// @ts-ignore +import { request } from '@/utils/request'; + +/** 鏌ヨ浼佷笟淇℃伅鍒嗛〉鍒楄〃鏁版嵁 POST /api/user/enterprise/getEnterprises */ +export async function getEnterprises(body: API.GetEnterprisesQuery, options?: API.RequestConfig) { + return request<API.PagedListQueryResultGetEnterprisesQueryResultItem>( + '/api/user/enterprise/getEnterprises', + { + method: 'POST', + headers: { + 'Content-Type': 'application/json-patch+json', + }, + data: body, + ...(options || {}), + } + ); +} diff --git a/src/services/api/index.ts b/src/services/api/index.ts index e96a264..1f801d3 100644 --- a/src/services/api/index.ts +++ b/src/services/api/index.ts @@ -2,15 +2,19 @@ /* eslint-disable */ // API 鏇存柊鏃堕棿锛� // API 鍞竴鏍囪瘑锛� -import * as dictionary from './dictionary'; import * as auth from './auth'; import * as menu from './menu'; +import * as dictionary from './dictionary'; import * as resource from './resource'; import * as role from './role'; +import * as userInfo from './userInfo'; +import * as enterprise from './enterprise'; export default { - dictionary, auth, menu, + dictionary, resource, role, + userInfo, + enterprise, }; diff --git a/src/services/api/role.ts b/src/services/api/role.ts index 36ede2e..1ed081d 100644 --- a/src/services/api/role.ts +++ b/src/services/api/role.ts @@ -41,6 +41,21 @@ }); } +/** 鏌ヨ瑙掕壊鐢ㄦ埛鍒楄〃 GET /api/user/role/getRoleUserInfos */ +export async function getRoleUserInfos( + // 鍙犲姞鐢熸垚鐨凱aram绫诲瀷 (闈瀊ody鍙傛暟swagger榛樿娌℃湁鐢熸垚瀵硅薄) + params: API.APIgetRoleUserInfosParams, + options?: API.RequestConfig +) { + return request<API.GetRoleUserInfosQueryResultItem[]>('/api/user/role/getRoleUserInfos', { + method: 'GET', + params: { + ...params, + }, + ...(options || {}), + }); +} + /** 淇濆瓨瑙掕壊 POST /api/user/role/saveRole */ export async function saveRole(body: API.SaveRoleCommand, options?: API.RequestConfig) { return request<string>('/api/user/role/saveRole', { @@ -52,3 +67,33 @@ ...(options || {}), }); } + +/** 璁剧疆瑙掕壊鏄惁绂佺敤 PUT /api/user/role/setRoleIsDisabled */ +export async function setRoleIsDisabled( + body: API.SetRoleIsDisabledCommand, + options?: API.RequestConfig +) { + return request<number>('/api/user/role/setRoleIsDisabled', { + method: 'PUT', + headers: { + 'Content-Type': 'application/json-patch+json', + }, + data: body, + ...(options || {}), + }); +} + +/** 璁剧疆瑙掕壊鐢ㄦ埛 PUT /api/user/role/setRoleUserInfos */ +export async function setRoleUserInfos( + body: API.SetRoleUserInfosCommand, + options?: API.RequestConfig +) { + return request<number>('/api/user/role/setRoleUserInfos', { + method: 'PUT', + headers: { + 'Content-Type': 'application/json-patch+json', + }, + data: body, + ...(options || {}), + }); +} diff --git a/src/services/api/typings.d.ts b/src/services/api/typings.d.ts index 5773566..960421a 100644 --- a/src/services/api/typings.d.ts +++ b/src/services/api/typings.d.ts @@ -13,6 +13,20 @@ request?: GetCurrentLogierMenusQuery; } + interface APIgetDictionaryCategorySelectParams { + /** 鏌ヨ鏁版嵁瀛楀吀绫诲埆閫夋嫨鍣ㄦ暟鎹� */ + request?: GetDictionaryCategorySelectQuery; + } + + interface APIgetDictionaryDataSelectParams { + /** 绫诲埆Id锛圛d/缂栧彿浜岄�変竴锛� */ + categoryId?: string; + /** 绫诲埆缂栧彿锛圛d/缂栧彿浜岄�変竴锛� */ + categoryCode?: string; + /** 涓婄骇Id */ + parentId?: string; + } + interface APIgetMenuParams { /** Id */ id?: string; @@ -46,6 +60,22 @@ interface APIgetRoleParams { /** Id */ id?: string; + } + + interface APIgetRoleUserInfosParams { + /** 瑙掕壊Id */ + roleId?: string; + } + + interface APIgetUserInfoRolesParams { + /** 鐢ㄦ埛Id */ + userInfoId?: string; + /** 瀹㈡埛绔被鍨� */ + clientType?: EnumClientType; + } + + interface DeleteDictionaryCategoryCommand { + ids: string[]; } interface DeleteMenuCommand { @@ -103,6 +133,10 @@ Resource = 3, /**鐢ㄦ埛瑙掕壊 */ Role = 4, + /**鐢ㄦ埛淇℃伅 */ + UserInfo = 5, + /**浼佷笟淇℃伅 */ + Enterprise = 6, } enum EnumResourceMethod { @@ -129,6 +163,13 @@ CurrentEnterprise = 30, /**鏌ヨ鎵�鏈� */ All = 999, + } + + enum EnumUserInfoStatus { + /**姝e父 */ + Normal = 10, + /**绂佺敤 */ + Disabled = 100, } enum EnumUserType { @@ -289,6 +330,100 @@ timestamp?: number; } + interface FriendlyResultListGetRoleUserInfosQueryResultItem { + /** 璺熻釜Id */ + traceId?: string; + /** 鐘舵�佺爜 */ + code?: number; + /** 閿欒鐮� */ + errorCode?: string; + /** 鏁版嵁 */ + data?: GetRoleUserInfosQueryResultItem[]; + /** 鎵ц鎴愬姛 */ + success?: boolean; + /** 閿欒淇℃伅 */ + msg?: any; + /** 闄勫姞鏁版嵁 */ + extras?: any; + /** 鏃堕棿鎴� */ + timestamp?: number; + } + + interface FriendlyResultListGetUserInfoRolesQueryResultItem { + /** 璺熻釜Id */ + traceId?: string; + /** 鐘舵�佺爜 */ + code?: number; + /** 閿欒鐮� */ + errorCode?: string; + /** 鏁版嵁 */ + data?: GetUserInfoRolesQueryResultItem[]; + /** 鎵ц鎴愬姛 */ + success?: boolean; + /** 閿欒淇℃伅 */ + msg?: any; + /** 闄勫姞鏁版嵁 */ + extras?: any; + /** 鏃堕棿鎴� */ + timestamp?: number; + } + + interface FriendlyResultListSelectQueryResultOptionGuidGetDictionaryCategorySelectQueryOption { + /** 璺熻釜Id */ + traceId?: string; + /** 鐘舵�佺爜 */ + code?: number; + /** 閿欒鐮� */ + errorCode?: string; + /** 鏁版嵁 */ + data?: SelectQueryResultOptionGuidGetDictionaryCategorySelectQueryOption[]; + /** 鎵ц鎴愬姛 */ + success?: boolean; + /** 閿欒淇℃伅 */ + msg?: any; + /** 闄勫姞鏁版嵁 */ + extras?: any; + /** 鏃堕棿鎴� */ + timestamp?: number; + } + + interface FriendlyResultListSelectQueryResultOptionGuidGetDictionaryDataSelectQueryResultOption { + /** 璺熻釜Id */ + traceId?: string; + /** 鐘舵�佺爜 */ + code?: number; + /** 閿欒鐮� */ + errorCode?: string; + /** 鏁版嵁 */ + data?: SelectQueryResultOptionGuidGetDictionaryDataSelectQueryResultOption[]; + /** 鎵ц鎴愬姛 */ + success?: boolean; + /** 閿欒淇℃伅 */ + msg?: any; + /** 闄勫姞鏁版嵁 */ + extras?: any; + /** 鏃堕棿鎴� */ + timestamp?: number; + } + + interface FriendlyResultPagedListQueryResultGetDictionaryCategoriesQueryResultItem { + /** 璺熻釜Id */ + traceId?: string; + /** 鐘舵�佺爜 */ + code?: number; + /** 閿欒鐮� */ + errorCode?: string; + data?: PagedListQueryResultGetDictionaryCategoriesQueryResultItem; + /** 鎵ц鎴愬姛 */ + success?: boolean; + /** 閿欒淇℃伅 */ + msg?: any; + /** 闄勫姞鏁版嵁 */ + extras?: any; + /** 鏃堕棿鎴� */ + timestamp?: number; + } + interface FriendlyResultPagedListQueryResultGetDictionaryDatasQueryResultItem { /** 璺熻釜Id */ traceId?: string; @@ -297,6 +432,42 @@ /** 閿欒鐮� */ errorCode?: string; data?: PagedListQueryResultGetDictionaryDatasQueryResultItem; + /** 鎵ц鎴愬姛 */ + success?: boolean; + /** 閿欒淇℃伅 */ + msg?: any; + /** 闄勫姞鏁版嵁 */ + extras?: any; + /** 鏃堕棿鎴� */ + timestamp?: number; + } + + interface FriendlyResultPagedListQueryResultGetEnterprisesQueryResultItem { + /** 璺熻釜Id */ + traceId?: string; + /** 鐘舵�佺爜 */ + code?: number; + /** 閿欒鐮� */ + errorCode?: string; + data?: PagedListQueryResultGetEnterprisesQueryResultItem; + /** 鎵ц鎴愬姛 */ + success?: boolean; + /** 閿欒淇℃伅 */ + msg?: any; + /** 闄勫姞鏁版嵁 */ + extras?: any; + /** 鏃堕棿鎴� */ + timestamp?: number; + } + + interface FriendlyResultPagedListQueryResultGetOperationUserInfosQueryResultItem { + /** 璺熻釜Id */ + traceId?: string; + /** 鐘舵�佺爜 */ + code?: number; + /** 閿欒鐮� */ + errorCode?: string; + data?: PagedListQueryResultGetOperationUserInfosQueryResultItem; /** 鎵ц鎴愬姛 */ success?: boolean; /** 閿欒淇℃伅 */ @@ -355,11 +526,98 @@ type GetCurrentLogierMenusQuery = Record<string, any>; - interface GetDictionaryDatasQuery { + interface GetDictionaryCategoriesQuery { pageModel?: PagedListQueryPageModel; + /** 鍏抽敭瀛� */ + keywords?: string; } - type GetDictionaryDatasQueryResultItem = Record<string, any>; + interface GetDictionaryCategoriesQueryResultItem { + /** Id */ + id?: string; + /** 缂栧彿 */ + code?: string; + /** 鍚嶇О */ + name?: string; + /** 瀛楁鍚嶏紙閫楀彿闅斿紑锛� */ + fieldNames?: string; + /** 鎺掑簭 */ + sort?: number; + } + + type GetDictionaryCategorySelectQuery = Record<string, any>; + + interface GetDictionaryDatasQuery { + pageModel?: PagedListQueryPageModel; + /** 绫诲埆Id锛圛d/缂栧彿浜岄�変竴锛� */ + categoryId?: string; + /** 绫诲埆缂栧彿锛圛d/缂栧彿浜岄�変竴锛� */ + categoryCode?: string; + /** 鍏抽敭瀛� */ + keywords?: string; + } + + interface GetDictionaryDatasQueryResultItem { + /** Id */ + id?: string; + /** 绫诲埆Id */ + categoryId?: string; + /** 绫诲埆缂栧彿 */ + categoryCode?: string; + /** 绫诲埆鍚嶇О */ + categoryName?: string; + category?: GetDictionaryDatasQueryResultItemCategory; + /** 涓婄骇Id */ + parentId?: string; + /** 缂栧彿 */ + code?: string; + /** 鏄剧ず鍐呭 */ + content: string; + /** 瀛楁1 */ + field1?: string; + /** 瀛楁2 */ + field2?: string; + /** 瀛楁3 */ + field3?: string; + /** 瀛楁4 */ + field4?: string; + /** 瀛楁5 */ + field5?: string; + /** 鎺掑簭 */ + sort?: number; + /** 鏄惁绂佺敤 */ + isDisabled?: boolean; + } + + interface GetDictionaryDatasQueryResultItemCategory { + /** 绫诲埆缂栧彿 */ + code?: string; + /** 鍚嶇О */ + name?: string; + } + + interface GetEnterprisesQuery { + pageModel?: PagedListQueryPageModel; + /** 鍏抽敭瀛� */ + keywords?: string; + /** 鏄惁宸查厤缃� */ + isConfigured?: boolean; + } + + interface GetEnterprisesQueryResultItem { + /** Id */ + id?: string; + /** 浼佷笟鍏ㄧО */ + enterpriseName?: string; + /** 娉曚汉濮撳悕 */ + legalPerson?: string; + /** 缁熶竴绀句細淇$敤浠g爜 */ + societyCreditCode?: string; + /** 鑱旂郴浜� */ + contacts?: string; + /** 鑱旂郴鐢佃瘽 */ + contactNumber?: string; + } interface GetMenuQueryResult { /** Id */ @@ -477,6 +735,37 @@ remark?: string; } + interface GetOperationUserInfosQuery { + pageModel?: PagedListQueryPageModel; + /** 鍏抽敭瀛� */ + keywords?: string; + } + + interface GetOperationUserInfosQueryResultItem { + /** Id */ + id?: string; + /** 濮撳悕 */ + name?: string; + /** 鐢ㄦ埛鍚� */ + userName?: string; + /** 鎵嬫満鍙� */ + phoneNumber?: string; + /** 澶囨敞 */ + remark?: string; + /** 瑙掕壊 */ + roles?: GetOperationUserInfosQueryResultItemRole[]; + status?: EnumUserInfoStatus; + } + + interface GetOperationUserInfosQueryResultItemRole { + /** 鐢ㄦ埛Id */ + userInfoId?: string; + /** 瑙掕壊Id */ + id?: string; + /** 鍚嶇О */ + name?: string; + } + interface GetResourceFieldsQueryResultItem { /** 缂栧彿 */ code?: string; @@ -537,6 +826,8 @@ pageModel?: PagedListQueryPageModel; userType?: EnumUserType; clientType?: EnumClientType; + /** 鍏抽敭瀛� */ + keywords?: string; } interface GetRolesQueryResultItem { @@ -551,6 +842,32 @@ dataPower?: EnumRoleWebApiDataPower; /** 澶囨敞 */ remark?: string; + /** 鏄惁绂佺敤 */ + isDisabled?: boolean; + /** 鐢ㄦ埛鏁伴噺 */ + userCount?: number; + } + + interface GetRoleUserInfosQueryResultItem { + /** 鐢ㄦ埛Id */ + id?: string; + /** 濮撳悕 */ + name?: string; + /** 鐢ㄦ埛鍚� */ + userName?: string; + /** 鏄惁閫変腑 */ + isChecked?: boolean; + } + + interface GetUserInfoRolesQueryResultItem { + /** 瑙掕壊Id */ + id?: string; + /** 鍚嶇О */ + name?: string; + /** 澶囨敞 */ + remark?: string; + /** 鏄惁閫変腑 */ + isChecked?: boolean; } interface PagedListQueryPageModel { @@ -568,10 +885,28 @@ order?: EnumPagedListOrder; } + interface PagedListQueryResultGetDictionaryCategoriesQueryResultItem { + pageModel?: PagedListQueryResultPageModel; + /** 鏁版嵁 */ + data?: GetDictionaryCategoriesQueryResultItem[]; + } + interface PagedListQueryResultGetDictionaryDatasQueryResultItem { pageModel?: PagedListQueryResultPageModel; /** 鏁版嵁 */ data?: GetDictionaryDatasQueryResultItem[]; + } + + interface PagedListQueryResultGetEnterprisesQueryResultItem { + pageModel?: PagedListQueryResultPageModel; + /** 鏁版嵁 */ + data?: GetEnterprisesQueryResultItem[]; + } + + interface PagedListQueryResultGetOperationUserInfosQueryResultItem { + pageModel?: PagedListQueryResultPageModel; + /** 鏁版嵁 */ + data?: GetOperationUserInfosQueryResultItem[]; } interface PagedListQueryResultGetRolesQueryResultItem { @@ -607,6 +942,46 @@ accessToken?: string; /** 鍒锋柊浠ょ墝 */ refreshToken?: string; + } + + interface SaveDictionaryCategoryCommand { + /** Id */ + id?: string; + /** 缂栧彿 */ + code: string; + /** 鍚嶇О */ + name: string; + /** 瀛楁鍚嶏紙閫楀彿闅斿紑锛� */ + fieldNames?: string; + /** 鎺掑簭 */ + sort?: number; + } + + interface SaveDictionaryDataCommand { + /** Id */ + id?: string; + /** 绫诲埆Id */ + categoryId?: string; + /** 涓婄骇Id */ + parentId?: string; + /** 缂栧彿 */ + code?: string; + /** 鏄剧ず鍐呭 */ + content: string; + /** 瀛楁1 */ + field1?: string; + /** 瀛楁2 */ + field2?: string; + /** 瀛楁3 */ + field3?: string; + /** 瀛楁4 */ + field4?: string; + /** 瀛楁5 */ + field5?: string; + /** 鎺掑簭 */ + sort?: number; + /** 鏄惁绂佺敤 */ + isDisabled?: boolean; } interface SaveMenuButtonCommand { @@ -750,6 +1125,30 @@ resources?: GetRoleQueryResultResource[]; } + interface SelectQueryResultOptionGuidGetDictionaryCategorySelectQueryOption { + /** 鍊� */ + value?: string; + /** 鏍囩 */ + label?: string; + /** 鏁版嵁 */ + data?: any; + } + + interface SelectQueryResultOptionGuidGetDictionaryDataSelectQueryResultOption { + /** 鍊� */ + value?: string; + /** 鏍囩 */ + label?: string; + /** 鏁版嵁 */ + data?: any; + } + + interface SetDictionaryDataIsDisabledCommand { + ids?: string[]; + /** 鏄惁宸茬鐢� */ + isDisabled?: boolean; + } + interface SetMenuSwitchCommand { /** Id */ ids?: string[]; @@ -759,4 +1158,30 @@ /** 鏄惁缂撳瓨锛坣ull鏃朵笉鏇存柊锛� */ isCache?: boolean; } + + interface SetRoleIsDisabledCommand { + ids?: string[]; + /** 鏄惁宸茬鐢� */ + isDisabled?: boolean; + } + + interface SetRoleUserInfosCommand { + /** 瑙掕壊Id */ + roleId?: string; + /** 鐢ㄦ埛Id */ + userInfoIds?: string[]; + } + + interface SetUserInfoRolesCommand { + /** 鐢ㄦ埛Id */ + userInfoId?: string; + /** 瑙掕壊Id */ + roleIds?: string[]; + } + + interface SetUserInfoStatusCommand { + /** Id */ + ids?: string[]; + status?: EnumUserInfoStatus; + } } diff --git a/src/services/api/userInfo.ts b/src/services/api/userInfo.ts new file mode 100644 index 0000000..4367d18 --- /dev/null +++ b/src/services/api/userInfo.ts @@ -0,0 +1,66 @@ +/* eslint-disable */ +// @ts-ignore +import { request } from '@/utils/request'; + +/** 鏌ヨ杩愯惀绔敤鎴峰垎椤靛垪琛ㄦ暟鎹� POST /api/user/userInfo/getOperationUserInfos */ +export async function getOperationUserInfos( + body: API.GetOperationUserInfosQuery, + options?: API.RequestConfig +) { + return request<API.PagedListQueryResultGetOperationUserInfosQueryResultItem>( + '/api/user/userInfo/getOperationUserInfos', + { + method: 'POST', + headers: { + 'Content-Type': 'application/json-patch+json', + }, + data: body, + ...(options || {}), + } + ); +} + +/** 鏌ヨ鐢ㄦ埛瑙掕壊鍒楄〃 GET /api/user/userInfo/getUserInfoRoles */ +export async function getUserInfoRoles( + // 鍙犲姞鐢熸垚鐨凱aram绫诲瀷 (闈瀊ody鍙傛暟swagger榛樿娌℃湁鐢熸垚瀵硅薄) + params: API.APIgetUserInfoRolesParams, + options?: API.RequestConfig +) { + return request<API.GetUserInfoRolesQueryResultItem[]>('/api/user/userInfo/getUserInfoRoles', { + method: 'GET', + params: { + ...params, + }, + ...(options || {}), + }); +} + +/** 璁剧疆鐢ㄦ埛淇℃伅瑙掕壊 PUT /api/user/userInfo/setUserInfoRoles */ +export async function setUserInfoRoles( + body: API.SetUserInfoRolesCommand, + options?: API.RequestConfig +) { + return request<number>('/api/user/userInfo/setUserInfoRoles', { + method: 'PUT', + headers: { + 'Content-Type': 'application/json-patch+json', + }, + data: body, + ...(options || {}), + }); +} + +/** 璁剧疆鐢ㄦ埛淇℃伅鐘舵�� PUT /api/user/userInfo/setUserInfoStatus */ +export async function setUserInfoStatus( + body: API.SetUserInfoStatusCommand, + options?: API.RequestConfig +) { + return request<number>('/api/user/userInfo/setUserInfoStatus', { + method: 'PUT', + headers: { + 'Content-Type': 'application/json-patch+json', + }, + data: body, + ...(options || {}), + }); +} diff --git a/src/utils/common/common.ts b/src/utils/common/common.ts index b05dfc3..374c3a8 100644 --- a/src/utils/common/common.ts +++ b/src/utils/common/common.ts @@ -106,3 +106,12 @@ export function filterNumbersFromString(str: string) { return str.replace(/\D/g, ''); } + +export function formatRoleName(roleName: string) { + let lastUnderscoreIndex = roleName.lastIndexOf('_'); + + if (lastUnderscoreIndex !== -1) { + roleName = roleName.substring(0, lastUnderscoreIndex); + } + return roleName; +} diff --git a/src/views/DictionaryManage/DataDictionary.vue b/src/views/DictionaryManage/DataDictionary.vue index 782f4d8..de06a45 100644 --- a/src/views/DictionaryManage/DataDictionary.vue +++ b/src/views/DictionaryManage/DataDictionary.vue @@ -5,26 +5,15 @@ <template #query> <QueryFilterItem> <FieldSelect - v-model="extraParamState.searchType" + v-model="extraParamState.categoryId" @change="getList()" - :value-enum="SearchTypeText" + :value-enum="dictionaryCategoryList" placeholder="璇烽�夋嫨鎵�灞炵被鍒�" - ></FieldSelect> - </QueryFilterItem> - <QueryFilterItem v-if="extraParamState.searchType === SearchType.Position"> - <FieldSelect - v-model="extraParamState.parentId" - @change="getList()" - :value-enum="typeList" - enum-label-key="name" - enum-value-key="id" - placeholder="璇烽�夋嫨琛屼笟绫诲瀷" - clearable ></FieldSelect> </QueryFilterItem> <QueryFilterItem> <SearchInput - v-model="extraParamState.name" + v-model="extraParamState.keywords" style="width: 200px" placeholder="璇疯緭鍏ュ悕绉�" @on-click-search="getList" @@ -44,19 +33,22 @@ </template> </ProTableQueryFilterBar> <ProTableV2 v-bind="proTableProps" :columns="column" :operationBtns="operationBtns"> - <template #columns="{ row, column }"> - <template v-if="column.property === 'status'"> - <FieldSwitch - v-model="row.status" - active-text="鏄剧ず" - inactive-text="闅愯棌" - :before-change="() => setCategoryVis(row)" - /> - </template> + <template #isDisabled="{ row }"> + <FieldSwitch + v-model="row.isDisabled" + active-text="鍚敤" + inactive-text="绂佺敤" + :active-value="false" + :inactive-value="true" + :before-change="() => setCategoryVis(row)" + /> + </template> + <template #category="{ row }"> + {{ row.category?.name }} </template> </ProTableV2> </AppContainer> - <AddOrEditSearchSetting v-bind="dialogProps" :typeList="typeList" /> + <AddOrEditDictionaryDialog v-bind="dialogProps" /> </LoadingLayout> </template> @@ -74,20 +66,13 @@ UploadUserFile, FieldSwitch, FieldSelect, - FieldRadio, } from '@bole-core/components'; -import { useAccess } from '@/hooks'; -import { - SearchType, - SearchTypeText, - // BelongType, - // BelongTypeText, - BooleanOptions, -} from '@/constants'; -import { OrderInputType, Message } from '@bole-core/core'; -import AddOrEditSearchSetting from './components/AddOrEditSearchSetting.vue'; -import { convertApi2FormUrl } from '@/utils'; -import { useQueryClient } from '@tanstack/vue-query'; +import { useAccess, useDictionaryDataSelect, useGetDictionaryCategorySelect } from '@/hooks'; +import { Message } from '@bole-core/core'; +import AddOrEditDictionaryDialog from './components/AddOrEditDictionaryDialog.vue'; +import { convertApi2FormUrl, convertApi2FormUrlOnlyOne } from '@/utils'; +import * as dictionaryServices from '@/services/api/dictionary'; +import { CategoryCode } from '@/constants'; defineOptions({ name: 'DataDictionary', @@ -101,14 +86,23 @@ operationBtnMap, }); +const { dictionaryCategoryList, ensureQueryData, getDictionaryCategoryNameByCode } = + useGetDictionaryCategorySelect(); + +const { getDictionaryDataNameByCode } = useDictionaryDataSelect({ + categoryCode: CategoryCode.IndustryCategory, +}); + const BaseState = { loading: true, }; -const queryClient = useQueryClient(); -const typeList = ref([]); const state = reactive({ ...BaseState }); onMounted(async () => { + const dictionaryCategoryList = await ensureQueryData(); + if (dictionaryCategoryList.length > 0) { + extraParamState.categoryId = dictionaryCategoryList[0].value; + } await getList(); state.loading = false; }); @@ -122,23 +116,16 @@ } = useTable( async ({ pageIndex, pageSize }, extraParamState) => { try { - let params: API.GetSearchSettingListInput = { + let params: API.GetDictionaryDatasQuery = { pageModel: { rows: pageSize, page: pageIndex, orderInput: extraParamState.orderInput, }, - name: extraParamState.name, - // belongType: Number(extraParamState.belongType), - searchType: Number(extraParamState.searchType), - status: extraParamState.status, + categoryId: extraParamState.categoryId, + keywords: extraParamState.keywords, }; - - if (extraParamState.searchType === SearchType.Position) { - params.isRecommend = extraParamState.isRecommend; - params.parentId = extraParamState.parentId; - } - let res = await searchSettingServices.getSearchSettingList(params, { + let res = await dictionaryServices.getDictionaryDatas(params, { showLoading: !state.loading, }); return res; @@ -148,34 +135,38 @@ }, { defaultExtraParams: { - name: '', - searchType: SearchType.Identity, - orderInput: [{ property: 'sort', order: OrderInputType.Asc }], - status: '' as any as boolean, - isRecommend: '' as any as boolean, - parentId: '', + categoryId: '', + keywords: '', + orderInput: [{ property: 'sort', order: EnumPagedListOrder.Asc }], }, - queryKey: ['searchSettingServices/getSearchSettingList'], + queryKey: ['dictionaryServices/getDictionaryDatas'], columnsRenderProps: { - searchType: { type: 'enum', valueEnum: SearchTypeText }, + field1: { + formatter(row: API.GetDictionaryDatasQueryResultItem) { + return row.categoryCode == CategoryCode.Position + ? getDictionaryDataNameByCode(row.field1) + : ''; + }, + }, }, } ); -function openDialog(row?: API.GetSearchSettingList) { +function openDialog(row?: API.GetDictionaryDatasQueryResultItem) { if (row) { handleEdit({ id: row.id, - searchType: extraParamState.searchType, - name: row.name, + categoryId: row.categoryId, + code: row.code, + content: row.content, sort: row.sort, - status: row.status, - src: row.src?.length ? [convertApi2FormUrl(row.src)] : [], - parentId: row.parentId ?? '', + isDisabled: row.isDisabled, + field1: row.field1, + field2: convertApi2FormUrlOnlyOne(row.field2), }); } else { handleAdd({ - searchType: extraParamState.searchType, + categoryId: extraParamState.categoryId, }); } } @@ -184,55 +175,47 @@ onConfirm: handleAddOrEdit, defaultFormParams: { id: '', - searchType: SearchType.Identity, - name: '', + categoryId: '', + code: '', + content: '', sort: 0, - status: true, - src: [] as UploadUserFile[], - parentId: '', + isDisabled: false, + field1: '', + field2: [] as UploadUserFile[], }, }); async function handleAddOrEdit() { try { - let params: API.CreateOrEditSearchInput = { - searchType: extraParamState.searchType, - name: editForm.name, + let params: API.SaveDictionaryDataCommand = { + categoryId: editForm.categoryId, + code: editForm.code, sort: editForm.sort, - status: editForm.status, - src: editForm.src?.[0]?.path ?? '', - parentId: editForm.parentId ?? '', + content: editForm.content, + isDisabled: editForm.isDisabled, + field1: editForm.field1, + field2: editForm.field2?.[0]?.path ?? '', }; if (editForm.id) { params.id = editForm.id; } - let res = await searchSettingServices.createOrEditSearchSetting(params); + let res = await dictionaryServices.saveDictionaryData(params); if (res) { Message.successMessage('鎿嶄綔鎴愬姛'); getList(paginationState.pageIndex); dialogState.dialogVisible = false; - updateCategoryMenu(); } } catch (error) {} } -function updateCategoryMenu() { - queryClient.invalidateQueries({ - queryKey: [ - 'searchSettingServices/getTypeSearchSettingList', - { searchType: extraParamState.searchType, belongType: null }, - ], - }); -} - -async function setCategoryVis(row: API.GetSearchSettingList) { +async function setCategoryVis(row: API.GetDictionaryDatasQueryResultItem) { try { - let params: API.EnableSearchSettingInput = { - id: row.id, - status: !row.status, + await Message.tipMessage(`纭瑕�${row.isDisabled ? '鍚敤' : '绂佺敤'}鍚楋紵`); + let params: API.SetDictionaryDataIsDisabledCommand = { + ids: [row.id], + isDisabled: !row.isDisabled, }; - let res = await searchSettingServices.enableSearchSetting(params); - updateCategoryMenu(); + let res = await dictionaryServices.setDictionaryDataIsDisabled(params); getList(paginationState.pageIndex); return !!res; } catch (error) {} diff --git a/src/views/DictionaryManage/DictionaryCategoryManage.vue b/src/views/DictionaryManage/DictionaryCategoryManage.vue new file mode 100644 index 0000000..b110d7b --- /dev/null +++ b/src/views/DictionaryManage/DictionaryCategoryManage.vue @@ -0,0 +1,165 @@ +<template> + <LoadingLayout :loading="state.loading"> + <AppContainer> + <ProTableQueryFilterBar @on-reset="reset"> + <template #query> + <QueryFilterItem> + <SearchInput + v-model="extraParamState.keywords" + style="width: 200px" + placeholder="鍚嶇О/缂栧彿" + @on-click-search="getList" + @keyup.enter="getList()" + > + </SearchInput> + </QueryFilterItem> + </template> + <template #btn> + <el-button + v-if="checkSubModuleItemShow('pageButton', 'addBtn')" + @click="openDialog()" + icon="Plus" + type="primary" + >鏂板</el-button + > + </template> + </ProTableQueryFilterBar> + <ProTableV2 v-bind="proTableProps" :columns="column" :operationBtns="operationBtns"> + </ProTableV2> + </AppContainer> + <AddOrEditDictionaryCategory v-bind="dialogProps" /> + </LoadingLayout> +</template> + +<script setup lang="ts"> +import { + ProTableQueryFilterBar, + OperationBtnType, + ProTableV2, + SearchInput, + LoadingLayout, + AppContainer, + QueryFilterItem, + useTable, + useFormDialog, +} from '@bole-core/components'; +import { useAccess } from '@/hooks'; +import { Message } from '@bole-core/core'; +import AddOrEditDictionaryCategory from './components/AddOrEditDictionaryCategory.vue'; +import { useQueryClient } from '@tanstack/vue-query'; +import * as dictionaryServices from '@/services/api/dictionary'; + +defineOptions({ + name: 'DictionaryCategoryManage', +}); + +const operationBtnMap: Record<string, OperationBtnType> = { + editBtn: { emits: { onClick: (role) => openDialog(role) } }, + delBtn: { emits: { onClick: (role) => handleDel(role) }, props: { type: 'danger' } }, +}; + +const { checkSubModuleItemShow, column, operationBtns } = useAccess({ + operationBtnMap, +}); + +const BaseState = { + loading: true, +}; +const state = reactive({ ...BaseState }); + +onMounted(async () => { + await getList(); + state.loading = false; +}); + +const { + getDataSource: getList, + proTableProps, + paginationState, + extraParamState, + reset, +} = useTable( + async ({ pageIndex, pageSize }, extraParamState) => { + try { + let params: API.GetDictionaryCategoriesQuery = { + pageModel: { + rows: pageSize, + page: pageIndex, + orderInput: extraParamState.orderInput, + }, + keywords: extraParamState.keywords, + }; + let res = await dictionaryServices.getDictionaryCategories(params, { + showLoading: !state.loading, + }); + return res; + } catch (error) { + console.log('error: ', error); + } + }, + { + defaultExtraParams: { + keywords: '', + orderInput: [{ property: 'sort', order: EnumPagedListOrder.Asc }], + }, + queryKey: ['dictionaryServices/getDictionaryCategories'], + columnsRenderProps: {}, + } +); + +function openDialog(row?: API.GetDictionaryCategoriesQueryResultItem) { + if (row) { + handleEdit({ + id: row.id, + name: row.name, + sort: row.sort, + code: row.code, + fieldNames: row.fieldNames, + }); + } else { + handleAdd(); + } +} + +const { dialogProps, handleAdd, handleEdit, editForm } = useFormDialog({ + onConfirm: handleAddOrEdit, + defaultFormParams: { + id: '', + name: '', + code: '', + fieldNames: '', + sort: 0, + }, +}); + +async function handleAddOrEdit() { + try { + let params: API.SaveDictionaryCategoryCommand = { + code: editForm.code, + name: editForm.name, + sort: editForm.sort, + fieldNames: editForm.fieldNames, + }; + if (editForm.id) { + params.id = editForm.id; + } + let res = await dictionaryServices.saveDictionaryCategory(params); + if (res) { + Message.successMessage('鎿嶄綔鎴愬姛'); + getList(paginationState.pageIndex); + } + } catch (error) {} +} + +async function handleDel(row: API.GetDictionaryCategoriesQueryResultItem) { + try { + await Message.tipMessage('纭瑕佸垹闄よ绫诲埆鍚楋紵'); + let params: API.DeleteDictionaryCategoryCommand = { ids: [row.id] }; + let res = await dictionaryServices.deleteDictionaryCategory(params); + if (res) { + Message.successMessage('鎿嶄綔鎴愬姛'); + getList(paginationState.pageIndex); + } + } catch (error) {} +} +</script> diff --git a/src/views/DictionaryManage/components/AddOrEditDictionaryCategory.vue b/src/views/DictionaryManage/components/AddOrEditDictionaryCategory.vue new file mode 100644 index 0000000..021d6e4 --- /dev/null +++ b/src/views/DictionaryManage/components/AddOrEditDictionaryCategory.vue @@ -0,0 +1,90 @@ +<template> + <ProDialog + :title="`${title}绫诲埆`" + v-model="visible" + @close="onDialogClose" + destroy-on-close + draggable + > + <ProForm :model="form" ref="dialogForm" label-width="90px"> + <ProFormItemV2 label="鍚嶇О:" prop="name" :check-rules="[{ message: '璇疯緭鍏ュ悕绉�' }]"> + <ProFormText + placeholder="璇疯緭鍏ュ悕绉�" + v-model.trim="form.name" + :maxlength="15" + ></ProFormText> + </ProFormItemV2> + <ProFormItemV2 label="缂栧彿:" prop="code"> + <ProFormText placeholder="璇疯緭鍏ョ紪鍙�" v-model.trim="form.code"></ProFormText> + </ProFormItemV2> + <ProFormItemV2 label="瀛楁鍚�:" prop="fieldNames"> + <ProFormText placeholder="璇疯緭鍏ョ紪鍙�" v-model.trim="form.fieldNames"></ProFormText> + </ProFormItemV2> + <ProFormItemV2 label="鎺掑簭:" prop="sort"> + <ProFormInputNumber + v-model="form.sort" + :controls="false" + :min="0" + :max="999999" + ></ProFormInputNumber> + </ProFormItemV2> + </ProForm> + <template #footer> + <span class="dialog-footer"> + <el-button @click="emit('onCancel')">鍙� 娑�</el-button> + <el-button type="primary" @click="handleConfirm">纭� 瀹�</el-button> + </span> + </template> + </ProDialog> +</template> + +<script setup lang="ts"> +import { FormInstance } from 'element-plus'; +import { + ProDialog, + ProForm, + ProFormItemV2, + ProFormText, + ProFormInputNumber, +} from '@bole-core/components'; + +defineOptions({ + name: 'AddOrEditDictionaryCategory', +}); + +type Form = { + id?: string; + name: string; + sort: number; + code: string; + fieldNames: string; +}; + +const form = defineModel<Form>('form'); +const visible = defineModel<boolean>('modelValue'); + +const title = computed(() => (form.value.id ? '缂栬緫' : '鏂板')); + +const emit = defineEmits<{ + (e: 'onConfirm'): void; + (e: 'onCancel'): void; +}>(); + +const dialogForm = ref<FormInstance>(); + +function onDialogClose() { + if (!dialogForm.value) return; + dialogForm.value.resetFields(); +} + +function handleConfirm() { + if (!dialogForm.value) return; + dialogForm.value.validate((valid) => { + if (valid) { + emit('onConfirm'); + } else { + return; + } + }); +} +</script> diff --git a/src/views/DictionaryManage/components/AddOrEditDictionaryDialog.vue b/src/views/DictionaryManage/components/AddOrEditDictionaryDialog.vue new file mode 100644 index 0000000..9784ece --- /dev/null +++ b/src/views/DictionaryManage/components/AddOrEditDictionaryDialog.vue @@ -0,0 +1,142 @@ +<template> + <ProDialog + :title="`${title}绫诲埆`" + v-model="visible" + @close="onDialogClose" + destroy-on-close + draggable + > + <ProForm :model="form" ref="dialogForm" label-width="90px"> + <ProFormItemV2 + label="琛屼笟绫诲瀷:" + prop="field1" + v-if="category?.data?.code === '30'" + :check-rules="[{ message: '璇烽�夋嫨琛屼笟绫诲瀷' }]" + > + <ProFormSelect + v-model="form.field1" + :value-enum="dictionaryDataList" + enum-value-key="code" + /> + </ProFormItemV2> + <ProFormItemV2 label="鍚嶇О:" prop="content" :check-rules="[{ message: '璇疯緭鍏ュ悕绉�' }]"> + <ProFormText + placeholder="璇疯緭鍏ュ悕绉�" + v-model.trim="form.content" + :maxlength="15" + ></ProFormText> + </ProFormItemV2> + <ProFormItemV2 label="鎺掑簭:" prop="sort"> + <ProFormInputNumber + v-model="form.sort" + :controls="false" + :min="0" + :max="999999" + ></ProFormInputNumber> + </ProFormItemV2> + <ProFormItemV2 label="缂栧彿:" prop="code"> + <ProFormText v-model.trim="form.code"></ProFormText> + </ProFormItemV2> + <ProFormItemV2 label="鍥剧墖:" prop="src" v-if="category?.data?.code === '50'"> + <ProFormImageUpload v-model:file-url="form.field2" :limitFileCount="1"></ProFormImageUpload> + </ProFormItemV2> + <ProFormItemV2 label="鐘舵��:" prop="status"> + <ProFormRadio + v-model="form.isDisabled" + :value-enum="[ + { label: '鍚敤', value: false }, + { label: '绂佺敤', value: true }, + ]" + ></ProFormRadio> + </ProFormItemV2> + </ProForm> + <template #footer> + <span class="dialog-footer"> + <el-button @click="emit('onCancel')">鍙� 娑�</el-button> + <el-button type="primary" @click="handleConfirm">纭� 瀹�</el-button> + </span> + </template> + </ProDialog> +</template> + +<script setup lang="ts"> +import { FormInstance } from 'element-plus'; +import { + ProDialog, + ProForm, + ProFormItemV2, + ProFormText, + ProFormInputNumber, + ProFormSelect, + ProFormRadio, + UploadUserFile, + ProFormImageUpload, +} from '@bole-core/components'; +import { useDictionaryDataSelect, useGetDictionaryCategorySelect } from '@/hooks'; +import { CategoryCode } from '@/constants'; + +defineOptions({ + name: 'AddOrEditDictionaryDialog', +}); + +type Form = { + id?: string; + categoryId: string; + content: string; + code: string; + sort: number; + isDisabled: boolean; + field1?: string; + field2?: UploadUserFile[]; +}; + +const form = defineModel<Form>('form'); +const visible = defineModel<boolean>('modelValue'); + +const title = computed(() => (form.value.id ? '缂栬緫' : '鏂板')); + +const { getDictionaryCategoryById } = useGetDictionaryCategorySelect(); + +const { dictionaryDataList, refetch, getDictionaryDataNameById } = useDictionaryDataSelect({ + categoryCode: computed(() => CategoryCode.IndustryCategory), +}); + +const category = computed(() => { + return getDictionaryCategoryById(form.value.categoryId); +}); + +watch( + () => visible.value, + (value) => { + if (value) { + refetch(); + } + }, + { + immediate: true, + } +); + +const emit = defineEmits<{ + (e: 'onConfirm'): void; + (e: 'onCancel'): void; +}>(); + +const dialogForm = ref<FormInstance>(); + +function onDialogClose() { + if (!dialogForm.value) return; + dialogForm.value.resetFields(); +} + +function handleConfirm() { + if (!dialogForm.value) return; + dialogForm.value.validate((valid) => { + if (valid) { + emit('onConfirm'); + } else { + return; + } + }); +} +</script> diff --git a/src/views/DictionaryManage/components/AddOrEditSearchSetting.vue b/src/views/DictionaryManage/components/AddOrEditSearchSetting.vue deleted file mode 100644 index 1eab56d..0000000 --- a/src/views/DictionaryManage/components/AddOrEditSearchSetting.vue +++ /dev/null @@ -1,147 +0,0 @@ -<template> - <ProDialog - :title="innerForm.title" - v-model="innerVisible" - @close="onDialogClose" - destroy-on-close - draggable - > - <ProForm :rules="rules" :model="innerForm" ref="dialogForm" label-width="90px"> - <ProFormItemV2 label="琛屼笟绫诲瀷:" prop="parentId" v-if="showWorkSearchType"> - <ProFormSelect - v-model="innerForm.parentId" - :value-enum="typeList" - enum-value-key="id" - enum-label-key="name" - /> - </ProFormItemV2> - <ProFormItemV2 label="鍚嶇О:" prop="name"> - <ProFormText - placeholder="璇疯緭鍏ュ悕绉�" - v-model.trim="innerForm.name" - :maxlength="15" - ></ProFormText> - </ProFormItemV2> - <ProFormItemV2 label="鎺掑簭:" prop="sort" required> - <ProFormInputNumber - v-model="innerForm.sort" - :controls="false" - :min="0" - :max="999" - ></ProFormInputNumber> - </ProFormItemV2> - <ProFormItemV2 - label="绫诲埆鍥炬爣:" - prop="src" - :check-rules="[{ type: 'upload', required: false }]" - > - <ProFormImageUpload - v-model:file-url="innerForm.src" - :limitFileCount="1" - ></ProFormImageUpload> - </ProFormItemV2> - <ProFormItemV2 label="鐘舵��:" prop="status" required> - <el-radio-group v-model="innerForm.status"> - <el-radio-button :value="true">鏄剧ず</el-radio-button> - <el-radio-button :value="false">闅愯棌</el-radio-button> - </el-radio-group> - </ProFormItemV2> - </ProForm> - <template #footer> - <span class="dialog-footer"> - <el-button @click="emit('onCancel')">鍙� 娑�</el-button> - <el-button type="primary" @click="handleConfirm">纭� 瀹�</el-button> - </span> - </template> - </ProDialog> -</template> - -<script setup lang="ts"> -import { FormRules, FormInstance } from 'element-plus'; -import { SearchType } from '@/constants'; -import { - ProDialog, - ProForm, - ProFormItemV2, - ProFormRadio, - ProFormText, - ProFormInputNumber, - ProFormImageUpload, - UploadUserFile, - ProFormSelect, -} from '@bole-core/components'; - -defineOptions({ - name: 'AddOrEditSearchSetting', -}); - -type Props = { - modelValue: boolean; - form?: { - title?: string; - searchType: number; - name: string; - sort: number; - status: boolean; - src: UploadUserFile[]; - parentId?: string; - }; - typeList: API.GetTypeSearchSettingList[]; -}; - -const props = withDefaults(defineProps<Props>(), { - modelValue: false, -}); - -const showWorkSearchType = computed(() => props.form.searchType === SearchType.Position); - -const emit = defineEmits<{ - (e: 'update:modelValue', value: boolean): void; - (e: 'update:form', value: Props['form']): void; - (e: 'onConfirm'): void; - (e: 'onCancel'): void; -}>(); - -const dialogForm = ref<FormInstance>(); - -const innerVisible = computed({ - get() { - return props.modelValue; - }, - set(val) { - emit('update:modelValue', val); - }, -}); - -const innerForm = computed({ - get() { - return props.form; - }, - set(val) { - emit('update:form', val); - }, -}); - -const rules = reactive<FormRules>({ - status: [{ required: true, message: '璇烽�夋嫨鐘舵��', trigger: 'change' }], - name: [{ required: true, message: '璇疯緭鍏ュ悕绉�', trigger: 'blur' }], - sort: [{ required: true, message: '璇疯緭鍏ユ帓搴�', trigger: 'blur' }], - parentId: [{ required: true, message: '璇烽�夋嫨鎵�灞炵被鍒�', trigger: 'change' }], -}); - -function onDialogClose() { - if (!dialogForm.value) return; - dialogForm.value.resetFields(); -} - -function handleConfirm() { - if (!dialogForm.value) return; - dialogForm.value.validate((valid) => { - if (valid) { - emit('onConfirm'); - } else { - return; - } - }); -} -</script> diff --git a/src/views/Permission/OperationUserManage.vue b/src/views/Permission/OperationUserManage.vue new file mode 100644 index 0000000..a008812 --- /dev/null +++ b/src/views/Permission/OperationUserManage.vue @@ -0,0 +1,175 @@ +<template> + <LoadingLayout :loading="state.loading"> + <AppContainer> + <ProTableQueryFilterBar @on-reset="reset"> + <template #query> + <QueryFilterItem> + <SearchInput + v-model="extraParamState.keywords" + style="width: 200px" + placeholder="瑙掕壊鍚嶇О" + @on-click-search="getList" + @keyup.enter="getList()" + > + </SearchInput> + </QueryFilterItem> + </template> + </ProTableQueryFilterBar> + <ProTableV2 v-bind="proTableProps" :columns="column" :operationBtns="operationBtns"> + <template #roles="{ row }"> + {{ row.roles?.map((x) => formatRoleName(x.name)).join() }} + </template> + <template #status="{ row }"> + <FieldSwitch + v-model="row.status" + active-text="鍚敤" + inactive-text="绂佺敤" + :active-value="EnumUserInfoStatus.Normal" + :inactive-value="EnumUserInfoStatus.Disabled" + :before-change="() => setStatus(row)" + /> + </template> + </ProTableV2> + </AppContainer> + <SetOperationUserRoleDialog v-bind="dialogProps" /> + </LoadingLayout> +</template> + +<script setup lang="ts"> +import { + ProTableQueryFilterBar, + OperationBtnType, + ProTableV2, + SearchInput, + LoadingLayout, + AppContainer, + QueryFilterItem, + useTable, + FieldSwitch, + useFormDialog, +} from '@bole-core/components'; +import { useAccess } from '@/hooks'; +import { formatRoleName } from '@/utils'; +import * as userInfoServices from '@/services/api/userInfo'; +import { Message } from '@bole-core/core'; +import { EnumUserInfoStatus } from '@/constants'; +import SetOperationUserRoleDialog from './components/SetOperationUserRoleDialog.vue'; + +defineOptions({ + name: 'OperationUserManage', +}); + +const operationBtnMap: Record<string, OperationBtnType> = { + setRoleBtn: { emits: { onClick: (role) => openDialog(role) } }, +}; + +const { checkSubModuleItemShow, column, operationBtns } = useAccess({ + operationBtnMap, +}); + +const BaseState = { + loading: true, +}; + +const state = reactive({ ...BaseState }); + +onMounted(async () => { + await getList(); + state.loading = false; +}); + +const { + getDataSource: getList, + proTableProps, + paginationState, + extraParamState, + reset, +} = useTable( + async ({ pageIndex, pageSize }, extraParamState) => { + try { + let params: API.GetOperationUserInfosQuery = { + pageModel: { + rows: pageSize, + page: pageIndex, + orderInput: extraParamState.orderInput, + }, + keywords: extraParamState.keywords, + }; + let res = await userInfoServices.getOperationUserInfos(params, { + showLoading: !state.loading, + }); + return res; + } catch (error) {} + }, + { + defaultExtraParams: { + keywords: '', + orderInput: [{ property: 'id', order: EnumPagedListOrder.Desc }], + }, + queryKey: ['userInfoServices/getOperationUserInfos'], + columnsRenderProps: {}, + } +); + +async function setStatus(row: API.GetOperationUserInfosQueryResultItem) { + try { + await Message.tipMessage( + `纭瑕�${row.status === EnumUserInfoStatus.Normal ? '绂佺敤' : '鍚敤'}璇ヨ处鍙峰悧锛焋 + ); + let params: API.SetUserInfoStatusCommand = { + ids: [row.id], + status: + row.status === EnumUserInfoStatus.Normal + ? EnumUserInfoStatus.Disabled + : EnumUserInfoStatus.Normal, + }; + let res = await userInfoServices.setUserInfoStatus(params); + return !!res; + } catch (error) {} +} + +const { dialogProps, handleEdit, editForm } = useFormDialog({ + onConfirm: setUserInfoRoles, + defaultFormParams: { + roleIds: [] as string[], + userInfoId: '', + roles: [] as API.GetOperationUserInfosQueryResultItem[], + }, +}); + +async function openDialog(row?: API.GetOperationUserInfosQueryResultItem) { + if (row) { + const roles = await getUserInfoRoles(row); + handleEdit({ + userInfoId: row.id, + roleIds: row.roles?.map((x) => x.id), + roles: roles, + }); + } +} + +async function setUserInfoRoles() { + try { + let params: API.SetUserInfoRolesCommand = { + userInfoId: editForm.userInfoId, + roleIds: editForm.roleIds, + }; + let res = await userInfoServices.setUserInfoRoles(params); + if (res) { + Message.successMessage('鎿嶄綔鎴愬姛'); + getList(paginationState.pageIndex); + } + } catch (error) {} +} + +async function getUserInfoRoles(row: API.GetOperationUserInfosQueryResultItem) { + try { + let params: API.APIgetUserInfoRolesParams = { + userInfoId: row.id, + // clientType: row.clientType, + }; + let res = await userInfoServices.getUserInfoRoles(params); + return res; + } catch (error) {} +} +</script> diff --git a/src/views/Permission/components/SetOperationUserRoleDialog.vue b/src/views/Permission/components/SetOperationUserRoleDialog.vue new file mode 100644 index 0000000..05a104a --- /dev/null +++ b/src/views/Permission/components/SetOperationUserRoleDialog.vue @@ -0,0 +1,61 @@ +<template> + <ProDialog title="璁剧疆瑙掕壊" v-model="visible" @close="onDialogClose" destroy-on-close draggable> + <ProForm :model="form" ref="dialogForm" label-width="90px"> + <ProFormItemV2 label="瑙掕壊" prop="roleIds" :check-rules="[{ message: '璇烽�夋嫨瑙掕壊' }]"> + <ProFormCheckbox + v-model="form.roleIds" + :value-enum="form.roles" + enumLabelKey="name" + enum-value-key="id" + ></ProFormCheckbox> + </ProFormItemV2> + </ProForm> + <template #footer> + <span class="dialog-footer"> + <el-button @click="emit('onCancel')">鍙� 娑�</el-button> + <el-button type="primary" @click="handleConfirm">纭� 瀹�</el-button> + </span> + </template> + </ProDialog> +</template> + +<script setup lang="ts"> +import { FormInstance } from 'element-plus'; +import { ProDialog, ProForm, ProFormItemV2, ProFormCheckbox } from '@bole-core/components'; + +defineOptions({ + name: 'SetOperationUserRoleDialog', +}); + +type Form = { + userInfoId: string; + roleIds: string[]; + roles: API.GetOperationUserInfosQueryResultItem[]; +}; + +const form = defineModel<Form>('form'); +const visible = defineModel({ type: Boolean }); + +const emit = defineEmits<{ + (e: 'onConfirm'): void; + (e: 'onCancel'): void; +}>(); + +const dialogForm = ref<FormInstance>(); + +function onDialogClose() { + if (!dialogForm.value) return; + dialogForm.value.resetFields(); +} + +function handleConfirm() { + if (!dialogForm.value) return; + dialogForm.value.validate((valid) => { + if (valid) { + emit('onConfirm'); + } else { + return; + } + }); +} +</script> diff --git a/src/views/System/ModuleManage.vue b/src/views/System/ModuleManage.vue index 5a20161..217df8b 100644 --- a/src/views/System/ModuleManage.vue +++ b/src/views/System/ModuleManage.vue @@ -556,17 +556,32 @@ if (drawerState.type === SubModuleType.Column) { let columnModuleList = drawerState.tableData; //.filter((d) => d.isEdit); if (columnModuleList.length > 0) { - const groups = currentDrawerModule.value.groups.map((group) => { - if (group.group === state.group) { - group.fields = columnModuleList.map((c) => ({ + let groups = [...currentDrawerModule.value.groups]; + const isExist = groups.some((g) => g.group === state.group); + if (isExist) { + groups = groups.map((group) => { + if (group.group === state.group) { + group.fields = columnModuleList.map((c) => ({ + code: c.enCode, + name: c.name, + width: c.width, + sort: c.sortCode, + })); + } + return group; + }); + } else { + const group: API.GetMenuQueryResultGroup = { + group: state.group, + fields: columnModuleList.map((c) => ({ code: c.enCode, name: c.name, width: c.width, sort: c.sortCode, - })); - } - return group; - }); + })), + }; + groups.push(group); + } let params: API.SaveMenuCommand = { ...currentDrawerModule.value, groups: groups, diff --git a/types/api.d.ts b/types/api.d.ts index 1061075..bfb7903 100644 --- a/types/api.d.ts +++ b/types/api.d.ts @@ -14,5 +14,17 @@ customErrorHandler?: (error: any) => boolean; } + interface SelectQueryResultOptionGuidGetDictionaryCategorySelectQueryOptionMap{ + field1?:string + } + + interface SelectQueryResultOptionGuidGetDictionaryCategorySelectQueryOption{ + fieldNamesMap?: SelectQueryResultOptionGuidGetDictionaryCategorySelectQueryOptionMap; + code?:string + } + + interface SelectQueryResultOptionGuidGetDictionaryDataSelectQueryResultOption{ + code?:string + } } -- Gitblit v1.9.1