|
@@ -0,0 +1,571 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div class="p-2">
|
|
|
|
|
+ <!-- 页面标题 -->
|
|
|
|
|
+ <el-card shadow="never" class="mb-2">
|
|
|
|
|
+ <div class="flex justify-between items-center">
|
|
|
|
|
+ <div class="flex items-center">
|
|
|
|
|
+ <el-button link @click="handleBack" class="mr-2">
|
|
|
|
|
+ <el-icon class="mr-1"><ArrowLeft /></el-icon>
|
|
|
|
|
+ 返回
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <span class="text-lg font-bold">{{ pageTitle }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <el-button type="primary" @click="submitForm" :loading="buttonLoading">保存</el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-card>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 基本信息 -->
|
|
|
|
|
+ <el-card shadow="never" class="mb-2">
|
|
|
|
|
+ <el-form ref="revenueHeaderFormRef" :model="form" :rules="rules" label-width="120px">
|
|
|
|
|
+ <el-row :gutter="20" v-if="form.revenueType == '0'">
|
|
|
|
|
+ <el-col :span="8">
|
|
|
|
|
+ <el-form-item label="客户编号:" prop="customerCode">
|
|
|
|
|
+ <el-select
|
|
|
|
|
+ v-model="form.customerCode"
|
|
|
|
|
+ placeholder="请输入客户编号"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ filterable
|
|
|
|
|
+ remote
|
|
|
|
|
+ :remote-method="handleSearchCustomer"
|
|
|
|
|
+ :loading="customerSearchLoading"
|
|
|
|
|
+ @change="handleCustomerChange"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-option
|
|
|
|
|
+ v-for="customer in filteredCustomerList"
|
|
|
|
|
+ :key="customer.id"
|
|
|
|
|
+ :label="`${customer.customerNo} - ${customer.customerName}`"
|
|
|
|
|
+ :value="customer.customerNo"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :span="8">
|
|
|
|
|
+ <el-form-item label="收入单类型:" prop="revenueType">
|
|
|
|
|
+ <el-select v-model="form.revenueType" placeholder="请选择" style="width: 100%" disabled>
|
|
|
|
|
+ <el-option v-for="dict in revenue_type" :key="dict.value" :label="dict.label" :value="dict.value" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :span="8">
|
|
|
|
|
+ <el-form-item label="所属公司:" prop="companyName">
|
|
|
|
|
+ <el-input v-model="form.companyName" disabled />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ <el-row :gutter="20" v-if="form.revenueType == '1'">
|
|
|
|
|
+ <el-col :span="8">
|
|
|
|
|
+ <el-form-item label="收入单类型:" prop="revenueType">
|
|
|
|
|
+ <el-select v-model="form.revenueType" placeholder="请选择" style="width: 100%" disabled>
|
|
|
|
|
+ <el-option v-for="dict in revenue_type" :key="dict.value" :label="dict.label" :value="dict.value" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :span="8">
|
|
|
|
|
+ <el-form-item label="所属公司:" prop="companyName">
|
|
|
|
|
+ <el-input v-model="form.companyName" disabled />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :span="8">
|
|
|
|
|
+ <el-form-item label="供应商:" prop="supplierName">
|
|
|
|
|
+ <el-select
|
|
|
|
|
+ v-model="form.supplierName"
|
|
|
|
|
+ placeholder="请输入供应商名称"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ filterable
|
|
|
|
|
+ remote
|
|
|
|
|
+ :remote-method="handleSearchCustomer"
|
|
|
|
|
+ :loading="customerSearchLoading"
|
|
|
|
|
+ @change="handleCustomerChange"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-option
|
|
|
|
|
+ v-for="customer in filteredCustomerList"
|
|
|
|
|
+ :key="customer.id"
|
|
|
|
|
+ :label="`${customer.customerNo} - ${customer.customerName}`"
|
|
|
|
|
+ :value="customer.customerNo"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+
|
|
|
|
|
+ <el-row :gutter="20">
|
|
|
|
|
+ <el-col :span="8">
|
|
|
|
|
+ <el-form-item label="业务部门:" prop="businessDept">
|
|
|
|
|
+ <el-input v-model="form.businessDept" disabled />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :span="8">
|
|
|
|
|
+ <el-form-item label="客服人员:" prop="customerService">
|
|
|
|
|
+ <el-input v-model="form.customerService" disabled />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :span="8">
|
|
|
|
|
+ <el-form-item label="业务员:" prop="businessStaff">
|
|
|
|
|
+ <el-input v-model="form.businessStaff" disabled />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+
|
|
|
|
|
+ <el-row :gutter="20">
|
|
|
|
|
+ <el-col :span="8">
|
|
|
|
|
+ <el-form-item label="是否含税:" prop="isPrwTax">
|
|
|
|
|
+ <el-radio-group v-model="form.isPrwTax">
|
|
|
|
|
+ <el-radio v-for="dict in sys_platform_yes_no" :key="dict.value" :value="dict.value">{{ dict.label }}</el-radio>
|
|
|
|
|
+ </el-radio-group>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :span="8">
|
|
|
|
|
+ <el-form-item label="交易币别:" prop="currencyId">
|
|
|
|
|
+ <el-select v-model="form.currencyId" placeholder="请选择" style="width: 100%" clearable>
|
|
|
|
|
+ <el-option v-for="currency in currencyList" :key="currency.id" :label="currency.currencyName" :value="currency.id" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ <el-row :gutter="20">
|
|
|
|
|
+ <el-col :span="16">
|
|
|
|
|
+ <el-form-item label="备注:" prop="remark">
|
|
|
|
|
+ <el-input v-model="form.remark" type="textarea" :min="3" placeholder="请输入备注" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ </el-card>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 其他信息 -->
|
|
|
|
|
+ <el-card shadow="never">
|
|
|
|
|
+ <template #header>
|
|
|
|
|
+ <div class="flex justify-between items-center">
|
|
|
|
|
+ <span>其他信息:</span>
|
|
|
|
|
+ <el-button type="primary" plain @click="handleAddDetail">新增</el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div style="margin-left: 60px">
|
|
|
|
|
+ <span>总计:{{ totalAmount.toFixed(2) }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+
|
|
|
|
|
+ <el-table :data="detailList" border style="width: 100%">
|
|
|
|
|
+ <el-table-column label="费用类型" min-width="150" align="center">
|
|
|
|
|
+ <template #default="scope">
|
|
|
|
|
+ <el-select v-model="scope.row.revenueId" placeholder="请选择" style="width: 100%">
|
|
|
|
|
+ <el-option v-for="item in feeTypeList" :key="item.id" :label="`${item.revenueCode},${item.revenueName}`" :value="item.id" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="数量" min-width="120" align="center">
|
|
|
|
|
+ <template #default="scope">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="scope.row.quantity"
|
|
|
|
|
+ :precision="0"
|
|
|
|
|
+ :controls="false"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ placeholder="请输入"
|
|
|
|
|
+ @change="handleQuantityOrPriceChange(scope.$index)"
|
|
|
|
|
+ />
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="单价" min-width="120" align="center">
|
|
|
|
|
+ <template #default="scope">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="scope.row.unitPrice"
|
|
|
|
|
+ :precision="2"
|
|
|
|
|
+ :controls="false"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ placeholder="请输入"
|
|
|
|
|
+ @change="handleQuantityOrPriceChange(scope.$index)"
|
|
|
|
|
+ />
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="总金额" min-width="120" align="center">
|
|
|
|
|
+ <template #default="scope">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="scope.row.totalAmount"
|
|
|
|
|
+ :precision="2"
|
|
|
|
|
+ :controls="false"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ placeholder="请输入"
|
|
|
|
|
+ @change="calculateTotal"
|
|
|
|
|
+ />
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="备注" min-width="150" align="center">
|
|
|
|
|
+ <template #default="scope">
|
|
|
|
|
+ <el-input v-model="scope.row.remark" placeholder="请输入" />
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="操作" width="80" fixed="right" align="center">
|
|
|
|
|
+ <template #default="scope">
|
|
|
|
|
+ <el-button link type="danger" @click="handleDeleteDetail(scope.$index)">删除</el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ </el-table>
|
|
|
|
|
+ </el-card>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+<script setup lang="ts">
|
|
|
|
|
+import { useRouter } from 'vue-router';
|
|
|
|
|
+import { listRevenueHeader, getRevenueHeader, addRevenueHeader, updateRevenueHeader } from '@/api/order/revenueHeader';
|
|
|
|
|
+import { RevenueHeaderVO, RevenueHeaderQuery, RevenueHeaderForm } from '@/api/order/revenueHeader/types';
|
|
|
|
|
+import { listCustomerInfo, getCustomerInfo } from '@/api/customer/customerFile/customerInfo';
|
|
|
|
|
+import { CustomerInfoVO } from '@/api/customer/customerFile/customerInfo/types';
|
|
|
|
|
+import { listRevenueExpense } from '@/api/company/revenueExpense';
|
|
|
|
|
+import { RevenueExpenseVO } from '@/api/company/revenueExpense/types';
|
|
|
|
|
+import { listComCurrency } from '@/api/company/comCurrency';
|
|
|
|
|
+import { ComCurrencyVO } from '@/api/company/comCurrency/types';
|
|
|
|
|
+import { getCompany } from '@/api/company/company';
|
|
|
|
|
+
|
|
|
|
|
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
|
|
|
+const { sys_platform_yes_no, check_status, revenue_type } = toRefs<any>(proxy?.useDict('sys_platform_yes_no', 'check_status', 'revenue_type'));
|
|
|
|
|
+const router = useRouter();
|
|
|
|
|
+const route = useRoute();
|
|
|
|
|
+
|
|
|
|
|
+const revenueHeaderFormRef = ref();
|
|
|
|
|
+const buttonLoading = ref(false);
|
|
|
|
|
+const customerList = ref<CustomerInfoVO[]>([]);
|
|
|
|
|
+const filteredCustomerList = ref<CustomerInfoVO[]>([]);
|
|
|
|
|
+const customerSearchLoading = ref(false);
|
|
|
|
|
+const feeTypeList = ref<RevenueExpenseVO[]>([]);
|
|
|
|
|
+const currencyList = ref<ComCurrencyVO[]>([]);
|
|
|
|
|
+
|
|
|
|
|
+// 防抖定时器
|
|
|
|
|
+let searchTimer: NodeJS.Timeout | null = null;
|
|
|
|
|
+const detailList = ref<any[]>([]);
|
|
|
|
|
+
|
|
|
|
|
+// 计算总金额
|
|
|
|
|
+const totalAmount = computed(() => {
|
|
|
|
|
+ return detailList.value.reduce((sum, item) => {
|
|
|
|
|
+ const amount = Number(item.totalAmount) || 0;
|
|
|
|
|
+ return sum + amount;
|
|
|
|
|
+ }, 0);
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+// 表单初始数据
|
|
|
|
|
+const initFormData: RevenueHeaderForm = {
|
|
|
|
|
+ id: undefined,
|
|
|
|
|
+ revenueType: '收入申请',
|
|
|
|
|
+ orderRevenueCode: undefined,
|
|
|
|
|
+ incomeOrderCode: undefined,
|
|
|
|
|
+ otherRevenueType: undefined,
|
|
|
|
|
+ customerId: undefined,
|
|
|
|
|
+ customerCode: undefined,
|
|
|
|
|
+ supplierId: undefined,
|
|
|
|
|
+ isPrwTax: '0',
|
|
|
|
|
+ currencyId: undefined,
|
|
|
|
|
+ pushStatus: undefined,
|
|
|
|
|
+ orderFile: undefined,
|
|
|
|
|
+ status: undefined,
|
|
|
|
|
+ remark: undefined,
|
|
|
|
|
+ companyId: undefined,
|
|
|
|
|
+ businessDept: undefined,
|
|
|
|
|
+ customerService: undefined,
|
|
|
|
|
+ businessStaff: undefined,
|
|
|
|
|
+ createTime: new Date().toISOString().split('T')[0],
|
|
|
|
|
+ orderRevenueDetails: []
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const data = reactive<PageData<RevenueHeaderForm, RevenueHeaderQuery>>({
|
|
|
|
|
+ form: { ...initFormData },
|
|
|
|
|
+ queryParams: {
|
|
|
|
|
+ pageNum: 1,
|
|
|
|
|
+ pageSize: 10,
|
|
|
|
|
+ revenueType: undefined,
|
|
|
|
|
+ orderRevenueCode: undefined,
|
|
|
|
|
+ incomeOrderCode: undefined,
|
|
|
|
|
+ otherRevenueType: undefined,
|
|
|
|
|
+ customerId: undefined,
|
|
|
|
|
+ supplierId: undefined,
|
|
|
|
|
+ isPrwTax: undefined,
|
|
|
|
|
+ currencyId: undefined,
|
|
|
|
|
+ pushStatus: undefined,
|
|
|
|
|
+ orderFile: undefined,
|
|
|
|
|
+ status: undefined,
|
|
|
|
|
+ platformCode: undefined,
|
|
|
|
|
+ params: {}
|
|
|
|
|
+ },
|
|
|
|
|
+ rules: {
|
|
|
|
|
+ revenueType: [{ required: true, message: '收入单类型不能为空', trigger: 'change' }],
|
|
|
|
|
+ customerCode: [{ required: true, message: '客户编号不能为空', trigger: 'blur' }],
|
|
|
|
|
+ companyId: [{ required: true, message: '所属公司不能为空', trigger: 'change' }],
|
|
|
|
|
+ currencyId: [{ required: true, message: '交易币别不能为空', trigger: 'change' }],
|
|
|
|
|
+ isPrwTax: [{ required: true, message: '是否含税不能为空', trigger: 'change' }]
|
|
|
|
|
+ }
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+const { queryParams, form, rules } = toRefs(data);
|
|
|
|
|
+
|
|
|
|
|
+// 防抖搜索客户
|
|
|
|
|
+const handleSearchCustomer = (query: string) => {
|
|
|
|
|
+ if (searchTimer) {
|
|
|
|
|
+ clearTimeout(searchTimer);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!query) {
|
|
|
|
|
+ filteredCustomerList.value = [];
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ customerSearchLoading.value = true;
|
|
|
|
|
+
|
|
|
|
|
+ searchTimer = setTimeout(async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await listCustomerInfo({
|
|
|
|
|
+ customerNo: query,
|
|
|
|
|
+ pageNum: 1,
|
|
|
|
|
+ pageSize: 10
|
|
|
|
|
+ });
|
|
|
|
|
+ filteredCustomerList.value = res.rows || [];
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('搜索客户失败:', error);
|
|
|
|
|
+ filteredCustomerList.value = [];
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ customerSearchLoading.value = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }, 500);
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 客户选择变化
|
|
|
|
|
+const handleCustomerChange = async (customerNo: string) => {
|
|
|
|
|
+ if (!customerNo) {
|
|
|
|
|
+ // 清空相关字段
|
|
|
|
|
+ form.value.customerId = undefined;
|
|
|
|
|
+ form.value.customerName = '';
|
|
|
|
|
+ form.value.companyName = '';
|
|
|
|
|
+ form.value.businessDept = '';
|
|
|
|
|
+ form.value.customerService = '';
|
|
|
|
|
+ form.value.businessStaff = '';
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 从筛选列表中找到选中的客户
|
|
|
|
|
+ const selectedCustomer = filteredCustomerList.value.find((c) => c.customerNo === customerNo);
|
|
|
|
|
+ if (!selectedCustomer) return;
|
|
|
|
|
+
|
|
|
|
|
+ // 获取客户详细信息
|
|
|
|
|
+ const res = await getCustomerInfo(selectedCustomer.id);
|
|
|
|
|
+ const customerInfo = res.data;
|
|
|
|
|
+
|
|
|
|
|
+ // 填充客户信息
|
|
|
|
|
+ form.value.customerId = customerInfo.id;
|
|
|
|
|
+ form.value.customerName = customerInfo.customerName;
|
|
|
|
|
+
|
|
|
|
|
+ // 从客户销售信息中获取业务信息
|
|
|
|
|
+ if (customerInfo.customerSalesInfoVo) {
|
|
|
|
|
+ const salesInfo = customerInfo.customerSalesInfoVo;
|
|
|
|
|
+ form.value.businessStaff = salesInfo.businessStaffName || '';
|
|
|
|
|
+ form.value.customerService = salesInfo.customerServiceName || '';
|
|
|
|
|
+ form.value.businessDept = salesInfo.businessDeptName || '';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取所属公司信息
|
|
|
|
|
+ if (customerInfo.belongCompanyId) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const companyRes = await getCompany(customerInfo.belongCompanyId);
|
|
|
|
|
+ form.value.companyName = companyRes.data.companyName || '';
|
|
|
|
|
+ form.value.companyId = customerInfo.belongCompanyId;
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('获取公司信息失败:', error);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('获取客户信息失败:', error);
|
|
|
|
|
+ ElMessage.error('获取客户信息失败');
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 加载费用类型列表
|
|
|
|
|
+const loadFeeTypeList = async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 根据revenueType决定查询条件
|
|
|
|
|
+ const queryParams: any = {
|
|
|
|
|
+ isShow: '0',
|
|
|
|
|
+ pageNum: 1,
|
|
|
|
|
+ pageSize: 1000
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ if (form.value.revenueType === '0') {
|
|
|
|
|
+ // 收入申请:查询收入类
|
|
|
|
|
+ queryParams.revenueFlag = '0';
|
|
|
|
|
+ } else if (form.value.revenueType === '1') {
|
|
|
|
|
+ // 费用申请:查询费用类
|
|
|
|
|
+ queryParams.expenseFlag = '0';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const res = await listRevenueExpense(queryParams);
|
|
|
|
|
+ feeTypeList.value = res.rows || [];
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('加载费用类型列表失败:', error);
|
|
|
|
|
+ feeTypeList.value = [];
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 加载币种列表
|
|
|
|
|
+const loadCurrencyList = async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await listComCurrency({
|
|
|
|
|
+ isShow: '0',
|
|
|
|
|
+ pageNum: 1,
|
|
|
|
|
+ pageSize: 1000
|
|
|
|
|
+ });
|
|
|
|
|
+ currencyList.value = res.rows || [];
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('加载币种列表失败:', error);
|
|
|
|
|
+ currencyList.value = [];
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 新增明细行
|
|
|
|
|
+const handleAddDetail = () => {
|
|
|
|
|
+ detailList.value.push({
|
|
|
|
|
+ revenueId: undefined,
|
|
|
|
|
+ quantity: 0,
|
|
|
|
|
+ unitPrice: 0,
|
|
|
|
|
+ totalAmount: 0,
|
|
|
|
|
+ remark: ''
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 数量或单价变化时自动计算总金额
|
|
|
|
|
+const handleQuantityOrPriceChange = (index: number) => {
|
|
|
|
|
+ const detail = detailList.value[index];
|
|
|
|
|
+ if (detail) {
|
|
|
|
|
+ const quantity = Number(detail.quantity) || 0;
|
|
|
|
|
+ const unitPrice = Number(detail.unitPrice) || 0;
|
|
|
|
|
+ detail.totalAmount = quantity * unitPrice;
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 删除明细行
|
|
|
|
|
+const handleDeleteDetail = (index: number) => {
|
|
|
|
|
+ detailList.value.splice(index, 1);
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 计算总金额(手动触发)
|
|
|
|
|
+const calculateTotal = () => {
|
|
|
|
|
+ // 触发计算属性重新计算
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 提交表单
|
|
|
|
|
+const submitForm = async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ await revenueHeaderFormRef.value?.validate();
|
|
|
|
|
+
|
|
|
|
|
+ // 验证是否有明细数据
|
|
|
|
|
+ if (!detailList.value || detailList.value.length === 0) {
|
|
|
|
|
+ ElMessage.warning('请至少添加一条其他信息');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ buttonLoading.value = true;
|
|
|
|
|
+
|
|
|
|
|
+ // 组装明细数据到 orderRevenueDetails
|
|
|
|
|
+ form.value.orderRevenueDetails = detailList.value.map((detail) => ({
|
|
|
|
|
+ revenueId: detail.revenueId,
|
|
|
|
|
+ quantity: detail.quantity,
|
|
|
|
|
+ unitPrice: detail.unitPrice,
|
|
|
|
|
+ totalAmount: detail.totalAmount,
|
|
|
|
|
+ remark: detail.remark
|
|
|
|
|
+ }));
|
|
|
|
|
+
|
|
|
|
|
+ // 调用保存接口
|
|
|
|
|
+ if (form.value.id) {
|
|
|
|
|
+ await updateRevenueHeader(form.value);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ await addRevenueHeader(form.value);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ElMessage.success('保存成功');
|
|
|
|
|
+ // 跳转回列表页
|
|
|
|
|
+ router.push('/order-center/order-revenue');
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('保存失败:', error);
|
|
|
|
|
+ if (error !== false) {
|
|
|
|
|
+ ElMessage.error('保存失败,请检查数据后重试');
|
|
|
|
|
+ }
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ buttonLoading.value = false;
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 返回按钮
|
|
|
|
|
+const handleBack = () => {
|
|
|
|
|
+ router.back();
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 取消
|
|
|
|
|
+const cancel = () => {
|
|
|
|
|
+ router.back();
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 页面标题
|
|
|
|
|
+const pageTitle = computed(() => {
|
|
|
|
|
+ const isEdit = !!route.query.id;
|
|
|
|
|
+ if (isEdit) {
|
|
|
|
|
+ return form.value.revenueType === '1' ? '编辑费用申请单' : '编辑收入申请单';
|
|
|
|
|
+ }
|
|
|
|
|
+ return form.value.revenueType === '1' ? '新增费用申请单' : '新增收入申请单';
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+// 加载订单详情
|
|
|
|
|
+const loadOrderDetail = async (id: string | number) => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await getRevenueHeader(id);
|
|
|
|
|
+ const data = res.data;
|
|
|
|
|
+
|
|
|
|
|
+ // 填充表单数据
|
|
|
|
|
+ Object.assign(form.value, data);
|
|
|
|
|
+
|
|
|
|
|
+ // 填充明细列表
|
|
|
|
|
+ if (data.orderRevenueDetailList && data.orderRevenueDetailList.length > 0) {
|
|
|
|
|
+ detailList.value = data.orderRevenueDetailList.map((item: any) => ({
|
|
|
|
|
+ revenueId: item.revenueId,
|
|
|
|
|
+ quantity: item.quantity || 0,
|
|
|
|
|
+ unitPrice: item.unitPrice || 0,
|
|
|
|
|
+ totalAmount: item.totalAmount || 0,
|
|
|
|
|
+ remark: item.remark || ''
|
|
|
|
|
+ }));
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('加载订单详情失败:', error);
|
|
|
|
|
+ ElMessage.error('加载订单详情失败');
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 组件挂载时加载数据
|
|
|
|
|
+onMounted(async () => {
|
|
|
|
|
+ // 从路由参数获取revenueType和id
|
|
|
|
|
+ const revenueType = route.query.revenueType as string;
|
|
|
|
|
+ const orderId = route.query.id as string;
|
|
|
|
|
+
|
|
|
|
|
+ if (revenueType) {
|
|
|
|
|
+ form.value.revenueType = revenueType;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 默认为收入申请
|
|
|
|
|
+ form.value.revenueType = '0';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 加载基础数据
|
|
|
|
|
+ await loadFeeTypeList();
|
|
|
|
|
+ await loadCurrencyList();
|
|
|
|
|
+
|
|
|
|
|
+ // 如果有id,说明是编辑模式,加载订单详情
|
|
|
|
|
+ if (orderId) {
|
|
|
|
|
+ await loadOrderDetail(orderId);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 新增模式,默认添加一个空行
|
|
|
|
|
+ handleAddDetail();
|
|
|
|
|
+ }
|
|
|
|
|
+});
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped lang="scss">
|
|
|
|
|
+.mb-2 {
|
|
|
|
|
+ margin-bottom: 16px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.mt-4 {
|
|
|
|
|
+ margin-top: 16px;
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|