From 94e941341c4e2ac704f70c5ae61be2d6a61fcef4 Mon Sep 17 00:00:00 2001 From: wupengfei <834520024@qq.com> Date: 星期二, 02 九月 2025 16:47:32 +0800 Subject: [PATCH] feat: 页面 --- /dev/null | 194 ---------------- src/views/ServiceChargeManage/constants/columns.ts | 33 + src/views/ServiceChargeManage/BalanceManage.vue | 137 +++++++++++ src/hooks/useEvent.ts | 1 src/views/ServiceChargeManage/ServiceChargeDetail.vue | 47 ++- src/views/ServiceChargeManage/components/EditAccountInfoDialog.vue | 89 +++++++ src/views/ServiceChargeManage/components/BalanceDetailDialog.vue | 141 +++++++++++ src/views/ServiceChargeManage/ServiceChargeManage.vue | 19 - src/router/index.ts | 12 9 files changed, 427 insertions(+), 246 deletions(-) diff --git a/src/hooks/useEvent.ts b/src/hooks/useEvent.ts index b462cd4..f897656 100644 --- a/src/hooks/useEvent.ts +++ b/src/hooks/useEvent.ts @@ -6,7 +6,6 @@ '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/router/index.ts b/src/router/index.ts index 3bdb5ca..98978f2 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -257,14 +257,14 @@ }, }, { - path: '/ServiceChargeSettle/:id', - name: 'ServiceChargeSettle', - hidden: true, - alwaysShow: false, - component: () => import('@/views/ServiceChargeManage/ServiceChargeSettle.vue'), + path: '/BalanceManage', + name: 'BalanceManage', + hidden: false, + alwaysShow: true, + component: () => import('@/views/ServiceChargeManage/BalanceManage.vue'), meta: { rank: 10042, - title: '缁撶畻', + title: '浣欓绠$悊', // rootMenu: true, icon: 'home', }, diff --git a/src/views/ServiceChargeManage/BalanceManage.vue b/src/views/ServiceChargeManage/BalanceManage.vue new file mode 100644 index 0000000..e4fac28 --- /dev/null +++ b/src/views/ServiceChargeManage/BalanceManage.vue @@ -0,0 +1,137 @@ +<template> + <LoadingLayout :loading="state.loading"> + <AppContainer> + <ProTableQueryFilterBar @on-reset="reset"> + <template #query> + <QueryFilterItem tip-content="浣欓鑼冨洿"> + <el-input-number + v-model="extraParamState.minAmount" + placeholder="浣欓鏈�灏忛噾棰�" + size="small" + style="width: 150px" + :controls="false" + />~ + <el-input-number + v-model="extraParamState.maxAmount" + placeholder="浣欓鏈�澶ч噾棰�" + size="small" + style="width: 150px" + :controls="false" + /> + </QueryFilterItem> + <QueryFilterItem> + <SearchInput + v-model="extraParamState.keyword" + style="width: 260px" + placeholder="濮撳悕/鎵嬫満鍙�/韬唤璇佸彿" + @on-click-search="getList" + > + </SearchInput> + </QueryFilterItem> + </template> + </ProTableQueryFilterBar> + <ProTableV2 + v-bind="proTableProps" + :columns="BalanceManageColumns" + :operationBtns="operationBtns" + > + </ProTableV2> + </AppContainer> + <BalanceDetailDialog v-bind="dialogProps" /> + </LoadingLayout> +</template> + +<script setup lang="ts"> +import { + ProTableQueryFilterBar, + ProTableV2, + SearchInput, + LoadingLayout, + AppContainer, + QueryFilterItem, + useTable, + useFormDialog, + defineOperationBtns, +} from '@bole-core/components'; +import * as enterpriseServices from '@/services/api/enterprise'; +import BalanceDetailDialog from './components/BalanceDetailDialog.vue'; +import { BalanceManageColumns } from './constants'; + +defineOptions({ + name: 'BalanceManage', +}); + +const operationBtns = defineOperationBtns([ + { + data: { + enCode: 'detailBtn', + name: '鏄庣粏', + }, + emits: { + onClick: (role) => openDialog(role), + }, + extraProps: { + hide: () => false, + }, + }, +]); + +const router = useRouter(); +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.GetEnterprisesQuery = { + pageModel: { + rows: pageSize, + page: pageIndex, + orderInput: extraParamState.orderInput, + }, + // searchKeys: extraParamState.keyword, + }; + let res = await enterpriseServices.getEnterprises(params, { + showLoading: !state.loading, + }); + return res; + } catch (error) {} + }, + { + defaultExtraParams: { + keyword: '', + status: '', + minAmount: null as number, + maxAmount: null as number, + orderInput: [{ property: 'id', order: EnumPagedListOrder.Asc }], + }, + columnsRenderProps: {}, + } +); + +const { dialogProps, handleEdit, editForm } = useFormDialog({ + defaultFormParams: { + id: '', + }, +}); + +function openDialog(row) { + handleEdit({ + id: row.id, + }); +} +</script> diff --git a/src/views/ServiceChargeManage/ServiceChargeDetail.vue b/src/views/ServiceChargeManage/ServiceChargeDetail.vue index f73a96f..0f4c891 100644 --- a/src/views/ServiceChargeManage/ServiceChargeDetail.vue +++ b/src/views/ServiceChargeManage/ServiceChargeDetail.vue @@ -2,11 +2,6 @@ <LoadingLayout :loading="isLoading"> <AppScrollContainer> <ChunkCell title="缁撶畻鍗曡鎯�"> - <template #titleRight> - <el-button type="primary" icon="Download" @click="handleDownloadTemplate()" - >鐢靛瓙鍥炲崟涓嬭浇</el-button - > - </template> <ProForm :model="form" ref="formRef" label-width="120px" :is-read="true"> <ProFormCol> <ProFormColItem :span="8"> @@ -36,7 +31,6 @@ ></ProFormDatePicker> </ProFormItemV2> </ProFormColItem> - <ProFormColItem :span="8"></ProFormColItem> </ProFormCol> <ProFormCol> <ProFormColItem :span="8"> @@ -49,16 +43,10 @@ <ProFormInputNumber v-model="form.money"> </ProFormInputNumber> </ProFormItemV2> </ProFormColItem> - <ProFormColItem :span="8"> - <ProFormItemV2 label="鐘舵��:" prop="status"> - <ProFormRadio v-model="form.status" :value-enum="[{ label: '鏄�', value: 1 }]"> - </ProFormRadio> - </ProFormItemV2> - </ProFormColItem> </ProFormCol> </ProForm> </ChunkCell> - <ChunkCell title="缁撶畻娴佺▼"> + <!-- <ChunkCell title="缁撶畻娴佺▼"> <div class="step-wrapper"> <el-steps :active="1" align-center finish-status="process"> <el-step title="缁撶畻鍗曚笂浼�" :icon="Edit"> @@ -79,7 +67,7 @@ </el-step> </el-steps> </div> - </ChunkCell> + </ChunkCell> --> <ChunkCell title="缁撶畻鍚嶅崟"> <ProTableQueryFilterBar @on-reset="reset"> <template #query> @@ -87,7 +75,7 @@ <SearchInput v-model="extraParamState.keywords" style="width: 300px" - placeholder="浜哄憳濮撳悕/韬唤璇佸彿/鎵嬫満鍙�" + placeholder="濮撳悕/鎵嬫満/韬唤璇佸彿/瀹㈡埛" @on-click-search="getList" > </SearchInput> @@ -107,6 +95,7 @@ </ProTableV2> </ChunkCell> </AppScrollContainer> + <EditAccountInfoDialog v-bind="dialogProps"></EditAccountInfoDialog> </LoadingLayout> </template> <script setup lang="ts"> @@ -129,12 +118,14 @@ QueryFilterItem, ProTableQueryFilterBar, TextOverTooltip, + useFormDialog, } from '@bole-core/components'; import { Edit, Upload } from '@element-plus/icons-vue'; import { SettlementListColumns } from './constants'; import { useQuery } from '@tanstack/vue-query'; import { downloadFileByUrl } from '@bole-core/core'; import * as taskServices from '@/services/api/task'; +import EditAccountInfoDialog from './components/EditAccountInfoDialog.vue'; defineOptions({ name: 'ServiceChargeDetail', @@ -143,8 +134,11 @@ const operationBtns = defineOperationBtns([ { data: { - enCode: 'downloadBtn', - name: '涓嬭浇鍥炲崟', + enCode: 'editBtn', + name: '缂栬緫', + }, + emits: { + onClick: (role) => openDialog(role), }, }, ]); @@ -209,10 +203,25 @@ } ); -function handleDownloadTemplate() { - downloadFileByUrl('', '鐢靛瓙鍥炲崟'); +const { dialogProps, handleAdd, handleEdit, editForm } = useFormDialog({ + onConfirm: handleAddOrEdit, + defaultFormParams: { + id: '', + name: '', + }, +}); + +function openDialog(row?) { + if (row) { + handleEdit({ + id: row?.id, + name: row?.name, + }); + } } +async function handleAddOrEdit() {} + onMounted(() => { getList(); }); diff --git a/src/views/ServiceChargeManage/ServiceChargeManage.vue b/src/views/ServiceChargeManage/ServiceChargeManage.vue index bd7fa87..47361e8 100644 --- a/src/views/ServiceChargeManage/ServiceChargeManage.vue +++ b/src/views/ServiceChargeManage/ServiceChargeManage.vue @@ -169,12 +169,6 @@ const router = useRouter(); -const eventContext = useGlobalEventContext(); - -eventContext.addEvent('serviceChargeSettle', () => { - getList(paginationState.pageIndex); -}); - const BaseState = { loading: true, }; @@ -251,7 +245,7 @@ handleEdit: handleSettleEdit, editForm: settleEditForm, } = useFormDialog({ - onConfirm: goSettle, + onConfirm: handleSettle, defaultFormParams: { id: '', name: '', @@ -259,20 +253,13 @@ }, }); +async function handleSettle() {} + function openSettleDialog(row?) { handleSettleEdit({ id: row.id, name: row.name, count: row.count, - }); -} - -async function goSettle() { - router.push({ - name: 'ServiceChargeSettle', - params: { - id: settleEditForm.id, - }, }); } diff --git a/src/views/ServiceChargeManage/ServiceChargeSettle.vue b/src/views/ServiceChargeManage/ServiceChargeSettle.vue deleted file mode 100644 index bdfca37..0000000 --- a/src/views/ServiceChargeManage/ServiceChargeSettle.vue +++ /dev/null @@ -1,194 +0,0 @@ -<template> - <LoadingLayout :loading="isLoading"> - <AppScrollContainer> - <ChunkCell title="浠樻鏂逛俊鎭�"> - <ProForm :model="form" ref="formRef" label-width="120px"> - <ProFormItemV2 - label="浠樻璐︽埛:" - prop="name" - :check-rules="[{ message: '璇烽�夋嫨浠樻璐︽埛' }]" - > - <ProFormSelect - v-model="form.name" - :valueEnum="[]" - placeholder="璇烽�夋嫨鎮ㄧ殑浠樻鏂瑰紡" - clearable - > - </ProFormSelect> - </ProFormItemV2> - <ProFormMixinsItemContainer> - <ProFormItemV2 - label="浠樻閲戦:" - prop="money" - :check-rules="[{ message: '璇疯緭鍏ヤ粯娆鹃噾棰�' }]" - mode="read" - > - <ProFormInputNumber v-model="form.money"> </ProFormInputNumber> - </ProFormItemV2> - </ProFormMixinsItemContainer> - </ProForm> - </ChunkCell> - <ChunkCell title="鏀舵鏂逛俊鎭�"> - <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"> - <ProFormMixinsItemContainer> - <ProFormItemV2 label="浜ゆ槗鐢ㄩ��:" prop="name" mode="read"> - <ProFormText v-model="form.name"> </ProFormText> - </ProFormItemV2> - </ProFormMixinsItemContainer> - <ProFormItemV2 label="闄勮█:" prop="name"> - <ProFormText v-model="form.name" :maxlength="30" show-word-limit> </ProFormText> - </ProFormItemV2> - <ProFormItemV2 label="澶囨敞:" prop="name"> - <ProFormText v-model="form.name" :maxlength="30" show-word-limit> </ProFormText> - </ProFormItemV2> - <div class="chuck-add-or-edit-actions"> - <el-button class="chuck-add-or-edit-actions" @click="handleBack()">鍙栨秷</el-button> - <el-button class="chuck-add-or-edit-actions" type="primary" @click="handleSubmit" - >鎻愪氦瀹℃牳</el-button - > - </div> - </ProForm> - </ChunkCell> - </AppScrollContainer> - </LoadingLayout> -</template> -<script setup lang="ts"> -import { - LoadingLayout, - AppScrollContainer, - ChunkCell, - ProForm, - ProFormItemV2, - ProFormText, - ProFormSelect, - ProFormInputNumber, - 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', -}); - -const route = useRoute(); -const id = (route.params.id as string) ?? ''; -const eventContext = useGlobalEventContext(); -const { closeViewPush } = useRouteView(); - -const form = reactive({ - name: '', - money: 0, -}); - -const { isLoading } = useQuery({ - queryKey: ['taskServices/getTaskInfo', id], - queryFn: async () => { - return await taskServices.getTaskInfo( - { id: id }, - { - showLoading: false, - } - ); - }, - 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, { - name: 'ServiceChargeManageList', - }); -} -const formRef = ref<FormInstance>(); -async function handleSubmit() { - try { - const valid = await validateFormList([formRef.value]); - if (valid) { - submit(); - } - } catch (error) {} -} - -async function submit() { - try { - eventContext.emit('serviceChargeSettle'); - } catch (error) {} -} -</script> - -<style lang="scss" scoped> -@use '@/style/common.scss' as *; -</style> diff --git a/src/views/ServiceChargeManage/components/BalanceDetailDialog.vue b/src/views/ServiceChargeManage/components/BalanceDetailDialog.vue new file mode 100644 index 0000000..a81d09f --- /dev/null +++ b/src/views/ServiceChargeManage/components/BalanceDetailDialog.vue @@ -0,0 +1,141 @@ +<template> + <ProDialog title="浣欓鏄庣粏" v-model="visible" destroy-on-close draggable> + <ProDialogTableWrapper :height="500"> + <ProTableQueryFilterBar @on-reset="reset"> + <template #query> + <QueryFilterItem> + <FieldSelect + v-model="extraParamState.status" + :valueEnum="[]" + clearable + filterable + placeholder="浜ゆ槗绫诲瀷" + /> + </QueryFilterItem> + <QueryFilterItem tip-content="鏌ヨ鏃ユ湡"> + <FieldDatePicker + v-model="extraParamState.creationTime" + type="daterange" + range-separator="~" + start-placeholder="璧峰鏃ユ湡" + end-placeholder="鎴鏃ユ湡" + clearable + @change="getList()" + ></FieldDatePicker> + </QueryFilterItem> + </template> + </ProTableQueryFilterBar> + <ProTableV2 v-bind="proTableProps" :columns="columns" :showOperationColumn="false"> + </ProTableV2> + </ProDialogTableWrapper> + </ProDialog> +</template> + +<script setup lang="ts"> +import { + defineColumns, + ProDialog, + useTable, + ProDialogTableWrapper, + QueryFilterItem, + FieldDatePicker, + FieldSelect, + ProTableV2, + ProTableQueryFilterBar, +} from '@bole-core/components'; +import * as enterpriseServices from '@/services/api/enterprise'; +import { ModelValueType } from 'element-plus'; + +defineOptions({ + name: 'FinanceDetailDialog', +}); + +type Form = { + id?: string; +}; + +const visible = defineModel({ type: Boolean }); +const form = defineModel<Form>('form'); + +const emit = defineEmits<{ + (e: 'update:modelValue', value: boolean): void; + (e: 'onCancel'): void; +}>(); + +const columns = defineColumns([ + { + id: '1', + enCode: 'name', + name: '浜ゆ槗鏃堕棿', + }, + { + id: '2', + enCode: 'name', + name: '鏀跺叆', + }, + { + id: '3', + enCode: 'name', + name: '鏀嚭', + }, + { + id: '4', + enCode: 'name', + name: '璐︽埛浣欓', + }, + { + id: '4', + enCode: 'name', + name: '瀵规柟甯愬彿/鎴峰悕', + }, + { + id: '4', + enCode: 'name', + name: '鐢ㄩ��', + }, +]); + +watch( + () => visible.value, + (value) => { + if (value) { + getList(); + } + } +); + +const { + getDataSource: getList, + proTableProps, + paginationState, + extraParamState, + reset, +} = useTable( + async ({ pageIndex, pageSize }, extraParamState) => { + try { + let params: API.GetEnterprisesQuery = { + pageModel: { + rows: pageSize, + page: pageIndex, + orderInput: extraParamState.orderInput, + }, + // searchKeys: extraParamState.keyword, + }; + let res = await enterpriseServices.getEnterprises(params); + return res; + } catch (error) {} + }, + { + defaultExtraParams: { + status: '', + creationTime: [] as unknown as ModelValueType, + orderInput: [{ property: 'id', order: EnumPagedListOrder.Asc }], + }, + columnsRenderProps: {}, + } +); +</script> + +<style lang="scss" scoped> +@use '@/style/common.scss' as *; +</style> diff --git a/src/views/ServiceChargeManage/components/EditAccountInfoDialog.vue b/src/views/ServiceChargeManage/components/EditAccountInfoDialog.vue new file mode 100644 index 0000000..fb6b2d5 --- /dev/null +++ b/src/views/ServiceChargeManage/components/EditAccountInfoDialog.vue @@ -0,0 +1,89 @@ +<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: '璇疯緭鍏ユ墍灞為摱琛�' }]"> + <ProFormText placeholder="璇疯緭鍏ユ墍灞為摱琛�" v-model.trim="form.name"></ProFormText> + </ProFormItemV2> + <ProFormItemV2 label="鏀舵璐︽埛锛�" prop="name" :check-rules="[{ message: '璇疯緭鍏ユ敹娆捐处鎴�' }]"> + <ProFormText placeholder="璇疯緭鍏ユ敹娆捐处鎴�" v-model.trim="form.name"></ProFormText> + </ProFormItemV2> + <ProFormItemV2 label="缁撶畻閲戦锛�" prop="name" :check-rules="[{ message: '璇疯緭鍏ョ粨绠楅噾棰�' }]"> + <ProFormInputNumber + placeholder="璇疯緭鍏ョ粨绠楅噾棰�" + v-model.trim="form.name" + :controls="false" + :min="0" + ></ProFormInputNumber> + </ProFormItemV2> + <ProFormItemV2 label="瀹炲彂閲戦锛�" prop="name" :check-rules="[{ message: '璇疯緭鍏ュ疄鍙戦噾棰�' }]"> + <ProFormInputNumber + placeholder="璇疯緭鍏ュ疄鍙戦噾棰�" + v-model.trim="form.name" + :controls="false" + :min="0" + ></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, + ProFormInputNumber, + ProFormItemV2, + ProFormText, + UploadUserFile, +} from '@bole-core/components'; + +defineOptions({ + name: 'EditAccountInfoDialog', +}); + +type Form = { + title?: string; + name: string; +}; + +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> diff --git a/src/views/ServiceChargeManage/constants/columns.ts b/src/views/ServiceChargeManage/constants/columns.ts index e7647e2..f9bb4a0 100644 --- a/src/views/ServiceChargeManage/constants/columns.ts +++ b/src/views/ServiceChargeManage/constants/columns.ts @@ -112,16 +112,29 @@ { id: '9', enCode: 'name', - name: '鐘舵��', - }, - { - id: '10', - enCode: 'name', - name: '缁撶畻娴佹按鍙�', - }, - { - id: '11', - enCode: 'name', name: '缁撶畻鏃堕棿', }, ]); + +export const BalanceManageColumns = defineColumns([ + { + id: '1', + enCode: 'name', + name: '濮撳悕', + }, + { + id: '2', + enCode: 'name', + name: '鎵嬫満鍙�', + }, + { + id: '3', + enCode: 'name', + name: '韬唤璇佸彿', + }, + { + id: '4', + enCode: 'name', + name: '璐︽埛浣欓', + }, +]); -- Gitblit v1.9.1