| | |
| | | <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="å½å
¥æ¥æï¼"> |
| | |
| | | </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 - 21em)"> |
| | | :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-column label="产å大类" prop="productCategory" /> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" /> |
| | | <el-table-column label="åä½" prop="unit" /> |
| | | <el-table-column label="产åç¶æ" width="100px" align="center"> |
| | | <template #default="scope"> |
| | | <el-tag v-if="scope.row.approveStatus === 0" type="info">æªåºåº</el-tag> |
| | | <el-tag v-if="scope.row.approveStatus === 1" type="success">å·²åºåº</el-tag> |
| | | <el-tag v-if="scope.row.approveStatus === 2" type="warning">å®¡æ ¸ä¸</el-tag> |
| | | <el-tag v-if="scope.row.approveStatus === 3" type="success">å®¡æ ¸æå</el-tag> |
| | | <el-tag v-if="scope.row.approveStatus === 4" type="danger">å®¡æ ¸å¤±è´¥</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å货车ç" minWidth="100px" align="center"> |
| | | <template #default="scope"> |
| | | <div> |
| | | <el-tag type="success" v-if="scope.row.shippingCarNumber">{{ scope.row.shippingCarNumber }}</el-tag> |
| | | <el-tag v-else type="info">æªåè´§</el-tag> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="åè´§æ¥æ" minWidth="100px" align="center"> |
| | | <template #default="scope"> |
| | | <div> |
| | | <div v-if="scope.row.shippingDate">{{ scope.row.shippingDate }}</div> |
| | | <el-tag v-else type="info">æªåè´§</el-tag> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <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 Width="60px" label="æä½" align="center"> |
| | | <template #default="scope"> |
| | | <el-button :disabled="scope.row.approveStatus!==2 || scope.row.approveStatus!==5" link type="primary" size="small" @click="openDeliveryForm(scope.row)">åè´§</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </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="productionStatus" width="100" show-overflow-tooltip > |
| | | <template #default="scope"> |
| | | <div> |
| | | <el-tag v-if="scope.row.productionStatus === '已宿'" type="success">已宿</el-tag> |
| | | <el-tag v-if="scope.row.productionStatus === 'ç产ä¸'" type="warning">ç产ä¸</el-tag> |
| | | <el-tag v-if="scope.row.productionStatus === 'æªå¼å§'" type="danger">æªå¼å§</el-tag> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å货车ç" prop="shippingCarNumber" width="120" show-overflow-tooltip> |
| | | <template #default="scope"> |
| | | <div> |
| | | <div v-if="scope.row.shippingCarNumber">{{ scope.row.shippingCarNumber }}</div> |
| | | <el-tag v-else type="warning">æªåè´§</el-tag> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="åè´§æ¥æ" prop="shippingDate" width="120" show-overflow-tooltip /> |
| | | <el-table-column label="ç¾è®¢æ¥æ" prop="executionDate" width="120" show-overflow-tooltip /> |
| | | <el-table-column label="å½å
¥æ¥æ" prop="entryDate" width="120" show-overflow-tooltip /> |
| | | <el-table-column fixed="right" label="æä½" min-width="200" align="center"> |
| | | <el-table-column label="ç¾è®¢æ¥æ" prop="executionDate" width="120" show-overflow-tooltip /> |
| | | <el-table-column fixed="right" label="æä½" min-width="100" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" @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> |
| | | <el-button v-if="!scope.row.shippingCarNumber" link type="primary" size="small" @click="openDeliveryForm(scope.row)">åè´§</el-button> |
| | | <!-- <el-button link type="primary" size="small" @click="openDeliveryForm(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> |
| | | <FormDialog |
| | | v-model="dialogFormVisible" |
| | | :title="operationType === 'add' ? 'æ°å¢éå®å°è´¦é¡µé¢' : 'ç¼è¾éå®å°è´¦é¡µé¢'" |
| | | :width="'70%'" |
| | | :operation-type="operationType" |
| | | @close="closeDia" |
| | | @confirm="submitForm" |
| | | @cancel="closeDia"> |
| | | <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 v-if="operationType !== 'view'"> |
| | | <el-col :span="24" style="display:flex; justify-content:flex-end; gap:10px; margin-bottom: 6px;"> |
| | | <el-button type="primary" plain @click="openQuotationDialog">ä»å®¡æ¹éè¿çæ¥ä»·å导å
¥</el-button> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="éå®ååå·ï¼" prop="salesContractNo"> |
| | |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä¸å¡åï¼" prop="salesman"> |
| | | <el-select v-model="form.salesman" |
| | | filterable |
| | | :reserve-keyword="false" placeholder="è¯·éæ©" clearable :disabled="operationType === 'view'"> |
| | | <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-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'" filterable> |
| | | <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-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å½å
¥äººï¼" prop="entryPerson"> |
| | | <el-select v-model="form.entryPerson" |
| | | filterable |
| | | default-first-option |
| | | :reserve-keyword="false" placeholder="è¯·éæ©" clearable @change="changs"> |
| | | <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-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-col> |
| | | </el-row> |
| | | </el-form> |
| | | </FormDialog> |
| | | |
| | | <!-- 仿¥ä»·å导å
¥ï¼ä»
审æ¹éè¿ï¼ --> |
| | | <el-dialog |
| | | v-model="quotationDialogVisible" |
| | | title="鿩审æ¹éè¿çé宿¥ä»·å" |
| | | width="80%" |
| | | :close-on-click-modal="false" |
| | | > |
| | | <div style="margin-bottom: 12px; display:flex; gap: 12px; align-items:center;"> |
| | | <el-input |
| | | v-model="quotationSearchForm.quotationNo" |
| | | placeholder="请è¾å
¥æ¥ä»·åå·" |
| | | clearable |
| | | style="max-width: 260px;" |
| | | @change="fetchQuotationList" |
| | | /> |
| | | <el-input |
| | | v-model="quotationSearchForm.customer" |
| | | placeholder="请è¾å
¥å®¢æ·åç§°" |
| | | clearable |
| | | style="max-width: 260px;" |
| | | @change="fetchQuotationList" |
| | | /> |
| | | <el-button type="primary" @click="fetchQuotationList">æç´¢</el-button> |
| | | <el-button @click="resetQuotationSearch">éç½®</el-button> |
| | | </div> |
| | | |
| | | <el-table |
| | | :data="quotationList" |
| | | border |
| | | stripe |
| | | v-loading="quotationLoading" |
| | | height="420px" |
| | | > |
| | | <el-table-column align="center" label="åºå·" type="index" width="60" /> |
| | | <el-table-column prop="quotationNo" label="æ¥ä»·åå·" width="180" show-overflow-tooltip /> |
| | | <el-table-column prop="customer" label="客æ·åç§°" min-width="220" show-overflow-tooltip /> |
| | | <el-table-column prop="salesperson" label="ä¸å¡å" width="120" show-overflow-tooltip /> |
| | | <el-table-column prop="quotationDate" label="æ¥ä»·æ¥æ" width="140" /> |
| | | <el-table-column prop="status" label="审æ¹ç¶æ" width="120" align="center" /> |
| | | <el-table-column prop="totalAmount" label="æ¥ä»·éé¢(å
)" width="160" align="right"> |
| | | <template #default="scope"> |
| | | {{ Number(scope.row.totalAmount ?? 0).toFixed(2) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column fixed="right" label="æä½" width="120" align="center"> |
| | | <template #default="scope"> |
| | | <el-button type="primary" link @click="applyQuotation(scope.row)">éæ©</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <template #footer> |
| | | <el-button @click="quotationDialogVisible = false">å
³é</el-button> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确认</el-button> |
| | | <el-button @click="closeDia">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | <FormDialog |
| | | v-model="productFormVisible" |
| | | :title="productOperationType === 'add' ? 'æ°å¢äº§å' : 'ç¼è¾äº§å'" |
| | | :width="'40%'" |
| | | :operation-type="productOperationType" |
| | | @close="closeProductDia" |
| | | @confirm="submitProduct" |
| | | @cancel="closeProductDia"> |
| | | <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-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="è§æ ¼åå·ï¼" prop="productModelId"> |
| | | <el-select v-model="productForm.productModelId" placeholder="è¯·éæ©" clearable @change="getProductModel" filterable> |
| | | <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-form> |
| | | </FormDialog> |
| | | <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" |
| | |
| | | <span class="value">{{ formatDate(item.createTime) }}</span> |
| | | </div> |
| | | <div> |
| | | <span class="label">å货车çå·ï¼</span> |
| | | <span class="value">{{ item.shippingCarNumber }}</span> |
| | | </div> |
| | | </div> |
| | | <div class="info-row"> |
| | | <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> |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="审æ¹äººï¼" prop="approverId"> |
| | | <el-select v-model="deliveryForm.approverId" placeholder="è¯·éæ©å®¡æ¹äºº" clearable :disabled="operationType === 'view'"> |
| | | <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | <FileListDialog ref="fileListRef" v-model="fileListDialogVisible" /> |
| | | <FileList ref="fileListRef" /> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | import pagination from "@/components/PIMTable/Pagination.vue"; |
| | | import {onMounted, ref} from "vue"; |
| | | import { addShippingInfo } from "@/api/salesManagement/deliveryLedger.js"; |
| | | import { ElMessageBox } from "element-plus"; |
| | | import {ElMessage, ElMessageBox} from "element-plus"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import { userListNoPage } from "@/api/system/user.js"; |
| | | import FileListDialog from '@/components/Dialog/FileListDialog.vue'; |
| | | import FormDialog from '@/components/Dialog/FormDialog.vue'; |
| | | import { getQuotationList } from "@/api/salesManagement/salesQuotation.js"; |
| | | import FileList from "./fileList.vue"; |
| | | import { |
| | | ledgerListPage, |
| | | productList, |
| | |
| | | import { modelList, productTreeList } from "@/api/basicData/product.js"; |
| | | import useFormData from "@/hooks/useFormData.js"; |
| | | import dayjs from "dayjs"; |
| | | import { getCurrentDate } from "@/utils/index.js"; |
| | | |
| | | const userStore = useUserStore(); |
| | | const { proxy } = getCurrentInstance(); |
| | |
| | | const data = reactive({ |
| | | searchForm: { |
| | | customerName: "", // 客æ·åç§° |
| | | customerContractNo: "", // 客æ·ååç¼å· |
| | | salesContractNo: "", // éå®ååç¼å· |
| | | projectName: "", // 项ç®åç§° |
| | | entryDate: null, // å½å
¥æ¥æ |
| | | entryDateStart: undefined, |
| | | entryDateEnd: undefined, |
| | |
| | | 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 printPreviewVisible = ref(false); |
| | | const printData = ref([]); |
| | | |
| | | // æ¥ä»·å导å
¥ç¸å
³ |
| | | const quotationDialogVisible = ref(false); |
| | | const quotationLoading = ref(false); |
| | | const quotationList = ref([]); |
| | | const quotationSearchForm = reactive({ |
| | | quotationNo: "", |
| | | customer: "", |
| | | }); |
| | | const selectedQuotation = ref(null); |
| | | |
| | | // åè´§ç¸å
³ |
| | | const deliveryFormVisible = ref(false); |
| | | const currentDeliveryRow = ref(null); |
| | |
| | | shippingCarNumber: [ |
| | | { required: true, message: "请è¾å
¥å货车çå·", trigger: "blur" } |
| | | ], |
| | | approverId:[ |
| | | { |
| | | required: true,message: "", |
| | | } |
| | | ] |
| | | }, |
| | | }); |
| | | const { deliveryForm, deliveryRules } = toRefs(deliveryFormData); |
| | |
| | | // æ¥è¯¢å表 |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | // åªæå¨ç¹å»æç´¢æé®æ¶æé置页ç å°ç¬¬ä¸é¡µ |
| | | // é¿å
表ååæ®µchangeäºä»¶å¹²æ°å页 |
| | | if (arguments.length === 0) { |
| | | page.current = 1; |
| | | } |
| | | expandedRowKeys.value = []; |
| | | getList(); |
| | | }; |
| | |
| | | page.size = obj.limit; |
| | | getList(); |
| | | }; |
| | | const getList = () => { |
| | | const getList =async () => { |
| | | let userLists = await userListNoPage(); |
| | | userList.value = userLists.data; |
| | | tableLoading.value = true; |
| | | const { entryDate, ...rest } = searchForm; |
| | | // å°èå´æ¥æåæ®µä¼ éç»å端 |
| | | const params = { ...rest, ...page }; |
| | | // ç§»é¤å½å
¥æ¥æçé»è®¤å¼è®¾ç½®ï¼åªä¿çèå´æ¥æå段 |
| | | delete params.entryDate; |
| | | ledgerListPage(params) |
| | | ledgerListPage({ ...rest, ...page }) |
| | | .then((res) => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.records; |
| | |
| | | }; |
| | | // è·å产å大类treeæ°æ® |
| | | const getProductOptions = () => { |
| | | // è¿å Promiseï¼ä¾¿äºå¨ç¼è¾äº§åæ¶çå¾
å è½½å®æ |
| | | return productTreeList().then((res) => { |
| | | productTreeList().then((res) => { |
| | | productOptions.value = convertIdToValue(res); |
| | | return productOptions.value; |
| | | }); |
| | | }; |
| | | const formattedNumber = (row, column, cellValue) => { |
| | |
| | | }); |
| | | }; |
| | | 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; |
| | |
| | | return newItem; |
| | | }); |
| | | } |
| | | // æ ¹æ®åç§°åæ¥äº§å大类 idï¼ä¾¿äºä»
ååç§°æ¶çåæ¾ |
| | | function findNodeIdByLabel(nodes, label) { |
| | | if (!label) return null; |
| | | for (let i = 0; i < nodes.length; i++) { |
| | | const node = nodes[i]; |
| | | if (node.label === label) return node.value; |
| | | if (node.children && node.children.length > 0) { |
| | | const found = findNodeIdByLabel(node.children, label); |
| | | if (found !== null && found !== undefined) return found; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | | const handleSelectionChange = (selection) => { |
| | | // è¿æ»¤æåæ°æ® |
| | |
| | | productSelectedRows.value = selectedRows; |
| | | }; |
| | | const expandedRowKeys = ref([]); |
| | | // å±å¼è¡ |
| | | const expandChange = (row, expandedRows) => { |
| | | if (expandedRows.length > 0) { |
| | | // å±å¼è¡ï¼å§ç»åªå±å¼ä¸è¡ï¼ |
| | | const expandChange = (row) => { |
| | | const rowKey = row.id; |
| | | const isExpanded = expandedRowKeys.value.includes(rowKey); |
| | | |
| | | if (isExpanded) { |
| | | // å½åè¡å·²å±å¼ -> æ¶èµ· |
| | | expandedRowKeys.value = []; |
| | | return; |
| | | } |
| | | |
| | | // å±å¼å½åè¡åï¼å
æ¶èµ·å
¶å®è¡ |
| | | 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); |
| | | // åªä¿çå½åè¿ä¸è¡å¤äºå±å¼ç¶æ |
| | | expandedRowKeys.value = [rowKey]; |
| | | }); |
| | | } catch (error) { |
| | | console.log(error); |
| | | } |
| | | } else { |
| | | expandedRowKeys.value = []; |
| | | } |
| | | }; |
| | | // 主表åè®¡æ¹æ³ |
| | |
| | | operationType.value = type; |
| | | form.value = {}; |
| | | productData.value = []; |
| | | selectedQuotation.value = null; |
| | | let userLists = await userListNoPage(); |
| | | userList.value = userLists.data; |
| | | customerList().then((res) => { |
| | | customerOption.value = res; |
| | | }); |
| | | form.value.entryPerson = userStore.id; |
| | | if (type === "add") { |
| | | // æ°å¢æ¶è®¾ç½®å½å
¥æ¥æä¸ºå½å¤© |
| | | form.value.entryDate = getCurrentDate(); |
| | | // ç¾è®¢æ¥æé»è®¤ä¸ºå½å¤© |
| | | form.value.executionDate = getCurrentDate(); |
| | | } else { |
| | | if (type !== "add") { |
| | | currentId.value = row.id; |
| | | getSalesLedgerWithProducts({ id: row.id, type: 1 }).then((res) => { |
| | | form.value = { ...res }; |
| | |
| | | // }); |
| | | form.value.entryDate = getCurrentDate(); // 设置é»è®¤å½å
¥æ¥æä¸ºå½åæ¥æ |
| | | dialogFormVisible.value = true; |
| | | }; |
| | | |
| | | // æå¼æ¥ä»·å鿩弹çªï¼ä»
审æ¹éè¿ï¼ |
| | | const openQuotationDialog = async () => { |
| | | if (operationType.value === "view") return; |
| | | quotationDialogVisible.value = true; |
| | | // å
ç¡®ä¿å®¢æ·å表已å è½½ï¼ä¾¿äºåç»åå¡« customerId |
| | | if (!customerOption.value || customerOption.value.length === 0) { |
| | | try { |
| | | const res = await customerList(); |
| | | customerOption.value = res; |
| | | } catch (e) { |
| | | // ignoreï¼å
è®¸ç¨æ·åç»æå¨éæ©å®¢æ· |
| | | } |
| | | } |
| | | await fetchQuotationList(); |
| | | }; |
| | | |
| | | const fetchQuotationList = async () => { |
| | | quotationLoading.value = true; |
| | | try { |
| | | const params = { |
| | | // å
¼å®¹å端å页忮µï¼è¿éæ²¿ç¨æ¥ä»·é¡µé¢å·²æå¯ç¨çåæ®µå½å |
| | | currentPage: 1, |
| | | pageSize: 100, |
| | | ...quotationSearchForm, |
| | | status: "éè¿", |
| | | }; |
| | | const res = await getQuotationList(params); |
| | | quotationList.value = res?.data?.records || []; |
| | | } finally { |
| | | quotationLoading.value = false; |
| | | } |
| | | }; |
| | | |
| | | const resetQuotationSearch = async () => { |
| | | quotationSearchForm.quotationNo = ""; |
| | | quotationSearchForm.customer = ""; |
| | | await fetchQuotationList(); |
| | | }; |
| | | |
| | | // é䏿¥ä»·åååå¡«å°å°è´¦è¡¨å |
| | | const applyQuotation = (row) => { |
| | | if (!row) return; |
| | | selectedQuotation.value = row; |
| | | |
| | | // ä¸å¡å |
| | | form.value.salesman = row.salesperson || ""; |
| | | |
| | | // 客æ·åç§° -> customerId |
| | | const customer = (customerOption.value || []).find((c) => c.customerName === row.customer); |
| | | if (customer?.id) { |
| | | form.value.customerId = customer.id; |
| | | } else { |
| | | // 妿æ¾ä¸å°ï¼ä¿çåå¼ï¼å
è®¸ç¨æ·æå¨éæ©/䏿æå·²æè¾å
¥ï¼ |
| | | form.value.customerId = form.value.customerId || ""; |
| | | } |
| | | |
| | | // 产åä¿¡æ¯æ å°ï¼æ¥ä»· products -> å°è´¦ productData |
| | | const products = Array.isArray(row.products) ? row.products : []; |
| | | productData.value = products.map((p) => { |
| | | const quantity = Number(p.quantity ?? 0) || 0; |
| | | const unitPrice = Number(p.unitPrice ?? 0) || 0; |
| | | const taxRate = "13"; // é»è®¤ 13%ï¼ä¾¿äºç´æ¥æäº¤ï¼å¦éå¯å¨äº§åä¸èªè¡ä¿®æ¹ï¼ |
| | | const taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2); |
| | | const taxExclusiveTotalPrice = proxy.calculateTaxExclusiveTotalPrice(taxInclusiveTotalPrice, taxRate); |
| | | return { |
| | | // å°è´¦å段 |
| | | productCategory: p.product || p.productName || "", |
| | | specificationModel: p.specification || "", |
| | | unit: p.unit || "", |
| | | quantity: quantity, |
| | | taxRate: taxRate, |
| | | taxInclusiveUnitPrice: unitPrice.toFixed(2), |
| | | taxInclusiveTotalPrice: taxInclusiveTotalPrice, |
| | | taxExclusiveTotalPrice: taxExclusiveTotalPrice, |
| | | invoiceType: "墿®ç¥¨", |
| | | }; |
| | | }); |
| | | |
| | | quotationDialogVisible.value = false; |
| | | }; |
| | | function changs(val) { |
| | | console.log(val); |
| | |
| | | |
| | | const productIndex = ref(0); |
| | | // æå¼äº§åå¼¹æ¡ |
| | | const openProductForm = async (type, row, index) => { |
| | | const openProductForm = (type, row,index) => { |
| | | productOperationType.value = type; |
| | | productForm.value = {}; |
| | | proxy.resetForm("productFormRef"); |
| | | if (type === "edit") { |
| | | productForm.value = { ...row }; |
| | | productIndex.value = index; |
| | | // ç¼è¾æ¶æ ¹æ®äº§å大类åç§°åæ¥ tree èç¹ idï¼å¹¶å è½½è§æ ¼åå·å表 |
| | | try { |
| | | const options = productOptions.value && productOptions.value.length > 0 |
| | | ? productOptions.value |
| | | : await getProductOptions(); |
| | | const categoryId = findNodeIdByLabel(options, productForm.value.productCategory); |
| | | if (categoryId) { |
| | | const models = await modelList({ id: categoryId }); |
| | | modelOptions.value = models || []; |
| | | // æ ¹æ®å½åè§æ ¼åå·åç§°åæ¥å¹¶è®¾ç½® productModelIdï¼ä¾¿äºä¸ææ¡æ¾ç¤ºå·²éå¼ |
| | | const currentModel = (modelOptions.value || []).find( |
| | | (m) => m.model === productForm.value.specificationModel |
| | | ); |
| | | if (currentModel) { |
| | | productForm.value.productModelId = currentModel.id; |
| | | } |
| | | } |
| | | } catch (e) { |
| | | // å 载失败æ¶ä¿æå¯ç¼è¾ï¼ä¸ä¸æå¼¹çª |
| | | console.error("å 载产åè§æ ¼åå·å¤±è´¥", e); |
| | | } |
| | | } |
| | | productFormVisible.value = true; |
| | | getProductOptions(); |
| | | }; |
| | | // æäº¤äº§å表å |
| | | const submitProduct = () => { |
| | |
| | | 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'; |
| | |
| | | * @param row ä¸è½½æä»¶çç¸å
³ä¿¡æ¯å¯¹è±¡ |
| | | */ |
| | | const fileListRef = ref(null) |
| | | const fileListDialogVisible = ref(false) |
| | | const downLoadFile = (row) => { |
| | | getSalesLedgerWithProducts({ id: row.id, type: 1 }).then((res) => { |
| | | if (fileListRef.value) { |
| | | fileListRef.value.open(res.salesLedgerFiles) |
| | | fileListDialogVisible.value = true |
| | | } |
| | | }); |
| | | } |
| | | |
| | | // æå¼åè´§å¼¹æ¡ |
| | | const openDeliveryForm = (row) => { |
| | | getProductInventory({ salesLedgerId: row.id, type:1 }).then((res) => { |
| | | currentDeliveryRow.value = row; |
| | | deliveryForm.value = { |
| | | shippingDate: getCurrentDate(), |
| | | shippingDate: "", // ç§»é¤é»è®¤å¼è®¾ç½® |
| | | shippingCarNumber: "", |
| | | }; |
| | | deliveryFormVisible.value = true; |
| | | }).catch(err => { |
| | | ElMessage.error(err.msg); |
| | | }); |
| | | }; |
| | | |
| | | // æäº¤å货表å |
| | |
| | | proxy.$refs["deliveryFormRef"].validate((valid) => { |
| | | if (valid) { |
| | | addShippingInfo({ |
| | | salesLedgerId: currentDeliveryRow.value.id, |
| | | approverId:deliveryForm.value.approverId, |
| | | salesLedgerId: currentDeliveryRow.value.salesLedgerId, |
| | | salesLedgerProductId: currentDeliveryRow.value.id, |
| | | shippingDate: deliveryForm.value.shippingDate, |
| | | shippingCarNumber: deliveryForm.value.shippingCarNumber, |
| | | }) |
| | |
| | | proxy.$modal.msgSuccess("åè´§æå"); |
| | | closeDeliveryDia(); |
| | | getList(); |
| | | expandedRowKeys.value = []; |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msgError("å货失败ï¼è¯·éè¯"); |