From a2971bb8f3be26eb30302bcf4de07e12e912700c Mon Sep 17 00:00:00 2001 From: wupengfei <834520024@qq.com> Date: 星期四, 21 八月 2025 11:10:41 +0800 Subject: [PATCH] feat: 页面 --- src/views/AgreementManage/AgreementManageList.vue | 2 src/hooks/useEvent.ts | 1 src/views/ServiceChargeManage/ServiceChargeDetail.vue | 23 +- src/views/ServiceChargeManage/ServiceChargeManage.vue | 155 +++++++++++++----- src/views/ServiceChargeManage/components/SettleDetailDialog.vue | 70 ++++++++ src/views/ServiceChargeManage/components/UploadStatementDialog.vue | 99 ++++++++++++ src/views/ServiceChargeManage/ServiceChargeSettle.vue | 127 +++++++++------ 7 files changed, 370 insertions(+), 107 deletions(-) diff --git a/src/hooks/useEvent.ts b/src/hooks/useEvent.ts index f897656..b462cd4 100644 --- a/src/hooks/useEvent.ts +++ b/src/hooks/useEvent.ts @@ -6,6 +6,7 @@ 'taskManage:add': any; 'taskManage:edit': any; checkReceiveTask: any; + serviceChargeSettle: any; }; export type GlobalEventListener<T extends keyof GlobalEvent> = (payload: GlobalEvent[T]) => any; diff --git a/src/views/AgreementManage/AgreementManageList.vue b/src/views/AgreementManage/AgreementManageList.vue index c812998..cf0dfff 100644 --- a/src/views/AgreementManage/AgreementManageList.vue +++ b/src/views/AgreementManage/AgreementManageList.vue @@ -156,7 +156,7 @@ time: [] as unknown as ModelValueType, orderInput: [{ property: 'id', order: EnumPagedListOrder.Desc }], }, - queryKey: ['flexEnterpriseServices/getFlexEnterpriseList'], + queryKey: ['taskServices/getTaskInfos'], columnsRenderProps: {}, } ); diff --git a/src/views/ServiceChargeManage/ServiceChargeDetail.vue b/src/views/ServiceChargeManage/ServiceChargeDetail.vue index 97cf434..f73a96f 100644 --- a/src/views/ServiceChargeManage/ServiceChargeDetail.vue +++ b/src/views/ServiceChargeManage/ServiceChargeDetail.vue @@ -85,7 +85,7 @@ <template #query> <QueryFilterItem> <SearchInput - v-model="extraParamState.searchWord" + v-model="extraParamState.keywords" style="width: 300px" placeholder="浜哄憳濮撳悕/韬唤璇佸彿/鎵嬫満鍙�" @on-click-search="getList" @@ -134,6 +134,7 @@ import { SettlementListColumns } from './constants'; import { useQuery } from '@tanstack/vue-query'; import { downloadFileByUrl } from '@bole-core/core'; +import * as taskServices from '@/services/api/task'; defineOptions({ name: 'ServiceChargeDetail', @@ -158,17 +159,19 @@ }); const { isLoading } = useQuery({ - queryKey: ['flexTaskServices/getFlexTaskDetail', id], + queryKey: ['taskServices/getTaskInfo', id], queryFn: async () => { - return await flexTaskServices.getFlexTaskDetail( + return await taskServices.getTaskInfo( { id: id }, { showLoading: false, } ); }, - placeholderData: () => ({} as API.GetFlexTaskDetailForBackOutput), - onSuccess(data) {}, + placeholderData: () => ({} as API.GetTaskInfoQueryResult), + onSuccess(data) { + form.name = data.name; + }, enabled: !!id, }); @@ -181,16 +184,16 @@ } = useTable( async ({ pageIndex, pageSize }, extraParamState) => { try { - let params: API.GetFlexEnterpriseInput = { + let params: API.GetOpenTaskInfosQuery = { pageModel: { rows: pageSize, page: pageIndex, orderInput: extraParamState.orderInput, }, - searchWord: extraParamState.searchWord, + keywords: extraParamState.keywords, }; - let res = await flexEnterpriseServices.getFlexEnterpriseList(params); + let res = await taskServices.getOpenTaskInfos(params); return res; } catch (error) { console.log('error: ', error); @@ -198,10 +201,10 @@ }, { defaultExtraParams: { - searchWord: '', + keywords: '', orderInput: [{ property: 'id', order: EnumPagedListOrder.Desc }], }, - queryKey: ['flexEnterpriseServices/getFlexEnterpriseList'], + queryKey: ['taskServices/getOpenTaskInfos'], columnsRenderProps: {}, } ); diff --git a/src/views/ServiceChargeManage/ServiceChargeManage.vue b/src/views/ServiceChargeManage/ServiceChargeManage.vue index d9cbb15..bd7fa87 100644 --- a/src/views/ServiceChargeManage/ServiceChargeManage.vue +++ b/src/views/ServiceChargeManage/ServiceChargeManage.vue @@ -5,7 +5,7 @@ <template #query> <QueryFilterItem tip-content="缁撶畻鍗曠姸鎬�"> <FieldRadio - v-model="extraParamState.flexEnterpriseSettingStatus" + v-model="extraParamState.status" :value-enum="[ { label: '宸插畨鎺�', value: 1 }, { label: '寰呭畨鎺�', value: 0 }, @@ -17,7 +17,7 @@ </QueryFilterItem> <QueryFilterItem tip-content="缁撶畻鐘舵��"> <FieldRadio - v-model="extraParamState.flexEnterpriseSettingStatus" + v-model="extraParamState.status" :value-enum="[ { label: '宸插畨鎺�', value: 1 }, { label: '寰呭畨鎺�', value: 0 }, @@ -29,7 +29,7 @@ </QueryFilterItem> <QueryFilterItem> <FieldDatePicker - v-model="extraParamState.flexEnterpriseSettingStatus" + v-model="extraParamState.time" type="daterange" range-separator="~" start-placeholder="璧峰鏃ユ湡" @@ -52,18 +52,8 @@ </template> <template #btn> <el-button type="primary" link @click="handleDownloadTemplate()">缁撶畻鍗曟ā鏉�</el-button> - <BlFileUpload - :limitFileSize="10" - accept="xls,xlsx" - :showTip="false" - :show-file-list="false" - :on-success="handleUploadSuccess" - style="margin-right: 10px; margin-left: 10px" - > - <template #default> - <el-button type="primary">涓婁紶缁撶畻鍗�</el-button> - </template> - </BlFileUpload> + + <el-button type="primary" @click="openDialog()">涓婁紶缁撶畻鍗�</el-button> <el-button type="primary" @click="handleDownloadTemplate()">瀵煎嚭</el-button> </template> </ProTableQueryFilterBar> @@ -72,23 +62,10 @@ :columns="ServiceChargeManageColumns" :operationBtns="operationBtns" > - <template #operationBtn-uploadBtn="{ data, row }"> - <BlFileUpload - v-model:file-url="row.fileUrl" - :limitFileSize="2" - :limit="1" - accept="doc,docx" - ref="uploadRef" - :showTip="false" - :on-success="(response) => handleUpload(response, row)" - :show-file-list="false" - class="pro-table-operation-btn upload-style-btn" - > - <el-button link type="primary">涓婁紶</el-button> - </BlFileUpload> - </template> </ProTableV2> </AppContainer> + <UploadStatementDialog v-bind="dialogProps" /> + <SettleDetailDialog v-bind="dialogSettleProps" /> </LoadingLayout> </template> @@ -104,12 +81,15 @@ FieldDatePicker, FieldRadio, defineOperationBtns, - BlFileUpload, + useFormDialog, UploadUserFile, } from '@bole-core/components'; import { ServiceChargeManageColumns } from './constants'; -import { EnumUserGender } from '@/constants'; import { downloadFileByUrl } from '@/utils'; +import * as taskServices from '@/services/api/task'; +import { ModelValueType } from 'element-plus'; +import UploadStatementDialog from './components/UploadStatementDialog.vue'; +import SettleDetailDialog from './components/SettleDetailDialog.vue'; defineOptions({ name: 'ServiceChargeManageList', @@ -121,6 +101,24 @@ enCode: 'uploadBtn', name: '涓婁紶', }, + emits: { + onClick: (role) => openDialog(role), + }, + extraProps: { + hide: () => false, + }, + }, + { + data: { + enCode: 'reUploadBtn', + name: '閲嶆柊涓婁紶', + }, + emits: { + onClick: (role) => openDialog(role), + }, + extraProps: { + hide: () => false, + }, }, { data: { @@ -128,7 +126,22 @@ name: '缁撶畻', }, emits: { - onClick: (role) => goSettle(role), + onClick: (role) => openSettleDialog(role), + }, + extraProps: { + hide: () => false, + }, + }, + { + data: { + enCode: 'recallBtn', + name: '鎾ゅ洖', + }, + emits: { + onClick: (role) => handleRecall(role), + }, + extraProps: { + hide: () => false, }, }, { @@ -148,10 +161,19 @@ emits: { onClick: (role) => handleExport(role), }, + extraProps: { + hide: () => false, + }, }, ]); const router = useRouter(); + +const eventContext = useGlobalEventContext(); + +eventContext.addEvent('serviceChargeSettle', () => { + getList(paginationState.pageIndex); +}); const BaseState = { loading: true, @@ -173,17 +195,15 @@ } = useTable( async ({ pageIndex, pageSize }, extraParamState) => { try { - let params: API.GetFlexEnterpriseInput = { + let params: API.GetTaskInfosQuery = { pageModel: { rows: pageSize, page: pageIndex, orderInput: extraParamState.orderInput, }, - flexEnterpriseSettingStatus: extraParamState.flexEnterpriseSettingStatus, - searchWord: extraParamState.searchWord, }; - let res = await flexEnterpriseServices.getFlexEnterpriseList(params, { + let res = await taskServices.getTaskInfos(params, { showLoading: !state.loading, }); return res; @@ -194,22 +214,69 @@ { defaultExtraParams: { searchWord: '', + status: 0, + time: [] as unknown as ModelValueType, orderInput: [{ property: 'id', order: EnumPagedListOrder.Desc }], - flexEnterpriseSettingStatus: '' as any as FlexEnterpriseSettingStatus, }, - queryKey: ['flexEnterpriseServices/getFlexEnterpriseList'], + queryKey: ['taskServices/getTaskInfos'], columnsRenderProps: {}, } ); -function goSettle(row) { +const { dialogProps, handleAdd, handleEdit, editForm } = useFormDialog({ + onConfirm: handleAddOrEdit, + defaultFormParams: { + id: '', + name: '', + settlementUrl: [] as UploadUserFile[], + }, +}); + +function openDialog(row?) { + if (row) { + handleEdit({ + id: row?.id, + name: row?.name, + settlementUrl: [] as UploadUserFile[], + }); + } else { + handleAdd(); + } +} + +async function handleAddOrEdit() {} + +const { + dialogProps: dialogSettleProps, + handleEdit: handleSettleEdit, + editForm: settleEditForm, +} = useFormDialog({ + onConfirm: goSettle, + defaultFormParams: { + id: '', + name: '', + count: 0, + }, +}); + +function openSettleDialog(row?) { + handleSettleEdit({ + id: row.id, + name: row.name, + count: row.count, + }); +} + +async function goSettle() { router.push({ name: 'ServiceChargeSettle', params: { - id: row.id, + id: settleEditForm.id, }, }); } + +function handleRecall(row) {} function goDetail(row) { router.push({ @@ -218,12 +285,6 @@ id: row.id, }, }); -} - -function handleUploadSuccess(response: UploadUserFile) {} - -function handleUpload(val, row) { - console.log('val: ', val); } function handleExport(val) { diff --git a/src/views/ServiceChargeManage/ServiceChargeSettle.vue b/src/views/ServiceChargeManage/ServiceChargeSettle.vue index d48fdbf..bdfca37 100644 --- a/src/views/ServiceChargeManage/ServiceChargeSettle.vue +++ b/src/views/ServiceChargeManage/ServiceChargeSettle.vue @@ -29,47 +29,30 @@ </ProForm> </ChunkCell> <ChunkCell title="鏀舵鏂逛俊鎭�"> - <ProForm :model="form" ref="formRef" label-width="120px"> - <ProFormItemV2 - label="鏀舵鏂硅处鎴�:" - prop="name" - :check-rules="[{ message: '璇烽�夋嫨鏀舵鏂硅处鎴�' }]" - > - <ProFormRadio - v-model="form.name" - :valueEnum="[]" - placeholder="璇烽�夋嫨鏀舵鏂硅处鎴�" - clearable - > - </ProFormRadio> - </ProFormItemV2> - <ProFormMixinsItemContainer> - <ProFormItemV2 - label="鏀舵鏂规埛鍚�:" - prop="name" - :check-rules="[{ message: '璇疯緭鍏ユ敹娆炬柟鎴峰悕' }]" - mode="read" - > - <ProFormText v-model="form.name"> </ProFormText> - </ProFormItemV2> - <ProFormItemV2 - label="鏀舵鏂硅处鍙�:" - prop="name" - :check-rules="[{ message: '璇疯緭鍏ユ敹娆炬柟璐﹀彿' }]" - mode="read" - > - <ProFormText v-model="form.name"> </ProFormText> - </ProFormItemV2> - <ProFormItemV2 - label="鏀舵鏂瑰紑鎴疯:" - prop="name" - :check-rules="[{ message: '璇疯緭鍏ユ敹娆惧紑鎴疯' }]" - mode="read" - > - <ProFormText v-model="form.name"> </ProFormText> - </ProFormItemV2> - </ProFormMixinsItemContainer> - </ProForm> + <ProTableQueryFilterBar @on-reset="reset"> + <template #query> + <QueryFilterItem> + <SearchInput + v-model="extraParamState.keywords" + style="width: 300px" + placeholder="浜哄憳濮撳悕/韬唤璇佸彿/鎵嬫満鍙�" + @on-click-search="getList" + > + </SearchInput> + </QueryFilterItem> + </template> + </ProTableQueryFilterBar> + <ProTableV2 + v-bind="proTableProps" + :columns="SettlementListColumns" + :show-operation-column="false" + :auto-height="false" + ref="proTable" + :tableProps="{ + maxHeight: '400px', + }" + > + </ProTableV2> </ChunkCell> <ChunkCell title="杞处淇℃伅"> <ProForm :model="form" ref="formRef" label-width="120px"> @@ -105,13 +88,19 @@ ProFormText, ProFormSelect, ProFormInputNumber, - ProFormRadio, + ProTableV2, + QueryFilterItem, + SearchInput, + ProTableQueryFilterBar, ProFormMixinsItemContainer, + useTable, } from '@bole-core/components'; import { useQuery } from '@tanstack/vue-query'; import { useRouteView } from '@/hooks'; import { FormInstance } from 'element-plus'; import { validateFormList } from '@/utils'; +import * as taskServices from '@/services/api/task'; +import { SettlementListColumns } from './constants'; defineOptions({ name: 'ServiceChargeSettle', @@ -119,7 +108,7 @@ const route = useRoute(); const id = (route.params.id as string) ?? ''; - +const eventContext = useGlobalEventContext(); const { closeViewPush } = useRouteView(); const form = reactive({ @@ -128,19 +117,55 @@ }); const { isLoading } = useQuery({ - queryKey: ['flexTaskServices/getFlexTaskDetail', id], + queryKey: ['taskServices/getTaskInfo', id], queryFn: async () => { - return await flexTaskServices.getFlexTaskDetail( + return await taskServices.getTaskInfo( { id: id }, { showLoading: false, } ); }, - placeholderData: () => ({} as API.GetFlexTaskDetailForBackOutput), - onSuccess(data) {}, + placeholderData: () => ({} as API.GetTaskInfoQueryResult), + onSuccess(data) { + form.name = data.name; + }, enabled: !!id, }); + +const { + getDataSource: getList, + proTableProps, + paginationState, + extraParamState, + reset, +} = useTable( + async ({ pageIndex, pageSize }, extraParamState) => { + try { + let params: API.GetOpenTaskInfosQuery = { + pageModel: { + rows: pageSize, + page: pageIndex, + orderInput: extraParamState.orderInput, + }, + keywords: extraParamState.keywords, + }; + + let res = await taskServices.getOpenTaskInfos(params); + return res; + } catch (error) { + console.log('error: ', error); + } + }, + { + defaultExtraParams: { + keywords: '', + orderInput: [{ property: 'id', order: EnumPagedListOrder.Desc }], + }, + queryKey: ['taskServices/getOpenTaskInfos'], + columnsRenderProps: {}, + } +); function handleBack() { closeViewPush(route, { @@ -152,12 +177,16 @@ try { const valid = await validateFormList([formRef.value]); if (valid) { - // + submit(); } } catch (error) {} } -onMounted(() => {}); +async function submit() { + try { + eventContext.emit('serviceChargeSettle'); + } catch (error) {} +} </script> <style lang="scss" scoped> diff --git a/src/views/ServiceChargeManage/components/SettleDetailDialog.vue b/src/views/ServiceChargeManage/components/SettleDetailDialog.vue new file mode 100644 index 0000000..189905a --- /dev/null +++ b/src/views/ServiceChargeManage/components/SettleDetailDialog.vue @@ -0,0 +1,70 @@ +<template> + <ProDialog + title="缁撶畻纭" + v-model="visible" + @close="onDialogClose" + destroy-on-close + draggable + :width="700" + > + <ProForm :model="form" ref="dialogForm" label-width="120px" is-read> + <ProFormItemV2 label="浠诲姟鍗曞彿锛�" prop="name"> + <ProFormSelect v-model="form.name" :valueEnum="[]"> </ProFormSelect> + </ProFormItemV2> + <ProFormItemV2 label="浠诲姟鍚嶇О锛�" prop="name"> + <ProFormText v-model.trim="form.name"></ProFormText> + </ProFormItemV2> + <ProFormItemV2 label="缁撶畻浜烘暟锛�" prop="count"> + <ProFormInputNumber v-model="form.count" unit="浜�"> </ProFormInputNumber> + </ProFormItemV2> + <ProFormItemV2 label="缁撶畻閲戦锛�" prop="count"> + <ProFormInputNumber v-model="form.count" unit="鍏�"> </ProFormInputNumber> + </ProFormItemV2> + </ProForm> + <template #footer> + <span class="dialog-footer"> + <el-button @click="emit('onCancel')">鍙栨秷</el-button> + <el-button type="primary" @click="emit('onConfirm')">纭</el-button> + </span> + </template> + </ProDialog> +</template> + +<script setup lang="ts"> +import { FormInstance } from 'element-plus'; +import { + ProDialog, + ProForm, + ProFormItemV2, + ProFormText, + ProFormSelect, + ProFormInputNumber, +} from '@bole-core/components'; + +defineOptions({ + name: 'SettleDetailDialog', +}); + +type Form = { + title?: string; + id: string; + name: string; + count: number; +}; + +const visible = defineModel({ type: Boolean }); + +const form = defineModel<Form>('form'); + +const emit = defineEmits<{ + (e: 'onConfirm'): void; + (e: 'onCancel'): void; +}>(); + +const dialogForm = ref<FormInstance>(); + +function onDialogClose() { + if (!dialogForm.value) return; + dialogForm.value.resetFields(); +} +</script> diff --git a/src/views/ServiceChargeManage/components/UploadStatementDialog.vue b/src/views/ServiceChargeManage/components/UploadStatementDialog.vue new file mode 100644 index 0000000..451b4fc --- /dev/null +++ b/src/views/ServiceChargeManage/components/UploadStatementDialog.vue @@ -0,0 +1,99 @@ +<template> + <ProDialog + title="涓婁紶缁撶畻鍗�" + v-model="visible" + @close="onDialogClose" + destroy-on-close + draggable + :width="700" + > + <ProForm :model="form" ref="dialogForm" label-width="120px"> + <ProFormItemV2 label="浠诲姟鍗曞彿锛�" prop="name" :check-rules="[{ message: '璇烽�夋嫨浠诲姟鍗曞彿' }]"> + <ProFormSelect + v-model="form.name" + :valueEnum="[]" + placeholder="璇烽�夋嫨浠诲姟鍗曞彿" + filterable + clearable + > + </ProFormSelect> + </ProFormItemV2> + <ProFormItemV2 label="浠诲姟鍚嶇О锛�" prop="name" :check-rules="[{ message: '璇疯緭鍏ヤ换鍔″悕绉�' }]"> + <ProFormText + style="width: 50%" + placeholder="璇疯緭鍏ヤ换鍔″悕绉�" + v-model.trim="form.name" + ></ProFormText> + </ProFormItemV2> + <ProFormItemV2 + label="涓婁紶缁撶畻鍗曪細" + prop="settlementUrl" + :check-rules="[{ message: '璇蜂笂浼犵粨绠楀崟', type: 'upload' }]" + > + <ProFormUpload + v-model:file-url="form.settlementUrl" + :limit="1" + :limitFileSize="10" + accept="jpg/jpeg,png,pdf" + ></ProFormUpload> + </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, + ProFormUpload, + ProFormSelect, + UploadUserFile, +} from '@bole-core/components'; + +defineOptions({ + name: 'UploadStatementDialog', +}); + +type Form = { + title?: string; + id: string; + name: string; + settlementUrl: UploadUserFile[]; +}; + +const visible = defineModel({ type: Boolean }); + +const form = defineModel<Form>('form'); + +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> -- Gitblit v1.9.1