| | |
| | | 'taskManage:add': any; |
| | | 'taskManage:edit': any; |
| | | checkReceiveTask: any; |
| | | serviceChargeSettle: any; |
| | | }; |
| | | |
| | | export type GlobalEventListener<T extends keyof GlobalEvent> = (payload: GlobalEvent[T]) => any; |
| | |
| | | time: [] as unknown as ModelValueType, |
| | | orderInput: [{ property: 'id', order: EnumPagedListOrder.Desc }], |
| | | }, |
| | | queryKey: ['flexEnterpriseServices/getFlexEnterpriseList'], |
| | | queryKey: ['taskServices/getTaskInfos'], |
| | | columnsRenderProps: {}, |
| | | } |
| | | ); |
| | |
| | | <template #query> |
| | | <QueryFilterItem> |
| | | <SearchInput |
| | | v-model="extraParamState.searchWord" |
| | | v-model="extraParamState.keywords" |
| | | style="width: 300px" |
| | | placeholder="人员姓名/身份证号/手机号" |
| | | @on-click-search="getList" |
| | |
| | | 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', |
| | |
| | | }); |
| | | |
| | | 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, |
| | | }); |
| | | |
| | |
| | | } = 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); |
| | |
| | | }, |
| | | { |
| | | defaultExtraParams: { |
| | | searchWord: '', |
| | | keywords: '', |
| | | orderInput: [{ property: 'id', order: EnumPagedListOrder.Desc }], |
| | | }, |
| | | queryKey: ['flexEnterpriseServices/getFlexEnterpriseList'], |
| | | queryKey: ['taskServices/getOpenTaskInfos'], |
| | | columnsRenderProps: {}, |
| | | } |
| | | ); |
| | |
| | | <template #query> |
| | | <QueryFilterItem tip-content="结算单状态"> |
| | | <FieldRadio |
| | | v-model="extraParamState.flexEnterpriseSettingStatus" |
| | | v-model="extraParamState.status" |
| | | :value-enum="[ |
| | | { label: '已安排', value: 1 }, |
| | | { label: '待安排', value: 0 }, |
| | |
| | | </QueryFilterItem> |
| | | <QueryFilterItem tip-content="结算状态"> |
| | | <FieldRadio |
| | | v-model="extraParamState.flexEnterpriseSettingStatus" |
| | | v-model="extraParamState.status" |
| | | :value-enum="[ |
| | | { label: '已安排', value: 1 }, |
| | | { label: '待安排', value: 0 }, |
| | |
| | | </QueryFilterItem> |
| | | <QueryFilterItem> |
| | | <FieldDatePicker |
| | | v-model="extraParamState.flexEnterpriseSettingStatus" |
| | | v-model="extraParamState.time" |
| | | type="daterange" |
| | | range-separator="~" |
| | | start-placeholder="起始日期" |
| | |
| | | </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> |
| | |
| | | :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> |
| | | |
| | |
| | | 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', |
| | |
| | | enCode: 'uploadBtn', |
| | | name: '上传', |
| | | }, |
| | | emits: { |
| | | onClick: (role) => openDialog(role), |
| | | }, |
| | | extraProps: { |
| | | hide: () => false, |
| | | }, |
| | | }, |
| | | { |
| | | data: { |
| | | enCode: 'reUploadBtn', |
| | | name: '重新上传', |
| | | }, |
| | | emits: { |
| | | onClick: (role) => openDialog(role), |
| | | }, |
| | | extraProps: { |
| | | hide: () => false, |
| | | }, |
| | | }, |
| | | { |
| | | data: { |
| | |
| | | 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, |
| | | }, |
| | | }, |
| | | { |
| | |
| | | emits: { |
| | | onClick: (role) => handleExport(role), |
| | | }, |
| | | extraProps: { |
| | | hide: () => false, |
| | | }, |
| | | }, |
| | | ]); |
| | | |
| | | const router = useRouter(); |
| | | |
| | | const eventContext = useGlobalEventContext(); |
| | | |
| | | eventContext.addEvent('serviceChargeSettle', () => { |
| | | getList(paginationState.pageIndex); |
| | | }); |
| | | |
| | | const BaseState = { |
| | | loading: true, |
| | |
| | | } = 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; |
| | |
| | | { |
| | | 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({ |
| | |
| | | id: row.id, |
| | | }, |
| | | }); |
| | | } |
| | | |
| | | function handleUploadSuccess(response: UploadUserFile) {} |
| | | |
| | | function handleUpload(val, row) { |
| | | console.log('val: ', val); |
| | | } |
| | | |
| | | function handleExport(val) { |
| | |
| | | </ProForm> |
| | | </ChunkCell> |
| | | <ChunkCell title="收款方信息"> |
| | | <ProForm :model="form" ref="formRef" label-width="120px"> |
| | | <ProFormItemV2 |
| | | label="收款方账户:" |
| | | prop="name" |
| | | :check-rules="[{ message: '请选择收款方账户' }]" |
| | | <ProTableQueryFilterBar @on-reset="reset"> |
| | | <template #query> |
| | | <QueryFilterItem> |
| | | <SearchInput |
| | | v-model="extraParamState.keywords" |
| | | style="width: 300px" |
| | | placeholder="人员姓名/身份证号/手机号" |
| | | @on-click-search="getList" |
| | | > |
| | | <ProFormRadio |
| | | v-model="form.name" |
| | | :valueEnum="[]" |
| | | placeholder="请选择收款方账户" |
| | | clearable |
| | | </SearchInput> |
| | | </QueryFilterItem> |
| | | </template> |
| | | </ProTableQueryFilterBar> |
| | | <ProTableV2 |
| | | v-bind="proTableProps" |
| | | :columns="SettlementListColumns" |
| | | :show-operation-column="false" |
| | | :auto-height="false" |
| | | ref="proTable" |
| | | :tableProps="{ |
| | | maxHeight: '400px', |
| | | }" |
| | | > |
| | | </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> |
| | | </ProTableV2> |
| | | </ChunkCell> |
| | | <ChunkCell title="转账信息"> |
| | | <ProForm :model="form" ref="formRef" label-width="120px"> |
| | |
| | | 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', |
| | |
| | | |
| | | const route = useRoute(); |
| | | const id = (route.params.id as string) ?? ''; |
| | | |
| | | const eventContext = useGlobalEventContext(); |
| | | const { closeViewPush } = useRouteView(); |
| | | |
| | | const form = reactive({ |
| | |
| | | }); |
| | | |
| | | 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, { |
| | |
| | | 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> |
New file |
| | |
| | | <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> |
New file |
| | |
| | | <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> |