| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- <template>
- <view class="edit-container">
- <scroll-view scroll-y class="scroll-content">
- <view class="form-wrapper">
- <uv-form :model="form" ref="formRef" labelWidth="100px" labelPosition="top" :borderBottom="false">
- <!-- 1. 到款信息 (Readonly) -->
- <CommonSection title="到款信息" :isFirst="true">
- <view class="info-list">
- <CommonInfoRow label="项目名称" @click="openProjectDialog">
- <view style="display: flex; align-items: center; justify-content: flex-end;">
- <text v-if="form.projectName" :style="{ color: isContinue ? '#666' : '#333', fontSize: '28rpx' }">{{ form.projectName }}</text>
- <text v-else style="color: #c0c4cc; font-size: 28rpx;">请选择项目名称</text>
- <uv-icon v-if="!isContinue" name="arrow-right" size="16" color="#c0c4cc" style="margin-left: 10rpx;"></uv-icon>
- </view>
- </CommonInfoRow>
- <CommonInfoRow label="项目负责人" v-if="form.projectLeaderName" :value="form.projectLeaderName" />
- <CommonInfoRow label="科室" v-if="form.deptName" :value="form.deptName" />
- <CommonInfoRow label="到款金额(元)" :value="formatAmount(form.amount)" isAmount />
- <CommonInfoRow label="管理费(元)" :value="formatAmount(form.manageAmount)" isAmount />
- <CommonInfoRow label="税费(元)" :value="formatAmount(form.taxAmount)" isAmount />
- <CommonInfoRow label="待认领金额(元)" :value="formatAmount(form.allotAmount)" isAmount />
- <CommonInfoRow label="到款日期" :value="form.date ? formatDate(new Date(form.date), 'YYYY-MM-DD') : '-'" />
- <CommonInfoRow label="到款类型" :value="getDictLabel(paymentReceivedTypeOptions, form.type)" />
- <CommonInfoRow label="打款单位" :value="form.unit || '-'" />
- </view>
- </CommonSection>
- <!-- 2. 认领经费 -->
- <CommonSection title="认领经费">
- <view class="edit-form-list">
- <template v-if="detail && detail.length > 0">
- <CommonInfoRow
- v-for="(item, index) in detail"
- :key="item.id || index"
- :label="item.subjName"
- >
- <uv-input
- v-model="item.amount"
- type="digit"
- placeholder="请输入金额"
- border="none"
- inputAlign="right"
- color="#ff4d4f"
- customStyle="font-weight: 600; font-family: 'DIN-Medium', sans-serif;"
- >
- <template v-slot:suffix>
- <text style="margin-left: 10rpx; font-size: 28rpx; color: #333; font-weight: normal;">元</text>
- </template>
- </uv-input>
- </CommonInfoRow>
- </template>
- <template v-else>
- <view style="padding: 20rpx; color: #999; text-align: center; font-size: 26rpx;">
- 暂无费用列表信息
- </view>
- </template>
- </view>
- </CommonSection>
- </uv-form>
- </view>
- </scroll-view>
-
- <!-- 提交按钮 -->
- <view class="bottom-bar">
- <uv-button type="primary" text="提交认领" @click="submitForm" :loading="loading" customStyle="border-radius: 40rpx;"></uv-button>
- </view>
- <uv-toast ref="toastRef"></uv-toast>
- <!-- 选择项目弹窗 -->
- <SelectProject ref="selectProjectRef" @select="onProjectSelected" />
- </view>
- </template>
- <script lang="ts" setup>
- import { ref, reactive, computed } from 'vue';
- import { onLoad } from '@dcloudio/uni-app';
- import { useSystemApi } from '@/api/system/index';
- import { useFundApi, useClaimApi } from '@/api/fund/index';
- import { formatDate } from '@/utils/date';
- import { onRouterPush } from '@/utils/router';
- import SelectProject from '@/components/SelectProject/index.vue';
- import CommonSection from '@/components/ui/CommonSection.vue';
- import CommonInfoRow from '@/components/ui/CommonInfoRow.vue';
- const systemApi = useSystemApi();
- const fundApi = useFundApi();
- const claimApi = useClaimApi();
- const toastRef = ref();
- const selectProjectRef = ref();
- const loading = ref(false);
- const paymentReceivedTypeOptions = ref<any[]>([]);
- const isContinue = ref(false);
- const detail = ref<any[]>([]);
- const form = reactive({
- id: 0,
- allotAmount: null,
- amount: 0,
- manageAmount: 0,
- taxAmount: 0,
- projectId: 0,
- projectName: '',
- projectLeaderName: '',
- deptName: '',
- projectType: '',
- startDate: '',
- endDate: '',
- createdName: '',
- createdTime: '',
- date: '',
- remark: '',
- serialNo: '',
- type: '',
- unit: '',
- status: '',
- externalAmount: 0,
- internalAmount: 0
- });
- const formatAmount = (cellValue: any) => {
- if (cellValue === null || cellValue === undefined || cellValue === '') return '0.00';
- const num = Number(cellValue);
- return isNaN(num) ? '0.00' : num.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
- };
- const getDictLabel = (options: any[], value: string) => {
- const find = options.find((item) => item.dictValue === value);
- return find ? find.dictLabel : value || '-';
- };
- const getDict = async () => {
- try {
- const resTypes: any = await systemApi.getDictDataByType('PaymentReceivedType');
- if (resTypes.code == 200 && resTypes.data) paymentReceivedTypeOptions.value = resTypes.data.values || [];
-
- const parList: any = await fundApi.getAllFirstSubj();
- if(parList.code == 200 && parList.data) {
- detail.value = parList.data.map((item: any) => ({
- ...item,
- amount: ''
- }));
- }
- } catch (err) {
- console.error(err);
- }
- };
- const getFundDetail = async (id: number) => {
- try {
- const res: any = await fundApi.getDetails({ id });
- if (res.code == 200 && res.data) {
- Object.assign(form, res.data);
- form.id = res.data.id;
- form.amount = res.data.amount || 0;
- form.manageAmount = res.data.manageAmount || 0;
- form.taxAmount = res.data.taxAmount || 0;
- form.allotAmount = res.data.allotAmount || 0;
-
- if (res.data.projectName) {
- isContinue.value = true;
- }
-
- if (form.status == '20') {
- onRouterPush(`/pages/fund/claim/detail?id=${id}`);
- }
- }
- } catch (err) {
- console.error(err);
- }
- };
- const openProjectDialog = () => {
- if (isContinue.value) return;
- selectProjectRef.value?.openDialog();
- };
- const onProjectSelected = (item: any) => {
- form.projectId = Number(item.projectId);
- form.projectName = item.projectName;
- form.projectLeaderName = item.projectLeaderName;
- form.deptName = item.deptName;
- form.startDate = item.startDate;
- form.endDate = item.endDate;
- form.projectType = item.projectType;
- };
- const submitForm = async () => {
- if (!form.projectId) {
- toastRef.value?.show({ message: '请选择项目信息', type: 'error' });
- return;
- }
- const totalEntry = detail.value.reduce((total, item) => total + (Number(item.amount) || 0), 0);
- const allotAmount = Number(form.allotAmount) || 0;
- const tolerance = 0.01;
- if (totalEntry === 0) {
- toastRef.value?.show({ message: '本次认领金额不能为0', type: 'error' });
- return;
- }
- if (totalEntry - allotAmount > tolerance) {
- toastRef.value?.show({ message: '本次认领金额不得大于待认领金额', type: 'error' });
- return;
- }
- const params = JSON.parse(JSON.stringify(form));
- params.fundId = form.id;
- params.detail = detail.value.map((item: any) => ({
- ...item,
- amount: Number(item.amount || 0)
- }));
- params.amount = Number(params.amount || 0);
- params.externalAmount = Number(params.externalAmount || 0);
- params.internalAmount = Number(params.internalAmount || 0);
-
- uni.showModal({
- title: '提示',
- content: '确认提交认领?',
- success: async (resModal) => {
- if (resModal.confirm) {
- loading.value = true;
- try {
- const res: any = await claimApi.create(params);
- if (res.code == 200) {
- toastRef.value.show({ message: '认领操作成功', type: 'success' });
- setTimeout(() => {
- onRouterPush('/pages/fund/claim/index');
- }, 1000);
- } else {
- toastRef.value.show({ message: res.msg || '提交失败', type: 'error' });
- }
- } catch (err) {
- console.error(err);
- } finally {
- loading.value = false;
- }
- }
- }
- });
- };
- onLoad((options: any) => {
- const id = options.id ? Number(options.id) : 0;
- getDict().then(() => {
- if (id) {
- getFundDetail(id);
- }
- });
- });
- </script>
- <style lang="scss" scoped>
- .edit-container {
- height: calc(100vh - var(--window-top));
- display: flex;
- flex-direction: column;
- background-color: #f5f7fa;
- box-sizing: border-box;
- }
- .scroll-content {
- flex: 1;
- height: 100%;
- }
- .form-wrapper {
- padding: 40rpx 30rpx calc(140rpx + env(safe-area-inset-bottom));
- }
- .edit-form-list {
- :deep(.uv-form-item) {
- padding: 10rpx 0;
- border-bottom: 1px solid #f5f5f5;
-
- &:last-child {
- border-bottom: none;
- }
- }
- }
- .bottom-bar {
- position: fixed;
- bottom: 0;
- left: 0;
- right: 0;
- background-color: #fff;
- padding: 20rpx 30rpx;
- box-sizing: border-box;
- box-shadow: 0 -4rpx 16rpx rgba(0, 0, 0, 0.05);
- padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
- z-index: 99;
- }
- .highlight-number {
- flex: 1;
- text-align: right;
- font-size: 28rpx;
- color: #333;
- }
- .primary-color {
- color: #1c9bfd !important;
- font-weight: 500;
- }
- .number-font {
- font-family: 'Helvetica Neue', Arial, sans-serif;
- }
- </style>
|