<template>
|
<div class="app-container">
|
<div class="search_form">
|
<el-form :model="searchForm" :inline="true">
|
<el-form-item label="客户名称:">
|
<el-input v-model="searchForm.customerName" placeholder="请输入" clearable prefix-icon="Search"
|
@change="handleQuery" />
|
</el-form-item>
|
<el-form-item label="客户合同号:">
|
<el-input v-model="searchForm.customerContractNo" placeholder="请输入" clearable prefix-icon="Search"
|
@change="handleQuery" />
|
</el-form-item>
|
<el-form-item label="销售合同号:">
|
<el-input v-model="searchForm.salesContractNo" placeholder="请输入" clearable prefix-icon="Search"
|
@change="handleQuery" />
|
</el-form-item>
|
<el-form-item label="项目名称:">
|
<el-input v-model="searchForm.projectName" placeholder="请输入" clearable prefix-icon="Search"
|
@change="handleQuery" />
|
</el-form-item>
|
<el-form-item label="录入日期:">
|
<el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
|
placeholder="请选择" clearable @change="changeDaterange" />
|
</el-form-item>
|
<el-form-item>
|
<el-button type="primary" @click="handleQuery"> 搜索 </el-button>
|
</el-form-item>
|
</el-form>
|
</div>
|
<div class="table_list">
|
<div class="actions">
|
<div></div>
|
<div>
|
<el-button type="primary" @click="openForm('add')">
|
新增台账
|
</el-button>
|
<el-button @click="handleOut">导出</el-button>
|
<el-button type="danger" plain @click="handleDelete">删除</el-button>
|
<el-button type="primary" plain @click="handlePrint">打印</el-button>
|
</div>
|
</div>
|
<el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange"
|
:expand-row-keys="expandedRowKeys" :row-key="(row) => row.id" show-summary style="width: 100%"
|
:summary-method="summarizeMainTable" @expand-change="expandChange" height="calc(100vh - 18.5em)">
|
<el-table-column align="center" type="selection" width="55" />
|
<el-table-column type="expand">
|
<template #default="props">
|
<el-table :data="props.row.children" border show-summary :summary-method="summarizeChildrenTable">
|
<el-table-column align="center" label="序号" type="index" width="60" />
|
<el-table-column label="产品大类" prop="productCategory" />
|
<el-table-column label="规格型号" prop="specificationModel" />
|
<el-table-column label="单位" prop="unit" />
|
<el-table-column label="数量" prop="quantity" />
|
<el-table-column label="税率(%)" prop="taxRate" />
|
<el-table-column label="含税单价(元)" prop="taxInclusiveUnitPrice" :formatter="formattedNumber" />
|
<el-table-column label="含税总价(元)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" />
|
<el-table-column label="不含税总价(元)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" />
|
</el-table>
|
</template>
|
</el-table-column>
|
<el-table-column align="center" label="序号" type="index" width="60" />
|
<el-table-column label="销售合同号" prop="salesContractNo" width="180" show-overflow-tooltip />
|
<el-table-column label="客户合同号" prop="customerContractNo" width="180" show-overflow-tooltip />
|
<el-table-column label="客户名称" prop="customerName" width="300" show-overflow-tooltip />
|
<el-table-column label="业务员" prop="salesman" width="100" show-overflow-tooltip />
|
<el-table-column label="项目名称" prop="projectName" width="180" show-overflow-tooltip />
|
<el-table-column label="付款方式" prop="paymentMethod" show-overflow-tooltip />
|
<el-table-column label="合同金额(元)" prop="contractAmount" width="220" show-overflow-tooltip
|
:formatter="formattedNumber" />
|
<el-table-column label="录入人" prop="entryPersonName" width="100" show-overflow-tooltip />
|
<el-table-column label="录入日期" prop="entryDate" width="120" show-overflow-tooltip />
|
<el-table-column label="签订日期" prop="executionDate" width="120" show-overflow-tooltip />
|
<el-table-column fixed="right" label="操作" min-width="140" align="center">
|
<template #default="scope">
|
<el-button link type="primary" size="small" :disabled="scope.row.invoiceTotal>0 || scope.row.entryPersonName !== userStore.nickName" @click="openForm('edit', scope.row)">编辑</el-button>
|
<!-- <el-button link type="primary" size="small" @click="openForm('view', scope.row)">详情</el-button>-->
|
<el-button link type="primary" size="small" @click="downLoadFile(scope.row)">附件</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
<pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper"
|
:page="page.current" :limit="page.size" @pagination="paginationChange" />
|
</div>
|
<el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? '新增销售台账页面' : '编辑销售台账页面'" width="70%"
|
@close="closeDia">
|
<el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
|
<el-row :gutter="30">
|
<el-col :span="12">
|
<el-form-item label="销售合同号:" prop="salesContractNo">
|
<el-input v-model="form.salesContractNo" placeholder="自动生成" clearable disabled />
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="业务员:" prop="salesman">
|
<el-select v-model="form.salesman" placeholder="请选择" clearable :disabled="operationType === 'view'">
|
<el-option v-for="item in userList" :key="item.nickName" :label="item.nickName"
|
:value="item.nickName" />
|
</el-select>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row :gutter="30">
|
<el-col :span="12">
|
<el-form-item label="客户合同号:" prop="customerContractNo">
|
<el-input v-model="form.customerContractNo" placeholder="请输入" clearable :disabled="operationType === 'view'"/>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="客户名称:" prop="customerId">
|
<el-select v-model="form.customerId" placeholder="请选择" clearable :disabled="operationType === 'view'">
|
<el-option v-for="item in customerOption" :key="item.id" :label="item.customerName" :value="item.id">
|
{{
|
item.customerName + "——" + item.taxpayerIdentificationNumber
|
}}
|
</el-option>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row :gutter="30">
|
<el-col :span="12">
|
<el-form-item label="项目名称:" prop="projectName">
|
<el-input v-model="form.projectName" placeholder="请输入" clearable :disabled="operationType === 'view'" />
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="签订日期:" prop="executionDate">
|
<el-date-picker style="width: 100%" v-model="form.executionDate" value-format="YYYY-MM-DD"
|
format="YYYY-MM-DD" type="date" placeholder="请选择" clearable :disabled="operationType === 'view'" />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row :gutter="30">
|
<el-col :span="12">
|
<el-form-item label="录入人:" prop="entryPerson">
|
<el-select v-model="form.entryPerson" placeholder="请选择" clearable @change="changs" disabled>
|
<el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
|
</el-select>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="录入日期:" prop="entryDate">
|
<el-date-picker style="width: 100%" v-model="form.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
|
type="date" placeholder="请选择" clearable disabled />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row :gutter="30">
|
<el-col :span="12">
|
<el-form-item label="付款方式">
|
<el-input v-model="form.paymentMethod" placeholder="请输入" clearable :disabled="operationType === 'view'" />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row>
|
<el-form-item label="产品信息:" prop="entryDate">
|
<el-button v-if="operationType !== 'view'" type="primary" @click="openProductForm('add')">添加</el-button>
|
<el-button v-if="operationType !== 'view'" plain type="danger" @click="deleteProduct" >删除</el-button>
|
</el-form-item>
|
</el-row>
|
<el-table :data="productData" border @selection-change="productSelected" show-summary
|
:summary-method="summarizeMainTable">
|
<el-table-column align="center" type="selection" width="55" v-if="operationType !== 'view'" />
|
<el-table-column align="center" label="序号" type="index" width="60" />
|
<el-table-column label="产品大类" prop="productCategory" />
|
<el-table-column label="规格型号" prop="specificationModel" />
|
<el-table-column label="单位" prop="unit" />
|
<el-table-column label="数量" prop="quantity" />
|
<el-table-column label="税率(%)" prop="taxRate" />
|
<el-table-column label="含税单价(元)" prop="taxInclusiveUnitPrice" :formatter="formattedNumber" />
|
<el-table-column label="含税总价(元)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" />
|
<el-table-column label="不含税总价(元)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" />
|
<el-table-column fixed="right" label="操作" min-width="60" align="center" v-if="operationType !== 'view'">
|
<template #default="scope">
|
<el-button link type="primary" size="small" @click="openProductForm('edit', scope.row,scope.$index)">编辑</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
<el-row :gutter="30">
|
<el-col :span="24">
|
<el-form-item label="备注·:" prop="remark">
|
<el-input v-model="form.remark" placeholder="请输入" clearable type="textarea" :rows="2" :disabled="operationType === 'view'" />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row :gutter="30">
|
<el-col :span="24">
|
<el-form-item label="附件材料:" prop="remark">
|
<el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload
|
:headers="upload.headers" :before-upload="handleBeforeUpload" :on-error="handleUploadError"
|
:on-success="handleUploadSuccess" :on-remove="handleRemove">
|
<el-button type="primary" v-if="operationType !== 'view'">上传</el-button>
|
<template #tip v-if="operationType !== 'view'">
|
<div class="el-upload__tip">
|
文件格式支持
|
doc,docx,xls,xlsx,ppt,pptx,pdf,txt,xml,jpg,jpeg,png,gif,bmp,rar,zip,7z
|
</div>
|
</template>
|
</el-upload>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
</el-form>
|
<template #footer>
|
<div class="dialog-footer">
|
<el-button type="primary" @click="submitForm">确认</el-button>
|
<el-button @click="closeDia">取消</el-button>
|
</div>
|
</template>
|
</el-dialog>
|
<el-dialog v-model="productFormVisible" :title="productOperationType === 'add' ? '新增产品' : '编辑产品'" width="40%"
|
@close="closeProductDia">
|
<el-form :model="productForm" label-width="140px" label-position="top" :rules="productRules" ref="productFormRef">
|
<el-row :gutter="30">
|
<el-col :span="24">
|
<el-form-item label="产品大类:" prop="productCategory">
|
<!-- <el-select v-model="productForm.productCategory" placeholder="请选择" clearable>
|
<el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" :value="item.nickName"/>
|
</el-select> -->
|
<el-tree-select v-model="productForm.productCategory" placeholder="请选择" clearable check-strictly
|
@change="getModels" :data="productOptions" :render-after-expand="false" style="width: 100%" />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row :gutter="30">
|
<el-col :span="24">
|
<el-form-item label="规格型号:" prop="productModelId">
|
<el-select v-model="productForm.productModelId" placeholder="请选择" clearable @change="getProductModel">
|
<el-option v-for="item in modelOptions" :key="item.id" :label="item.model" :value="item.id" />
|
</el-select>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row :gutter="30">
|
<el-col :span="12">
|
<el-form-item label="单位:" prop="unit">
|
<el-input v-model="productForm.unit" placeholder="请输入" clearable />
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="税率(%):" prop="taxRate">
|
<el-select v-model="productForm.taxRate" placeholder="请选择" clearable @change="calculateFromTaxRate">
|
<el-option label="1" value="1" />
|
<el-option label="6" value="6" />
|
<el-option label="13" value="13" />
|
</el-select>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row :gutter="30">
|
<el-col :span="12">
|
<el-form-item label="含税单价(元):" prop="taxInclusiveUnitPrice">
|
<el-input-number :step="0.01" :min="0" v-model="productForm.taxInclusiveUnitPrice" style="width: 100%"
|
:precision="2"
|
placeholder="请输入" clearable @change="calculateFromUnitPrice" />
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="数量:" prop="quantity">
|
<el-input-number :step="0.1" :min="0" v-model="productForm.quantity" placeholder="请输入" clearable
|
:precision="2"
|
@change="calculateFromQuantity" style="width: 100%" />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row :gutter="30">
|
<el-col :span="12">
|
<el-form-item label="含税总价(元):" prop="taxInclusiveTotalPrice">
|
<el-input v-model="productForm.taxInclusiveTotalPrice" placeholder="请输入" clearable @change="calculateFromTotalPrice" />
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="不含税总价(元):" prop="taxExclusiveTotalPrice">
|
<el-input v-model="productForm.taxExclusiveTotalPrice" placeholder="请输入" clearable @change="calculateFromExclusiveTotalPrice" />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row :gutter="30">
|
<el-col :span="12">
|
<el-form-item label="发票类型:" prop="invoiceType">
|
<el-select v-model="productForm.invoiceType" placeholder="请选择" clearable>
|
<el-option label="增普票" value="增普票" />
|
<el-option label="增专票" value="增专票" />
|
</el-select>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
</el-form>
|
<template #footer>
|
<div class="dialog-footer">
|
<el-button type="primary" @click="submitProduct">确认</el-button>
|
<el-button @click="closeProductDia">取消</el-button>
|
</div>
|
</template>
|
</el-dialog>
|
<!-- 打印预览弹窗 -->
|
<el-dialog
|
v-model="printPreviewVisible"
|
title="打印预览"
|
width="90%"
|
:close-on-click-modal="false"
|
class="print-preview-dialog"
|
>
|
<div class="print-preview-container">
|
<div class="print-preview-header">
|
<el-button type="primary" @click="executePrint">执行打印</el-button>
|
<el-button @click="printPreviewVisible = false">关闭预览</el-button>
|
</div>
|
<div class="print-preview-content">
|
<div v-if="printData.length === 0" style="text-align: center; padding: 50px; color: #999;">
|
暂无打印数据
|
</div>
|
<div v-else style="text-align: center; padding: 10px; color: #666; font-size: 14px; background: #e8f4fd; margin-bottom: 10px;">
|
共 {{ printData.length }} 条数据待打印
|
</div>
|
<div v-for="(item, index) in printData" :key="index" class="print-page">
|
<div class="delivery-note">
|
<div class="header">
|
<div class="company-name">鼎诚瑞实业有限责任公司</div>
|
<div class="document-title">零售发货单</div>
|
</div>
|
|
<div class="info-section">
|
<div class="info-row">
|
<div>
|
<span class="label">发货日期:</span>
|
<span class="value">{{ formatDate(item.createTime) }}</span>
|
</div>
|
<div>
|
|
<span class="label">客户名称:</span>
|
<span class="value">{{ item.customerName || '张爱有' }}</span>
|
</div>
|
</div>
|
<div class="info-row">
|
<span class="label">单号:</span>
|
<span class="value">{{ item.salesContractNo }}</span>
|
</div>
|
</div>
|
|
<div class="table-section">
|
<table class="product-table">
|
<thead>
|
<tr>
|
<th>产品名称</th>
|
<th>规格型号</th>
|
<th>单位</th>
|
<th>单价</th>
|
<th>零售数量</th>
|
<th>零售金额</th>
|
</tr>
|
</thead>
|
<tbody>
|
<tr v-for="product in item.products" :key="product.id">
|
<td>{{ product.productCategory || '' }}</td>
|
<td>{{ product.specificationModel || '' }}</td>
|
<td>{{ product.unit || '' }}</td>
|
<td>{{ product.taxInclusiveUnitPrice || '0' }}</td>
|
<td>{{ product.quantity || '0' }}</td>
|
<td>{{ product.taxInclusiveTotalPrice || '0' }}</td>
|
</tr>
|
<tr v-if="!item.products || item.products.length === 0">
|
<td colspan="6" style="text-align: center; color: #999;">暂无产品数据</td>
|
</tr>
|
</tbody>
|
<tfoot>
|
<tr>
|
<td class="label">合计</td>
|
<td class="total-value"></td>
|
<td class="total-value"></td>
|
<td class="total-value"></td>
|
<td class="total-value">{{ getTotalQuantity(item.products) }}</td>
|
<td class="total-value">{{ getTotalAmount(item.products) }}</td>
|
</tr>
|
</tfoot>
|
</table>
|
</div>
|
|
<div class="footer-section">
|
<div class="footer-row">
|
<div class="footer-item">
|
<span class="label">收货电话:</span>
|
<span class="value"></span>
|
</div>
|
<div class="footer-item">
|
<span class="label">收货人:</span>
|
<span class="value"></span>
|
</div>
|
<div class="footer-item address-item">
|
<span class="label">收货地址:</span>
|
<span class="value address-value"></span>
|
</div>
|
</div>
|
<div class="footer-row">
|
<div class="footer-item">
|
<span class="label">操作员:</span>
|
<span class="value">{{ userStore.nickName || '撕开前' }}</span>
|
</div>
|
<div class="footer-item">
|
<span class="label">打印日期:</span>
|
<span class="value">{{ formatDateTime(new Date()) }}</span>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</el-dialog>
|
<FileList ref="fileListRef" />
|
</div>
|
</template>
|
|
<script setup>
|
import { getToken } from "@/utils/auth";
|
import pagination from "@/components/PIMTable/Pagination.vue";
|
import {onMounted, ref} from "vue";
|
import { ElMessageBox } from "element-plus";
|
import useUserStore from "@/store/modules/user";
|
import { userListNoPage } from "@/api/system/user.js";
|
import FileList from "./fileList.vue";
|
import {
|
ledgerListPage,
|
productList,
|
customerList,
|
addOrUpdateSalesLedger,
|
getSalesLedgerWithProducts,
|
delLedger,
|
addOrUpdateSalesLedgerProduct,
|
delProduct,
|
delLedgerFile,
|
} from "@/api/salesManagement/salesLedger.js";
|
import { modelList, productTreeList } from "@/api/basicData/product.js";
|
import useFormData from "@/hooks/useFormData.js";
|
import dayjs from "dayjs";
|
|
const userStore = useUserStore();
|
const { proxy } = getCurrentInstance();
|
const tableData = ref([]);
|
const productData = ref([]);
|
const selectedRows = ref([]);
|
const productSelectedRows = ref([]);
|
const userList = ref([]);
|
const customerOption = ref([]);
|
const productOptions = ref([]);
|
const modelOptions = ref([]);
|
const tableLoading = ref(false);
|
const page = reactive({
|
current: 1,
|
size: 100,
|
});
|
const total = ref(0);
|
const fileList = ref([]);
|
|
// 用户信息表单弹框数据
|
const operationType = ref("");
|
const dialogFormVisible = ref(false);
|
const data = reactive({
|
searchForm: {
|
customerName: "", // 客户名称
|
customerContractNo: "", // 客户合同编号
|
salesContractNo: "", // 销售合同编号
|
projectName: "", // 项目名称
|
entryDate: [
|
dayjs().format("YYYY-MM-DD"),
|
dayjs().add(1, "day").format("YYYY-MM-DD"),
|
], // 录入日期
|
entryDateStart: dayjs().format("YYYY-MM-DD"),
|
entryDateEnd: dayjs().add(1, "day").format("YYYY-MM-DD"),
|
},
|
form: {
|
salesContractNo: "",
|
salesman: "",
|
customerContractNo: "",
|
customerId: "",
|
projectName: "",
|
entryPerson: "",
|
entryDate: "",
|
maintenanceTime: "",
|
productData: [],
|
executionDate: "",
|
paymentMethod: "",
|
},
|
rules: {
|
salesman: [{ required: true, message: "请选择", trigger: "change" }],
|
customerContractNo: [
|
{ required: true, message: "请输入", trigger: "blur" },
|
],
|
customerId: [{ required: true, message: "请选择", trigger: "change" }],
|
projectName: [{ required: true, message: "请输入", trigger: "blur" }],
|
entryPerson: [{ required: true, message: "请选择", trigger: "change" }],
|
entryDate: [{ required: true, message: "请选择", trigger: "change" }],
|
executionDate: [{ required: true, message: "请选择", trigger: "change" }],
|
},
|
});
|
const { form, rules } = toRefs(data);
|
const { form: searchForm } = useFormData(data.searchForm);
|
// 产品表单弹框数据
|
const productFormVisible = ref(false);
|
const productOperationType = ref("");
|
const currentId = ref("");
|
const productFormData = reactive({
|
productForm: {
|
productCategory: "",
|
specificationModel: "",
|
unit: "",
|
quantity: "",
|
taxInclusiveUnitPrice: "",
|
taxRate: "",
|
taxInclusiveTotalPrice: "",
|
taxExclusiveTotalPrice: "",
|
invoiceType: "",
|
},
|
productRules: {
|
productCategory: [{ required: true, message: "请选择", trigger: "change" }],
|
productModelId: [{ required: true, message: "请选择", trigger: "change" }],
|
specificationModel: [
|
{ required: true, message: "请选择", trigger: "change" },
|
],
|
unit: [{ required: true, message: "请输入", trigger: "blur" }],
|
quantity: [{ required: true, message: "请输入", trigger: "blur" }],
|
taxInclusiveUnitPrice: [
|
{ required: true, message: "请输入", trigger: "blur" },
|
],
|
taxRate: [{ required: true, message: "请选择", trigger: "change" }],
|
taxInclusiveTotalPrice: [
|
{ required: true, message: "请输入", trigger: "blur" },
|
],
|
taxExclusiveTotalPrice: [
|
{ required: true, message: "请输入", trigger: "blur" },
|
],
|
invoiceType: [{ required: true, message: "请选择", trigger: "change" }],
|
},
|
});
|
const { productForm, productRules } = toRefs(productFormData);
|
// 防止循环计算的标志
|
const isCalculating = ref(false);
|
const upload = reactive({
|
// 上传的地址
|
url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
|
// 设置上传的请求头部
|
headers: { Authorization: "Bearer " + getToken() },
|
});
|
// 打印相关
|
const printPreviewVisible = ref(false);
|
const printData = ref([]);
|
|
const changeDaterange = (value) => {
|
if (value) {
|
searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
|
searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
|
} else {
|
searchForm.entryDateStart = undefined;
|
searchForm.entryDateEnd = undefined;
|
}
|
handleQuery();
|
};
|
|
// 查询列表
|
/** 搜索按钮操作 */
|
const handleQuery = () => {
|
page.current = 1;
|
expandedRowKeys.value = [];
|
getList();
|
};
|
const paginationChange = (obj) => {
|
page.current = obj.page;
|
page.size = obj.limit;
|
getList();
|
};
|
const getList = () => {
|
tableLoading.value = true;
|
const { entryDate, ...rest } = searchForm;
|
ledgerListPage({ ...rest, ...page })
|
.then((res) => {
|
tableLoading.value = false;
|
tableData.value = res.records;
|
tableData.value.map((item) => {
|
item.children = [];
|
});
|
total.value = res.total;
|
})
|
.catch(() => {
|
tableLoading.value = false;
|
});
|
};
|
// 获取产品大类tree数据
|
const getProductOptions = () => {
|
productTreeList().then((res) => {
|
productOptions.value = convertIdToValue(res);
|
});
|
};
|
const formattedNumber = (row, column, cellValue) => {
|
return parseFloat(cellValue).toFixed(2);
|
};
|
// 获取tree子数据
|
const getModels = (value) => {
|
productForm.value.productCategory = findNodeById(productOptions.value, value);
|
modelList({ id: value }).then((res) => {
|
modelOptions.value = res;
|
});
|
};
|
const getProductModel = (value) => {
|
console.log("value", value);
|
const index = modelOptions.value.findIndex((item) => item.id === value);
|
if (index !== -1) {
|
productForm.value.specificationModel = modelOptions.value[index].model;
|
productForm.value.unit = modelOptions.value[index].unit;
|
} else {
|
productForm.value.specificationModel = null;
|
productForm.value.unit = null;
|
}
|
};
|
const findNodeById = (nodes, productId) => {
|
for (let i = 0; i < nodes.length; i++) {
|
if (nodes[i].value === productId) {
|
return nodes[i].label; // 找到节点,返回该节点
|
}
|
if (nodes[i].children && nodes[i].children.length > 0) {
|
const foundNode = findNodeById(nodes[i].children, productId);
|
if (foundNode) {
|
return foundNode; // 在子节点中找到,返回该节点
|
}
|
}
|
}
|
return null; // 没有找到节点,返回null
|
};
|
function convertIdToValue(data) {
|
return data.map((item) => {
|
const { id, children, ...rest } = item;
|
const newItem = {
|
...rest,
|
value: id, // 将 id 改为 value
|
};
|
if (children && children.length > 0) {
|
newItem.children = convertIdToValue(children);
|
}
|
|
return newItem;
|
});
|
}
|
// 表格选择数据
|
const handleSelectionChange = (selection) => {
|
// 过滤掉子数据
|
selectedRows.value = selection.filter((item) => item.children !== undefined);
|
console.log("selection", selectedRows.value);
|
};
|
const productSelected = (selectedRows) => {
|
productSelectedRows.value = selectedRows;
|
};
|
const expandedRowKeys = ref([]);
|
// 展开行
|
const expandChange = (row, expandedRows) => {
|
if (expandedRows.length > 0) {
|
expandedRowKeys.value = [];
|
try {
|
productList({ salesLedgerId: row.id, type: 1 }).then((res) => {
|
const index = tableData.value.findIndex((item) => item.id === row.id);
|
if (index > -1) {
|
tableData.value[index].children = res.data;
|
}
|
expandedRowKeys.value.push(row.id);
|
});
|
} catch (error) {
|
console.log(error);
|
}
|
} else {
|
expandedRowKeys.value = [];
|
}
|
};
|
// 主表合计方法
|
const summarizeMainTable = (param) => {
|
return proxy.summarizeTable(param, [
|
"contractAmount",
|
"taxInclusiveTotalPrice",
|
"taxExclusiveTotalPrice",
|
]);
|
};
|
// 子表合计方法
|
const summarizeChildrenTable = (param) => {
|
return proxy.summarizeTable(param, [
|
"taxInclusiveUnitPrice",
|
"taxInclusiveTotalPrice",
|
"taxExclusiveTotalPrice",
|
]);
|
};
|
// 打开弹框
|
const openForm = async (type, row) => {
|
operationType.value = type;
|
form.value = {};
|
productData.value = [];
|
let userLists = await userListNoPage();
|
userList.value = userLists.data;
|
customerList().then((res) => {
|
customerOption.value = res;
|
});
|
form.value.entryPerson = userStore.id;
|
if (type !== "add") {
|
currentId.value = row.id;
|
getSalesLedgerWithProducts({ id: row.id, type: 1 }).then((res) => {
|
form.value = { ...res };
|
form.value.entryPerson = Number(res.entryPerson);
|
productData.value = form.value.productData;
|
fileList.value = form.value.salesLedgerFiles;
|
});
|
}
|
// let userAll = await userStore.getInfo()
|
// userList.value.forEach(element => {
|
// if(userAll.user.nickName === element.nickName && userAll.user.userName === element.userName) {
|
// form.value.entryPerson = userAll.user.userId // 设置默认业务员为当前用户
|
// }
|
// });
|
form.value.entryDate = getCurrentDate(); // 设置默认录入日期为当前日期
|
dialogFormVisible.value = true;
|
};
|
function changs(val) {
|
console.log(val);
|
}
|
// 上传前校检
|
function handleBeforeUpload(file) {
|
// 校检文件大小
|
// if (file.size > 1024 * 1024 * 10) {
|
// proxy.$modal.msgError("上传文件大小不能超过10MB!");
|
// return false;
|
// }
|
proxy.$modal.loading("正在上传文件,请稍候...");
|
return true;
|
}
|
// 上传失败
|
function handleUploadError(err) {
|
proxy.$modal.msgError("上传文件失败");
|
proxy.$modal.closeLoading();
|
}
|
// 上传成功回调
|
function handleUploadSuccess(res, file, uploadFiles) {
|
proxy.$modal.closeLoading();
|
if (res.code === 200) {
|
file.tempId = res.data.tempId;
|
proxy.$modal.msgSuccess("上传成功");
|
} else {
|
proxy.$modal.msgError(res.msg);
|
proxy.$refs.fileUpload.handleRemove(file);
|
}
|
}
|
// 移除文件
|
function handleRemove(file) {
|
if (operationType.value === "edit") {
|
let ids = [];
|
ids.push(file.id);
|
delLedgerFile(ids).then((res) => {
|
proxy.$modal.msgSuccess("删除成功");
|
});
|
}
|
}
|
// 提交表单
|
const submitForm = () => {
|
proxy.$refs["formRef"].validate((valid) => {
|
if (valid) {
|
console.log('productData.value--', productData.value)
|
if (productData.value !== null && productData.value.length > 0) {
|
form.value.productData = proxy.HaveJson(productData.value);
|
} else {
|
proxy.$modal.msgWarning("请添加产品信息");
|
return;
|
}
|
let tempFileIds = [];
|
if (fileList.value !== null && fileList.value.length > 0) {
|
tempFileIds = fileList.value.map((item) => item.tempId);
|
}
|
form.value.tempFileIds = tempFileIds;
|
form.value.type = 1;
|
addOrUpdateSalesLedger(form.value).then((res) => {
|
proxy.$modal.msgSuccess("提交成功");
|
closeDia();
|
getList();
|
});
|
}
|
});
|
};
|
// 关闭弹框
|
const closeDia = () => {
|
proxy.resetForm("formRef");
|
dialogFormVisible.value = false;
|
};
|
|
const productIndex = ref(0);
|
// 打开产品弹框
|
const openProductForm = (type, row,index) => {
|
productOperationType.value = type;
|
productForm.value = {};
|
proxy.resetForm("productFormRef");
|
if (type === "edit") {
|
productForm.value = { ...row };
|
productIndex.value = index;
|
}
|
productFormVisible.value = true;
|
getProductOptions();
|
};
|
// 提交产品表单
|
const submitProduct = () => {
|
proxy.$refs["productFormRef"].validate((valid) => {
|
if (valid) {
|
if (operationType.value === "edit") {
|
submitProductEdit();
|
} else {
|
if(productOperationType.value === "add"){
|
productData.value.push({ ...productForm.value });
|
}else{
|
productData.value[productIndex.value] = { ...productForm.value }
|
}
|
closeProductDia();
|
}
|
}
|
});
|
};
|
const submitProductEdit = () => {
|
productForm.value.salesLedgerId = currentId.value;
|
productForm.value.type = 1
|
addOrUpdateSalesLedgerProduct(productForm.value).then((res) => {
|
proxy.$modal.msgSuccess("提交成功");
|
closeProductDia();
|
getSalesLedgerWithProducts({ id: currentId.value, type: 1 }).then((res) => {
|
productData.value = res.productData;
|
});
|
});
|
};
|
// 删除产品
|
const deleteProduct = () => {
|
if (productSelectedRows.value.length === 0) {
|
proxy.$modal.msgWarning("请选择数据");
|
return;
|
}
|
if (operationType.value === "add") {
|
productSelectedRows.value.forEach((selectedRow) => {
|
const index = productData.value.findIndex(
|
(product) => product.id === selectedRow.id
|
);
|
if (index !== -1) {
|
productData.value.splice(index, 1);
|
}
|
});
|
} else {
|
let ids = [];
|
if (productSelectedRows.value.length > 0) {
|
ids = productSelectedRows.value.map((item) => item.id);
|
}
|
ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", {
|
confirmButtonText: "确认",
|
cancelButtonText: "取消",
|
type: "warning",
|
})
|
.then(() => {
|
delProduct(ids).then((res) => {
|
proxy.$modal.msgSuccess("删除成功");
|
closeProductDia();
|
getSalesLedgerWithProducts({ id: currentId.value, type: 1 }).then(
|
(res) => {
|
productData.value = res.productData;
|
}
|
);
|
});
|
})
|
.catch(() => {
|
proxy.$modal.msg("已取消");
|
});
|
}
|
};
|
// 关闭产品弹框
|
const closeProductDia = () => {
|
proxy.resetForm("productFormRef");
|
productFormVisible.value = false;
|
};
|
// 导出
|
const handleOut = () => {
|
ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", {
|
confirmButtonText: "确认",
|
cancelButtonText: "取消",
|
type: "warning",
|
})
|
.then(() => {
|
proxy.download("/sales/ledger/export", {}, "销售台账.xlsx");
|
})
|
.catch(() => {
|
proxy.$modal.msg("已取消");
|
});
|
};
|
// 删除
|
const handleDelete = () => {
|
let ids = [];
|
if (selectedRows.value.length > 0) {
|
ids = selectedRows.value.map((item) => item.id);
|
} else {
|
proxy.$modal.msgWarning("请选择数据");
|
return;
|
}
|
ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", {
|
confirmButtonText: "确认",
|
cancelButtonText: "取消",
|
type: "warning",
|
})
|
.then(() => {
|
delLedger(ids).then((res) => {
|
proxy.$modal.msgSuccess("删除成功");
|
getList();
|
});
|
})
|
.catch(() => {
|
proxy.$modal.msg("已取消");
|
});
|
};
|
|
// 打印功能
|
const handlePrint = async () => {
|
if (selectedRows.value.length === 0) {
|
proxy.$modal.msgWarning("请选择要打印的数据");
|
return;
|
}
|
|
// 显示加载状态
|
proxy.$modal.loading("正在获取产品数据,请稍候...");
|
|
try {
|
// 为每个选中的销售台账记录查询对应的产品数据
|
const printDataWithProducts = [];
|
|
for (const row of selectedRows.value) {
|
try {
|
// 调用productList接口查询产品数据
|
const productRes = await productList({ salesLedgerId: row.id, type: 1 });
|
|
// 将产品数据整合到销售台账记录中
|
const rowWithProducts = {
|
...row,
|
products: productRes.data || []
|
};
|
|
printDataWithProducts.push(rowWithProducts);
|
} catch (error) {
|
console.error(`获取销售台账 ${row.id} 的产品数据失败:`, error);
|
// 即使某个记录的产品数据获取失败,也要包含该记录
|
printDataWithProducts.push({
|
...row,
|
products: []
|
});
|
}
|
}
|
|
printData.value = printDataWithProducts;
|
console.log('打印数据(包含产品):', printData.value);
|
printPreviewVisible.value = true;
|
|
} catch (error) {
|
console.error('获取产品数据失败:', error);
|
proxy.$modal.msgError("获取产品数据失败,请重试");
|
} finally {
|
proxy.$modal.closeLoading();
|
}
|
};
|
// 执行打印
|
const executePrint = () => {
|
console.log('开始执行打印,数据条数:', printData.value.length);
|
console.log('打印数据:', printData.value);
|
|
// 创建一个新的打印窗口
|
const printWindow = window.open('', '_blank', 'width=800,height=600');
|
|
// 构建打印内容
|
let printContent = `
|
<!DOCTYPE html>
|
<html>
|
<head>
|
<meta charset="UTF-8">
|
<title>打印预览</title>
|
<style>
|
body {
|
margin: 0;
|
padding: 0;
|
font-family: "SimSun", serif;
|
background: white;
|
}
|
.print-page {
|
width: 200mm;
|
height: 75mm;
|
padding: 10mm;
|
padding-left: 20mm;
|
background: white;
|
box-sizing: border-box;
|
page-break-after: always;
|
page-break-inside: avoid;
|
}
|
.print-page:last-child {
|
page-break-after: avoid;
|
}
|
.delivery-note {
|
width: 100%;
|
height: 100%;
|
font-size: 12px;
|
line-height: 1.2;
|
display: flex;
|
flex-direction: column;
|
color: #000;
|
}
|
.header {
|
text-align: center;
|
margin-bottom: 8px;
|
}
|
.company-name {
|
font-size: 18px;
|
font-weight: bold;
|
margin-bottom: 4px;
|
}
|
.document-title {
|
font-size: 16px;
|
font-weight: bold;
|
}
|
.info-section {
|
margin-bottom: 8px;
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
}
|
.info-row {
|
line-height: 20px;
|
}
|
.label {
|
font-weight: bold;
|
width: 60px;
|
font-size: 12px;
|
}
|
.value {
|
margin-right: 20px;
|
min-width: 80px;
|
font-size: 12px;
|
}
|
.table-section {
|
margin-bottom: 40px;
|
// flex: 0.6;
|
}
|
.product-table {
|
width: 100%;
|
border-collapse: collapse;
|
border: 1px solid #000;
|
}
|
.product-table th, .product-table td {
|
border: 1px solid #000;
|
padding: 6px;
|
text-align: center;
|
font-size: 12px;
|
line-height: 1.4;
|
}
|
.product-table th {
|
font-weight: bold;
|
}
|
.total-value {
|
font-weight: bold;
|
}
|
.footer-section {
|
margin-top: auto;
|
}
|
.footer-row {
|
display: flex;
|
margin-bottom: 3px;
|
line-height: 22px;
|
justify-content: space-between;
|
}
|
.footer-item {
|
display: flex;
|
margin-right: 20px;
|
}
|
.footer-item .label {
|
font-weight: bold;
|
width: 80px;
|
font-size: 12px;
|
}
|
.footer-item .value {
|
min-width: 80px;
|
font-size: 12px;
|
}
|
.address-item .address-value {
|
min-width: 200px;
|
}
|
@media print {
|
body {
|
margin: 0;
|
padding: 0;
|
}
|
.print-page {
|
margin: 0;
|
padding: 10mm;
|
/* padding-left: 20mm; */
|
page-break-inside: avoid;
|
page-break-after: always;
|
}
|
.print-page:last-child {
|
page-break-after: avoid;
|
}
|
}
|
</style>
|
</head>
|
<body>
|
`;
|
|
// 为每条数据生成打印页面
|
printData.value.forEach((item, index) => {
|
printContent += `
|
<div class="print-page">
|
<div class="delivery-note">
|
<div class="header">
|
<div class="company-name">鼎诚瑞实业有限责任公司</div>
|
<div class="document-title">零售发货单</div>
|
</div>
|
|
<div class="info-section">
|
<div class="info-row">
|
<div>
|
<span class="label">发货日期:</span>
|
<span class="value">${formatDate(item.createTime)}</span>
|
</div>
|
<div>
|
<span class="label">客户名称:</span>
|
<span class="value">${item.customerName || '张爱有'}</span>
|
</div>
|
</div>
|
<div class="info-row">
|
<span class="label">单号:</span>
|
<span class="value">${item.salesContractNo || ''}</span>
|
</div>
|
</div>
|
|
<div class="table-section">
|
<table class="product-table">
|
<thead>
|
<tr>
|
<th>产品名称</th>
|
<th>规格型号</th>
|
<th>单位</th>
|
<th>单价</th>
|
<th>零售数量</th>
|
<th>零售金额</th>
|
</tr>
|
</thead>
|
<tbody>
|
${item.products && item.products.length > 0 ?
|
item.products.map(product => `
|
<tr>
|
<td>${product.productCategory || ''}</td>
|
<td>${product.specificationModel || ''}</td>
|
<td>${product.unit || ''}</td>
|
<td>${product.taxInclusiveUnitPrice || '0'}</td>
|
<td>${product.quantity || '0'}</td>
|
<td>${product.taxInclusiveTotalPrice || '0'}</td>
|
</tr>
|
`).join('') :
|
'<tr><td colspan="6" style="text-align: center; color: #999;">暂无产品数据</td></tr>'
|
}
|
</tbody>
|
<tfoot>
|
<tr>
|
<td class="label">合计</td>
|
<td class="total-value"></td>
|
<td class="total-value"></td>
|
<td class="total-value"></td>
|
<td class="total-value">${getTotalQuantityForPrint(item.products)}</td>
|
<td class="total-value">${getTotalAmountForPrint(item.products)}</td>
|
</tr>
|
</tfoot>
|
</table>
|
</div>
|
|
<div class="footer-section">
|
<div class="footer-row">
|
<div class="footer-item">
|
<span class="label">收货电话:</span>
|
<span class="value"></span>
|
</div>
|
<div class="footer-item">
|
<span class="label">收货人:</span>
|
<span class="value"></span>
|
</div>
|
<div class="footer-item address-item">
|
<span class="label">收货地址:</span>
|
<span class="value address-value"></span>
|
</div>
|
</div>
|
<div class="footer-row">
|
<div class="footer-item">
|
<span class="label">操作员:</span>
|
<span class="value">${userStore.nickName || '撕开前'}</span>
|
</div>
|
<div class="footer-item">
|
<span class="label">打印日期:</span>
|
<span class="value">${formatDateTime(new Date())}</span>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
`;
|
});
|
|
printContent += `
|
</body>
|
</html>
|
`;
|
|
// 写入内容到新窗口
|
printWindow.document.write(printContent);
|
printWindow.document.close();
|
|
// 等待内容加载完成后打印
|
printWindow.onload = () => {
|
setTimeout(() => {
|
printWindow.print();
|
printWindow.close();
|
printPreviewVisible.value = false;
|
}, 500);
|
};
|
};
|
// 格式化日期
|
const formatDate = (dateString) => {
|
if (!dateString) return getCurrentDate();
|
const date = new Date(dateString);
|
const year = date.getFullYear();
|
const month = String(date.getMonth() + 1).padStart(2, "0");
|
const day = String(date.getDate()).padStart(2, "0");
|
return `${year}/${month}/${day}`;
|
};
|
// 格式化日期时间
|
const formatDateTime = (date) => {
|
const year = date.getFullYear();
|
const month = String(date.getMonth() + 1).padStart(2, "0");
|
const day = String(date.getDate()).padStart(2, "0");
|
const hours = String(date.getHours()).padStart(2, "0");
|
const minutes = String(date.getMinutes()).padStart(2, "0");
|
const seconds = String(date.getSeconds()).padStart(2, "0");
|
return `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`;
|
};
|
// 获取当前日期并格式化为 YYYY-MM-DD
|
function getCurrentDate() {
|
const today = new Date();
|
const year = today.getFullYear();
|
const month = String(today.getMonth() + 1).padStart(2, "0"); // 月份从0开始
|
const day = String(today.getDate()).padStart(2, "0");
|
return `${year}-${month}-${day}`;
|
}
|
|
// 计算产品总数量
|
const getTotalQuantity = (products) => {
|
if (!products || products.length === 0) return '0';
|
const total = products.reduce((sum, product) => {
|
return sum + (parseFloat(product.quantity) || 0);
|
}, 0);
|
return total.toFixed(2);
|
};
|
|
// 计算产品总金额
|
const getTotalAmount = (products) => {
|
if (!products || products.length === 0) return '0';
|
const total = products.reduce((sum, product) => {
|
return sum + (parseFloat(product.taxInclusiveTotalPrice) || 0);
|
}, 0);
|
return total.toFixed(2);
|
};
|
|
// 用于打印的计算函数
|
const getTotalQuantityForPrint = (products) => {
|
if (!products || products.length === 0) return '0';
|
const total = products.reduce((sum, product) => {
|
return sum + (parseFloat(product.quantity) || 0);
|
}, 0);
|
return total.toFixed(2);
|
};
|
|
const getTotalAmountForPrint = (products) => {
|
if (!products || products.length === 0) return '0';
|
const total = products.reduce((sum, product) => {
|
return sum + (parseFloat(product.taxInclusiveTotalPrice) || 0);
|
}, 0);
|
return total.toFixed(2);
|
};
|
|
const mathNum = () => {
|
console.log("productForm.value", productForm.value);
|
if (!productForm.value.taxInclusiveUnitPrice) {
|
return;
|
}
|
if (!productForm.value.quantity) {
|
return;
|
}
|
// 含税总价计算
|
productForm.value.taxInclusiveTotalPrice =
|
proxy.calculateTaxIncludeTotalPrice(
|
productForm.value.taxInclusiveUnitPrice,
|
productForm.value.quantity
|
);
|
if (productForm.value.taxRate) {
|
// 不含税总价计算
|
productForm.value.taxExclusiveTotalPrice =
|
proxy.calculateTaxExclusiveTotalPrice(
|
productForm.value.taxInclusiveTotalPrice,
|
productForm.value.taxRate
|
);
|
}
|
};
|
|
// 根据含税总价计算含税单价和数量
|
const calculateFromTotalPrice = () => {
|
if (isCalculating.value) return;
|
|
const totalPrice = parseFloat(productForm.value.taxInclusiveTotalPrice);
|
const quantity = parseFloat(productForm.value.quantity);
|
|
if (!totalPrice || !quantity || quantity <= 0) {
|
return;
|
}
|
|
isCalculating.value = true;
|
|
// 计算含税单价 = 含税总价 / 数量
|
productForm.value.taxInclusiveUnitPrice = (totalPrice / quantity).toFixed(2);
|
|
// 如果有税率,计算不含税总价
|
if (productForm.value.taxRate) {
|
productForm.value.taxExclusiveTotalPrice =
|
proxy.calculateTaxExclusiveTotalPrice(
|
totalPrice,
|
productForm.value.taxRate
|
);
|
}
|
|
isCalculating.value = false;
|
};
|
|
// 根据不含税总价计算含税单价和数量
|
const calculateFromExclusiveTotalPrice = () => {
|
if (!productForm.value.taxRate) {
|
proxy.$modal.msgWarning("请先选择税率");
|
return;
|
}
|
if (isCalculating.value) return;
|
|
const exclusiveTotalPrice = parseFloat(productForm.value.taxExclusiveTotalPrice);
|
const quantity = parseFloat(productForm.value.quantity);
|
const taxRate = parseFloat(productForm.value.taxRate);
|
|
if (!exclusiveTotalPrice || !quantity || quantity <= 0 || !taxRate) {
|
return;
|
}
|
|
isCalculating.value = true;
|
|
// 先计算含税总价 = 不含税总价 / (1 - 税率/100)
|
const taxRateDecimal = taxRate / 100;
|
const inclusiveTotalPrice = exclusiveTotalPrice / (1 - taxRateDecimal);
|
productForm.value.taxInclusiveTotalPrice = inclusiveTotalPrice.toFixed(2);
|
|
// 计算含税单价 = 含税总价 / 数量
|
productForm.value.taxInclusiveUnitPrice = (inclusiveTotalPrice / quantity).toFixed(2);
|
|
isCalculating.value = false;
|
};
|
|
// 根据数量变化计算总价
|
const calculateFromQuantity = () => {
|
if (!productForm.value.taxRate) {
|
proxy.$modal.msgWarning("请先选择税率");
|
return;
|
}
|
if (isCalculating.value) return;
|
|
const quantity = parseFloat(productForm.value.quantity);
|
const unitPrice = parseFloat(productForm.value.taxInclusiveUnitPrice);
|
|
if (!quantity || quantity <= 0 || !unitPrice) {
|
return;
|
}
|
|
isCalculating.value = true;
|
|
// 计算含税总价
|
productForm.value.taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
|
|
// 如果有税率,计算不含税总价
|
if (productForm.value.taxRate) {
|
productForm.value.taxExclusiveTotalPrice =
|
proxy.calculateTaxExclusiveTotalPrice(
|
productForm.value.taxInclusiveTotalPrice,
|
productForm.value.taxRate
|
);
|
}
|
|
isCalculating.value = false;
|
};
|
|
// 根据含税单价变化计算总价
|
const calculateFromUnitPrice = () => {
|
if (!productForm.value.taxRate) {
|
proxy.$modal.msgWarning("请先选择税率");
|
return;
|
}
|
if (isCalculating.value) return;
|
|
const quantity = parseFloat(productForm.value.quantity);
|
const unitPrice = parseFloat(productForm.value.taxInclusiveUnitPrice);
|
|
if (!quantity || quantity <= 0 || !unitPrice) {
|
return;
|
}
|
|
isCalculating.value = true;
|
|
// 计算含税总价
|
productForm.value.taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
|
|
// 如果有税率,计算不含税总价
|
if (productForm.value.taxRate) {
|
productForm.value.taxExclusiveTotalPrice =
|
proxy.calculateTaxExclusiveTotalPrice(
|
productForm.value.taxInclusiveTotalPrice,
|
productForm.value.taxRate
|
);
|
}
|
|
isCalculating.value = false;
|
};
|
|
// 根据税率变化计算不含税总价
|
const calculateFromTaxRate = () => {
|
if (!productForm.value.taxRate) {
|
proxy.$modal.msgWarning("请先选择税率");
|
return;
|
}
|
if (isCalculating.value) return;
|
|
const inclusiveTotalPrice = parseFloat(productForm.value.taxInclusiveTotalPrice);
|
const taxRate = parseFloat(productForm.value.taxRate);
|
|
if (!inclusiveTotalPrice || !taxRate) {
|
return;
|
}
|
|
isCalculating.value = true;
|
|
// 计算不含税总价
|
productForm.value.taxExclusiveTotalPrice =
|
proxy.calculateTaxExclusiveTotalPrice(
|
inclusiveTotalPrice,
|
taxRate
|
);
|
|
isCalculating.value = false;
|
};
|
/**
|
* 下载文件
|
*
|
* @param row 下载文件的相关信息对象
|
*/
|
const fileListRef = ref(null)
|
const downLoadFile = (row) => {
|
getSalesLedgerWithProducts({ id: row.id, type: 1 }).then((res) => {
|
fileListRef.value.open(res.salesLedgerFiles)
|
});
|
|
}
|
onMounted(() => {
|
getList();
|
});
|
</script>
|
|
<style scoped lang="scss">
|
.ml-10 {
|
margin-left: 10px;
|
}
|
|
.table_list {
|
margin-top: unset;
|
}
|
|
.actions {
|
display: flex;
|
justify-content: space-between;
|
margin-bottom: 10px;
|
}
|
.print-preview-dialog {
|
.el-dialog__body {
|
padding: 0;
|
max-height: 80vh;
|
overflow-y: auto;
|
}
|
}
|
|
.print-preview-container {
|
.print-preview-header {
|
padding: 15px;
|
border-bottom: 1px solid #e4e7ed;
|
text-align: center;
|
|
.el-button {
|
margin: 0 10px;
|
}
|
}
|
|
.print-preview-content {
|
padding: 20px;
|
background-color: #f5f5f5;
|
min-height: 400px;
|
}
|
}
|
|
.print-page {
|
width: 220mm;
|
height: 90mm;
|
padding: 10mm;
|
margin: 0 auto;
|
background: white;
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
margin-bottom: 10px;
|
box-sizing: border-box;
|
}
|
|
.delivery-note {
|
width: 100%;
|
height: 100%;
|
font-family: "SimSun", serif;
|
font-size: 10px;
|
line-height: 1.2;
|
display: flex;
|
flex-direction: column;
|
}
|
|
.header {
|
text-align: center;
|
margin-bottom: 8px;
|
|
.company-name {
|
font-size: 18px;
|
font-weight: bold;
|
margin-bottom: 4px;
|
}
|
|
.document-title {
|
font-size: 16px;
|
font-weight: bold;
|
}
|
}
|
|
.info-section {
|
margin-bottom: 8px;
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
|
.info-row {
|
line-height: 20px;
|
|
.label {
|
font-weight: bold;
|
width: 60px;
|
font-size: 14px;
|
}
|
|
.value {
|
margin-right: 20px;
|
min-width: 80px;
|
font-size: 14px;
|
}
|
}
|
}
|
|
.table-section {
|
margin-bottom: 4px;
|
flex: 1;
|
|
.product-table {
|
width: 100%;
|
border-collapse: collapse;
|
border: 1px solid #000;
|
|
th, td {
|
border: 1px solid #000;
|
padding: 6px;
|
text-align: center;
|
font-size: 14px;
|
line-height: 1.4;
|
}
|
|
th {
|
font-weight: bold;
|
}
|
|
.total-label {
|
text-align: right;
|
font-weight: bold;
|
}
|
|
.total-value {
|
font-weight: bold;
|
}
|
}
|
}
|
|
.footer-section {
|
.footer-row {
|
display: flex;
|
margin-bottom: 3px;
|
line-height: 20px;
|
justify-content: space-between;
|
|
.footer-item {
|
display: flex;
|
margin-right: 20px;
|
|
.label {
|
font-weight: bold;
|
width: 80px;
|
font-size: 14px;
|
}
|
|
.value {
|
min-width: 80px;
|
font-size: 14px;
|
}
|
|
&.address-item {
|
.address-value {
|
min-width: 200px;
|
}
|
}
|
}
|
}
|
}
|
|
@media print {
|
.app-container {
|
display: none;
|
}
|
|
.print-page {
|
box-shadow: none;
|
margin: 0;
|
padding: 10mm;
|
padding-left: 20mm;
|
page-break-inside: avoid;
|
page-break-after: always;
|
}
|
.print-page:last-child {
|
page-break-after: avoid;
|
}
|
}
|
</style>
|