From c3207c8517780ec2019bd1e0943a62cc29b265d0 Mon Sep 17 00:00:00 2001
From: zhengyiming <540361168@qq.com>
Date: 星期二, 18 二月 2025 14:58:32 +0800
Subject: [PATCH] feat: api
---
src/constants/dic.ts | 23 ++
src/hooks/dic.ts | 55 ++++++
src/services/api/typings.d.ts | 1
src/constants/enum.ts | 5
src/constants/index.ts | 1
src/views/DictionaryManage/SearchSetting.vue | 244 ++++++++++++++++++++++++++++++
src/hooks/index.ts | 1
src/views/DictionaryManage/components/AddOrEditSearchSetting.vue | 147 ++++++++++++++++++
src/utils/request/index.ts | 1
9 files changed, 477 insertions(+), 1 deletions(-)
diff --git a/src/constants/dic.ts b/src/constants/dic.ts
new file mode 100644
index 0000000..3ad3406
--- /dev/null
+++ b/src/constants/dic.ts
@@ -0,0 +1,23 @@
+export enum SearchType {
+ /**韬唤 */
+ Identity = 210,
+ /**瀛﹀巻 */
+ Education = 220,
+ /**宀椾綅 */
+ Position = 230,
+ /**璇佷功绫诲瀷 */
+ CertificateType = 240,
+ /**绂忓埄 */
+ Welfare = 250,
+ /**琛屼笟绫诲瀷 */
+ IndustryCategory = 260,
+}
+
+export const SearchTypeText = {
+ [SearchType.Identity]: '韬唤',
+ [SearchType.Education]: '瀛﹀巻',
+ [SearchType.Position]: '宀椾綅',
+ [SearchType.CertificateType]: '璇佷功绫诲瀷',
+ [SearchType.Welfare]: '绂忓埄',
+ [SearchType.IndustryCategory]: '琛屼笟绫诲瀷',
+};
diff --git a/src/constants/enum.ts b/src/constants/enum.ts
index 936694e..e403f0e 100644
--- a/src/constants/enum.ts
+++ b/src/constants/enum.ts
@@ -38,3 +38,8 @@
Role = 1,
User,
}
+
+export const BooleanOptions = [
+ { label: '鏄�', value: true },
+ { label: '鍚�', value: false },
+];
diff --git a/src/constants/index.ts b/src/constants/index.ts
index fa61beb..303e5a6 100644
--- a/src/constants/index.ts
+++ b/src/constants/index.ts
@@ -9,3 +9,4 @@
export * from './menu';
export * from './role';
export * from './app';
+export * from './dic';
diff --git a/src/hooks/dic.ts b/src/hooks/dic.ts
new file mode 100644
index 0000000..d55c72f
--- /dev/null
+++ b/src/hooks/dic.ts
@@ -0,0 +1,55 @@
+import * as searchSettingServices from '@/services/api/SearchSetting';
+import { useQuery } from '@tanstack/vue-query';
+import { useQueryClient } from '@tanstack/vue-query';
+import { SearchType } from '@/constants';
+
+type UseSearchSettingTypeOptions = {
+ searchType: number;
+ belongType?: number;
+ onSuccess?: (data: API.GetTypeSearchSettingList[]) => any;
+};
+
+export function useSearchSettingType({
+ searchType,
+ belongType = null,
+ onSuccess,
+}: UseSearchSettingTypeOptions) {
+ const { data, refetch } = useQuery({
+ queryKey: ['searchSettingServices/getTypeSearchSettingList', { searchType, belongType }],
+ queryFn: async () => {
+ return await searchSettingServices.getTypeSearchSettingList(
+ {
+ searchType: searchType,
+ belongType: belongType,
+ },
+ { showLoading: false }
+ );
+ },
+ placeholderData: () => [] as API.GetTypeSearchSettingList[],
+ onSuccess(data) {
+ onSuccess?.(data);
+ },
+ });
+
+ const queryClient = useQueryClient();
+
+ async function ensureSearchSettingType() {
+ return await queryClient.ensureQueryData({
+ queryKey: [
+ 'searchSettingServices/getTypeSearchSettingList',
+ { searchType: searchType, belongType: belongType },
+ ],
+ });
+ }
+
+ function getSearchSettingTypeNameById(id: string) {
+ return data.value.find((x) => x.id === id)?.name ?? '';
+ }
+
+ return {
+ searchSettingTypeList: data,
+ ensureSearchSettingType,
+ refetchSearchSettingType: refetch,
+ getSearchSettingTypeNameById,
+ };
+}
diff --git a/src/hooks/index.ts b/src/hooks/index.ts
index cbe1cbd..bc2b519 100644
--- a/src/hooks/index.ts
+++ b/src/hooks/index.ts
@@ -6,3 +6,4 @@
export * from './useEvent';
export * from './useUser';
export * from './help';
+export * from './dic';
diff --git a/src/services/api/typings.d.ts b/src/services/api/typings.d.ts
index efb90c7..cd366cf 100644
--- a/src/services/api/typings.d.ts
+++ b/src/services/api/typings.d.ts
@@ -713,6 +713,7 @@
clickCount?: number;
src?: string;
isRecommend?: boolean;
+ searchType?: number;
}
interface GetSearchSettingListInput {
diff --git a/src/utils/request/index.ts b/src/utils/request/index.ts
index 3c654d4..3ebb819 100644
--- a/src/utils/request/index.ts
+++ b/src/utils/request/index.ts
@@ -170,7 +170,6 @@
requestInterceptors: [
[
(config) => {
- console.log('req config: ', config);
const $config = config;
// 寮�鍚繘搴︽潯鍔ㄧ敾
if (config.needNProcess) {
diff --git a/src/views/DictionaryManage/SearchSetting.vue b/src/views/DictionaryManage/SearchSetting.vue
new file mode 100644
index 0000000..a23b025
--- /dev/null
+++ b/src/views/DictionaryManage/SearchSetting.vue
@@ -0,0 +1,244 @@
+<template>
+ <LoadingLayout :loading="state.loading">
+ <AppContainer>
+ <ProTableQueryFilterBar @on-reset="reset">
+ <template #query>
+ <QueryFilterItem>
+ <FieldSelect
+ v-model="extraParamState.searchType"
+ @change="getList()"
+ :value-enum="SearchTypeText"
+ 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"
+ 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">
+ <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>
+ </ProTableV2>
+ </AppContainer>
+ <AddOrEditSearchSetting v-bind="dialogProps" :typeList="typeList" />
+ </LoadingLayout>
+</template>
+
+<script setup lang="ts">
+import {
+ ProTableQueryFilterBar,
+ OperationBtnType,
+ ProTableV2,
+ SearchInput,
+ LoadingLayout,
+ AppContainer,
+ QueryFilterItem,
+ useTable,
+ useFormDialog,
+ UploadUserFile,
+ FieldSwitch,
+ FieldSelect,
+ FieldRadio,
+} from '@bole-core/components';
+import { useAccess } from '@/hooks';
+import * as searchSettingServices from '@/services/api/SearchSetting';
+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 { useSearchSettingType } from '@/hooks';
+
+defineOptions({
+ name: 'SearchSetting',
+});
+
+const operationBtnMap: Record<string, OperationBtnType> = {
+ editBtn: { emits: { onClick: (role) => openDialog(role) } },
+};
+
+const { checkSubModuleItemShow, column, operationBtns } = useAccess({
+ operationBtnMap,
+});
+
+const BaseState = {
+ loading: true,
+};
+const queryClient = useQueryClient();
+const { searchSettingTypeList: typeList } = useSearchSettingType({
+ searchType: SearchType.IndustryCategory,
+});
+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.GetSearchSettingListInput = {
+ pageModel: {
+ rows: pageSize,
+ page: pageIndex,
+ orderInput: extraParamState.orderInput,
+ },
+ name: extraParamState.name,
+ // belongType: Number(extraParamState.belongType),
+ searchType: Number(extraParamState.searchType),
+ status: extraParamState.status,
+ };
+
+ if (extraParamState.searchType === SearchType.Position) {
+ params.isRecommend = extraParamState.isRecommend;
+ params.parentId = extraParamState.parentId;
+ }
+ let res = await searchSettingServices.getSearchSettingList(params, {
+ showLoading: !state.loading,
+ });
+ return res;
+ } catch (error) {
+ console.log('error: ', error);
+ }
+ },
+ {
+ defaultExtraParams: {
+ name: '',
+ searchType: SearchType.Identity,
+ orderInput: [{ property: 'sort', order: OrderInputType.Asc }],
+ status: '' as any as boolean,
+ isRecommend: '' as any as boolean,
+ parentId: '',
+ },
+ queryKey: ['searchSettingServices/getSearchSettingList'],
+ columnsRenderProps: {
+ searchType: { type: 'enum', valueEnum: SearchTypeText },
+ },
+ }
+);
+
+function openDialog(row?: API.GetSearchSettingList) {
+ if (row) {
+ handleEdit({
+ id: row.id,
+ searchType: extraParamState.searchType,
+ name: row.name,
+ sort: row.sort,
+ status: row.status,
+ src: row.src?.length ? [convertApi2FormUrl(row.src)] : [],
+ parentId: row.parentId ?? '',
+ });
+ } else {
+ handleAdd({
+ searchType: extraParamState.searchType,
+ });
+ }
+}
+
+const { dialogProps, handleAdd, handleEdit, editForm, dialogState } = useFormDialog({
+ onConfirm: handleAddOrEdit,
+ defaultFormParams: {
+ id: '',
+ searchType: SearchType.Identity,
+ name: '',
+ sort: 0,
+ status: true,
+ src: [] as UploadUserFile[],
+ parentId: '',
+ },
+});
+
+async function handleAddOrEdit() {
+ try {
+ let params: API.CreateOrEditSearchInput = {
+ searchType: extraParamState.searchType,
+ name: editForm.name,
+ sort: editForm.sort,
+ status: editForm.status,
+ src: editForm.src?.[0]?.path ?? '',
+ parentId: editForm.parentId ?? '',
+ };
+ if (editForm.id) {
+ params.id = editForm.id;
+ }
+ let res = await searchSettingServices.createOrEditSearchSetting(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) {
+ try {
+ let params: API.EnableSearchSettingInput = {
+ id: row.id,
+ status: !row.status,
+ };
+ let res = await searchSettingServices.enableSearchSetting(params);
+ updateCategoryMenu();
+ getList(paginationState.pageIndex);
+ return !!res;
+ } catch (error) {}
+}
+</script>
diff --git a/src/views/DictionaryManage/components/AddOrEditSearchSetting.vue b/src/views/DictionaryManage/components/AddOrEditSearchSetting.vue
new file mode 100644
index 0000000..1eab56d
--- /dev/null
+++ b/src/views/DictionaryManage/components/AddOrEditSearchSetting.vue
@@ -0,0 +1,147 @@
+<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>
--
Gitblit v1.9.1