| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // éè´-æ¥ç¥¨ç»è®°æ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // æ¥è¯¢éè´ååå· |
| | | export function getProduct(query) { |
| | | return request({ |
| | | url: "/purchase/ledger/getProduct", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢idéè´ååå· |
| | | export function getPurchaseNoById(query) { |
| | | return request({ |
| | | url: "/purchase/ledger/getPurchaseNoById", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | // æ ¹æ®éè´ååå·æ¥è¯¢è¯¦ç»ä¿¡æ¯ |
| | | export function getInfo(query) { |
| | | return request({ |
| | | url: "/purchase/ledger/getInfo", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | // 主å表æ¥è¯¢ |
| | | export function gePurchaseList(query) { |
| | | return request({ |
| | | url: "/purchase/ledger/list", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | // 主å表æ¥è¯¢ |
| | | export function getRegistrationById(query) { |
| | | return request({ |
| | | url: "/purchase/registration/getRegistrationById", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | // æ°å¢ç¼è¾æ¥ç¥¨ç»è®° |
| | | export function addOrUpdateRegistration(query) { |
| | | return request({ |
| | | url: "/purchase/registration/addOrUpdateRegistration", |
| | | method: "post", |
| | | data: query, |
| | | }); |
| | | } |
| | | // å 餿¥ç¥¨ç»è®° |
| | | export function delRegistration(query) { |
| | | return request({ |
| | | url: "/purchase/registration/delRegistration", |
| | | method: "delete", |
| | | data: query, |
| | | }); |
| | | } |
| | | |
| | | // 主å表æ¥è¯¢ |
| | | export function gePurchaseListPage(query) { |
| | | return request({ |
| | | url: "/purchase/ledger/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // 客æ·å¾æ¥ç»è®¡æ±æ» |
| | | export function customerTransactionsSummary(query) { |
| | | return request({ |
| | | url: "/metricStatistics/customerTransactionsSummary", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // 客æ·å¾æ¥äº§åæç» |
| | | export function customerTransactionsProducts(query) { |
| | | return request({ |
| | | url: "/metricStatistics/customerTransactionsProducts", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // 客æ·å¾æ¥åè´§æç» |
| | | export function customerTransactionsShipments(query) { |
| | | return request({ |
| | | url: "/metricStatistics/customerTransactionsShipments", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | path: "/customer-transactions-detail", |
| | | component: Layout, |
| | | hidden: true, |
| | | children: [ |
| | | { |
| | | path: "", |
| | | component: () => import("@/views/salesManagement/receiptPaymentLedger/detail.vue"), |
| | | name: "CustomerTransactionsDetail", |
| | | meta: { title: "客æ·å¾æ¥è¯¦æ
", activeMenu: "/salesManagement/receiptPaymentLedger" }, |
| | | }, |
| | | ], |
| | | }, |
| | | // è´¢å¡ç®¡ç模åè·¯ç± |
| | | // { |
| | | // path: "/financial", |
| | |
| | | <div></div> |
| | | </div> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="14"> |
| | | <el-col :span="8"> |
| | | <div class="table_list"> |
| | | <el-table ref="multipleTable" |
| | | border |
| | |
| | | prop="contractAmounts" |
| | | show-overflow-tooltip |
| | | :formatter="formattedNumber" /> |
| | | <el-table-column label="仿¬¾éé¢(å
)" |
| | | prop="paymentAmount" |
| | | show-overflow-tooltip |
| | | :formatter="formattedNumber" /> |
| | | <el-table-column label="åºä»éé¢(å
)" |
| | | prop="payableAmount" |
| | | show-overflow-tooltip> |
| | | <template #default="{ row, column }"> |
| | | <el-text type="danger"> |
| | | {{ formattedNumber(row, column, row.payableAmount) }} |
| | | </el-text> |
| | | </template> |
| | | </el-table-column> |
| | | <!-- <el-table-column label="åºä»éé¢(å
)"--> |
| | | <!-- prop="payableAmount"--> |
| | | <!-- show-overflow-tooltip>--> |
| | | <!-- <template #default="{ row, column }">--> |
| | | <!-- <el-text type="danger">--> |
| | | <!-- {{ formattedNumber(row, column, row.payableAmount) }}--> |
| | | <!-- </el-text>--> |
| | | <!-- </template>--> |
| | | <!-- </el-table-column>--> |
| | | </el-table> |
| | | <pagination v-show="total > 0" |
| | | @pagination="paginationSearch" |
| | |
| | | :limit="page.size" /> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="10"> |
| | | <el-col :span="16"> |
| | | <div class="table_list"> |
| | | <PIMTable rowKey="id" |
| | | :column="tableColumnSon" |
| | | :tableData="originalTableDataSon" |
| | | :isSelection="false" |
| | | :isShowPagination="true" |
| | | :page="sonPage" |
| | | :tableLoading="tableLoadingSon" |
| | | :isShowSummary="isShowSummarySon" |
| | | :summaryMethod="summarizeMainTable1" |
| | | height="calc(100vh - 18.5em)" |
| | | @pagination="sonPaginationSearch"> |
| | | <template #payableAmountSlot="{ row }"> |
| | | <el-text type="danger"> |
| | | {{ parseFloat(row.payableAmount).toFixed(2) }} |
| | | </el-text> |
| | | </template> |
| | | </PIMTable> |
| | | <div class="table-header" v-if="selectedSupplierName"> |
| | | <span class="supplier-title">ä¾åºåï¼{{ selectedSupplierName }}</span> |
| | | </div> |
| | | <el-table border |
| | | v-loading="tableLoadingSon" |
| | | :data="originalTableDataSon" |
| | | :header-cell-style="{ background: '#F0F1F5', color: '#333333' }" |
| | | height="calc(100vh - 20em)" |
| | | style="width: 100%" |
| | | tooltip-effect="dark" |
| | | :show-summary="isShowSummarySon" |
| | | :summary-method="summarizeMainTable1"> |
| | | <el-table-column align="center" |
| | | label="åºå·" |
| | | type="index" |
| | | width="60" /> |
| | | <el-table-column label="ååç¾è®¢æ¥æ" |
| | | prop="executionDate" |
| | | show-overflow-tooltip/> |
| | | <el-table-column label="éè´ååå·" |
| | | prop="purchaseContractNumber" |
| | | show-overflow-tooltip/> |
| | | <el-table-column label="项ç®åç§°" |
| | | prop="projectName" |
| | | show-overflow-tooltip/> |
| | | <el-table-column label="ååéé¢(å
)" |
| | | prop="contractAmount" |
| | | show-overflow-tooltip |
| | | :formatter="formattedNumber" /> |
| | | <!-- <el-table-column label="æ¶è´§ç¶æ"--> |
| | | <!-- prop="status"--> |
| | | <!-- show-overflow-tooltip--> |
| | | <!-- width="100">--> |
| | | <!-- <template #default="{ row }">--> |
| | | <!-- <el-tag :type="getReceiptStatusType(row.status)" size="small">--> |
| | | <!-- {{ receiptStatusText[row.status] || 'æªç¥ç¶æ' }}--> |
| | | <!-- </el-tag>--> |
| | | <!-- </template>--> |
| | | <!-- </el-table-column>--> |
| | | </el-table> |
| | | <pagination v-show="sonPage.total > 0" |
| | | @pagination="sonPaginationSearch" |
| | | :total="sonPage.total" |
| | | :layout="sonPage.layout" |
| | | :page="sonPage.current" |
| | | :limit="sonPage.size" /> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, toRefs } from "vue"; |
| | | import { ref, toRefs, reactive, getCurrentInstance } from "vue"; |
| | | import { Search } from "@element-plus/icons-vue"; |
| | | import { |
| | | paymentLedgerList, |
| | | paymentRecordList, |
| | | } from "@/api/procurementManagement/paymentLedger.js"; |
| | | import { gePurchaseListPage } from "@/api/procurementManagement/invoiceEntry.js"; |
| | | import Pagination from "../../../components/PIMTable/Pagination.vue"; |
| | | |
| | | const tableData = ref([]); |
| | |
| | | const isShowSummary = ref(true); |
| | | const { searchForm } = toRefs(data); |
| | | const currentSupplierId = ref(""); |
| | | const selectedSupplierName = ref(""); |
| | | const rowClick = row => { |
| | | currentSupplierId.value = row.supplierId; |
| | | selectedSupplierName.value = row.supplierName; |
| | | sonPage.current = 1; |
| | | getPaymenRecordtList(row.supplierId); |
| | | getPurchaseList(row.supplierName); |
| | | }; |
| | | // 忍¡å |
| | | const tableColumnSon = ref([ |
| | | { |
| | | label: "ååç¾è®¢æ¥æ", |
| | | prop: "executionDate", |
| | | width: 110, |
| | | }, |
| | | { |
| | | label: "éè´ååå·", |
| | | prop: "purchaseContractNumber", |
| | | width: 150, |
| | | }, |
| | | { |
| | | label: "ååéé¢(å
)", |
| | | prop: "contractAmount", |
| | | width: 200, |
| | | formatData: params => { |
| | | return params ? parseFloat(params).toFixed(2) : 0; |
| | | }, |
| | | }, |
| | | { |
| | | label: "仿¬¾éé¢(å
)", |
| | | prop: "paymentAmount", |
| | | width: 200, |
| | | formatData: params => { |
| | | return params ? parseFloat(params).toFixed(2) : 0; |
| | | }, |
| | | }, |
| | | { |
| | | label: "åºä»éé¢(å
)", |
| | | dataType: "slot", |
| | | width: 200, |
| | | prop: "payableAmount", |
| | | slot: "payableAmountSlot", |
| | | }, |
| | | ]); |
| | | const tableDataSon = ref([]); |
| | | const originalTableDataSon = ref([]); |
| | | const tableLoadingSon = ref(false); |
| | | const isShowSummarySon = ref(true); |
| | |
| | | const summarizeMainTable = param => { |
| | | return proxy.summarizeTable( |
| | | param, |
| | | ["contractAmounts", "paymentAmount", "payableAmount"], |
| | | ["contractAmounts", "payableAmount"], |
| | | { |
| | | ticketsNum: { noDecimal: true }, // ä¸ä¿çå°æ° |
| | | futureTickets: { noDecimal: true }, // ä¸ä¿çå°æ° |
| | | ticketsNum: { noDecimal: true }, |
| | | futureTickets: { noDecimal: true }, |
| | | } |
| | | ); |
| | | }; |
| | | // å表åè®¡æ¹æ³ |
| | | const summarizeMainTable1 = param => { |
| | | let summarizeTable = proxy.summarizeTable( |
| | | return proxy.summarizeTable( |
| | | param, |
| | | ["contractAmount", "invoiceAmount", "paymentAmount"], |
| | | ["contractAmount"], |
| | | { |
| | | ticketsNum: { noDecimal: true }, // ä¸ä¿çå°æ° |
| | | futureTickets: { noDecimal: true }, // ä¸ä¿çå°æ° |
| | | ticketsNum: { noDecimal: true }, |
| | | futureTickets: { noDecimal: true }, |
| | | } |
| | | ); |
| | | if (originalTableDataSon.value.length > 0) { |
| | | summarizeTable[summarizeTable.length - 1] = |
| | | originalTableDataSon.value[ |
| | | originalTableDataSon.value.length - 1 |
| | | ].payableAmount.toFixed(2); |
| | | } else { |
| | | summarizeTable[summarizeTable.length - 1] = 0.0; |
| | | } |
| | | return summarizeTable; |
| | | }; |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | |
| | | total.value = result.total || 0; |
| | | if (tableData.value.length > 0) { |
| | | currentSupplierId.value = tableData.value[0].supplierId; |
| | | selectedSupplierName.value = tableData.value[0].supplierName; |
| | | sonPage.current = 1; |
| | | getPaymenRecordtList(tableData.value[0].supplierId); |
| | | getPurchaseList(tableData.value[0].supplierName); |
| | | } else { |
| | | originalTableDataSon.value = []; |
| | | selectedSupplierName.value = ""; |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const getPaymenRecordtList = supplierId => { |
| | | const getPurchaseList = supplierName => { |
| | | tableLoadingSon.value = true; |
| | | paymentRecordList({ |
| | | supplierId: supplierId, |
| | | gePurchaseListPage({ |
| | | supplierName: supplierName, |
| | | current: sonPage.current, |
| | | size: sonPage.size, |
| | | }) |
| | |
| | | tableLoadingSon.value = false; |
| | | let result = res.data; |
| | | if (Array.isArray(result)) { |
| | | tableDataSon.value = result; |
| | | originalTableDataSon.value = result; |
| | | sonPage.total = result.length; |
| | | handlePagination({ page: sonPage.current, limit: sonPage.size }); |
| | | } else { |
| | | originalTableDataSon.value = result.records || []; |
| | | sonPage.total = result.total || 0; |
| | |
| | | tableLoadingSon.value = false; |
| | | }); |
| | | }; |
| | | const handlePagination = ({ page, limit }) => { |
| | | console.log(page, limit); |
| | | sonPage.current = page; |
| | | sonPage.size = limit; |
| | | |
| | | const start = (page - 1) * limit; |
| | | const end = start + limit; |
| | | |
| | | originalTableDataSon.value = tableDataSon.value.slice(start, end); |
| | | }; |
| | | |
| | | const sonPaginationSearch = pagination => { |
| | | // æ¥æ¶å页å¨åæ° { page, limit } |
| | | sonPage.current = pagination.page; |
| | | sonPage.size = pagination.limit; |
| | | getPaymenRecordtList(currentSupplierId.value); |
| | | getPurchaseList(selectedSupplierName.value); |
| | | }; |
| | | |
| | | const formattedNumber = (row, column, cellValue) => { |
| | | if (column.property !== "supplierName") { |
| | | if (cellValue !== undefined && cellValue !== null && !isNaN(cellValue)) { |
| | | return parseFloat(cellValue).toFixed(2); |
| | | } else { |
| | | return cellValue; |
| | | } |
| | | return "0.00"; |
| | | }; |
| | | |
| | | // æ¶è´§ç¶æææ¬æ å° |
| | | const receiptStatusText = { |
| | | 1: 'å¾
æ¶è´§', |
| | | 2: 'æ¶è´§ä¸', |
| | | 3: 'å·²æ¶è´§' |
| | | }; |
| | | |
| | | // æ¶è´§ç¶ææ ç¾ç±»å |
| | | const getReceiptStatusType = (status) => { |
| | | const typeMap = { |
| | | 1: 'info', |
| | | 2: 'warning', |
| | | 3: 'success' |
| | | }; |
| | | return typeMap[status] || 'info'; |
| | | }; |
| | | |
| | | getList(); |
| | | </script> |
| | | |
| | |
| | | .pagination-container { |
| | | margin-top: 0; |
| | | } |
| | | |
| | | .table-header { |
| | | margin-bottom: 10px; |
| | | padding: 10px; |
| | | background-color: #f5f7fa; |
| | | border-radius: 4px; |
| | | |
| | | .supplier-title { |
| | | font-weight: bold; |
| | | font-size: 14px; |
| | | color: #303133; |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="product-table-container"> |
| | | <el-table |
| | | :data="list" |
| | | v-loading="loading" |
| | | size="small" |
| | | border |
| | | class="custom-table" |
| | | :height="tableHeight" |
| | | > |
| | | <el-table-column label="ååå·" prop="salesContractNo" width="160" show-overflow-tooltip> |
| | | <template #default="{ row }"> |
| | | <span class="contract-no">{{ row.salesContractNo || '--' }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="产ååç§°" prop="productName" min-width="180" show-overflow-tooltip /> |
| | | <el-table-column label="è§æ ¼åå·" prop="model" width="140" show-overflow-tooltip> |
| | | <template #default="{ row }"> |
| | | <span class="model-text">{{ row.model || '--' }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="åä½" prop="unit" width="80" align="center" /> |
| | | <el-table-column label="ååæ°é" prop="contractQuantity" align="right" width="100"> |
| | | <template #default="{ row }"> |
| | | <span class="quantity">{{ formatNumber(row.contractQuantity) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="åååä»·" prop="taxInclusiveUnitPrice" align="right" width="110"> |
| | | <template #default="{ row }"> |
| | | <span class="price">Â¥{{ formatMoney(row.taxInclusiveUnitPrice) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ååéé¢" prop="contractAmount" align="right" width="130"> |
| | | <template #default="{ row }"> |
| | | <span class="amount">Â¥{{ formatMoney(row.contractAmount) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å·²åè´§æ°é" prop="shippedQuantity" align="right" width="100"> |
| | | <template #default="{ row }"> |
| | | <span class="shipped-qty">{{ formatNumber(row.shippedQuantity) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å·²åè´§éé¢" prop="shippedAmount" align="right" width="130"> |
| | | <template #default="{ row }"> |
| | | <span class="shipped-amt">Â¥{{ formatMoney(row.shippedAmount) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="åè´§è¿åº¦" width="180" align="center"> |
| | | <template #default="{ row }"> |
| | | <div class="progress-cell"> |
| | | <el-progress |
| | | :percentage="calcPercent(row.shippedQuantity, row.contractQuantity)" |
| | | :stroke-width="8" |
| | | :show-text="false" |
| | | :color="getProgressColor(calcPercent(row.shippedQuantity, row.contractQuantity))" |
| | | /> |
| | | <span class="progress-text">{{ calcPercent(row.shippedQuantity, row.contractQuantity) }}%</span> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <div class="pagination-wrapper"> |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | :page="queryParams.pageNum" |
| | | :limit="queryParams.pageSize" |
| | | @pagination="handlePagination" |
| | | /> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, watch, computed } from 'vue' |
| | | import { customerTransactionsProducts } from '@/api/salesManagement/indicatorStats.js' |
| | | import Pagination from '@/components/PIMTable/Pagination.vue' |
| | | |
| | | const props = defineProps({ |
| | | customerId: { |
| | | type: [Number, String], |
| | | required: true |
| | | } |
| | | }) |
| | | |
| | | const loading = ref(false) |
| | | const list = ref([]) |
| | | const total = ref(0) |
| | | const queryParams = ref({ |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | customerId: null |
| | | }) |
| | | |
| | | const tableHeight = computed(() => `calc(100vh - 32em)`) |
| | | |
| | | const getList = () => { |
| | | loading.value = true |
| | | queryParams.value.customerId = props.customerId |
| | | customerTransactionsProducts(queryParams.value) |
| | | .then(res => { |
| | | if (res.code === 200) { |
| | | list.value = res.data?.records || [] |
| | | total.value = res.data?.total || 0 |
| | | } |
| | | }) |
| | | .finally(() => { |
| | | loading.value = false |
| | | }) |
| | | } |
| | | |
| | | const handlePagination = ({ page, limit }) => { |
| | | queryParams.value.pageNum = page |
| | | queryParams.value.pageSize = limit |
| | | getList() |
| | | } |
| | | |
| | | const formatMoney = (value) => { |
| | | if (!value) return '0.00' |
| | | return Number(value).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) |
| | | } |
| | | |
| | | const formatNumber = (value) => { |
| | | if (!value) return '0' |
| | | return Number(value).toLocaleString('zh-CN') |
| | | } |
| | | |
| | | const calcPercent = (shipped, total) => { |
| | | if (!total || total === 0) return 0 |
| | | return Math.min(100, Math.round((shipped / total) * 100)) |
| | | } |
| | | |
| | | const getProgressColor = (percent) => { |
| | | if (percent < 30) return '#f56c6c' |
| | | if (percent < 60) return '#e6a23c' |
| | | if (percent < 80) return '#409eff' |
| | | return '#67c23a' |
| | | } |
| | | |
| | | watch(() => props.customerId, (val) => { |
| | | if (val) { |
| | | queryParams.value.pageNum = 1 |
| | | getList() |
| | | } |
| | | }, { immediate: true }) |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .product-table-container { |
| | | .custom-table { |
| | | border-radius: 8px; |
| | | overflow: hidden; |
| | | |
| | | :deep(.el-table__header-wrapper) { |
| | | th { |
| | | background: #f8f9fb !important; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | } |
| | | } |
| | | |
| | | :deep(.el-table__row) { |
| | | transition: all 0.2s; |
| | | |
| | | &:hover > td { |
| | | background: #f5f7fa !important; |
| | | } |
| | | } |
| | | |
| | | .contract-no { |
| | | color: #409eff; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .model-text { |
| | | color: #606266; |
| | | } |
| | | |
| | | .quantity { |
| | | font-weight: 500; |
| | | color: #303133; |
| | | } |
| | | |
| | | .price { |
| | | color: #606266; |
| | | } |
| | | |
| | | .amount { |
| | | font-weight: 600; |
| | | color: #303133; |
| | | } |
| | | |
| | | .shipped-qty { |
| | | color: #67c23a; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .shipped-amt { |
| | | color: #67c23a; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .progress-cell { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 8px; |
| | | padding: 0 10px; |
| | | |
| | | .el-progress { |
| | | flex: 1; |
| | | } |
| | | |
| | | .progress-text { |
| | | font-size: 12px; |
| | | color: #606266; |
| | | min-width: 32px; |
| | | text-align: right; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .pagination-wrapper { |
| | | padding: 16px 0 0; |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="shipment-table-container"> |
| | | <el-table |
| | | :data="list" |
| | | v-loading="loading" |
| | | size="small" |
| | | border |
| | | class="custom-table" |
| | | :height="tableHeight" |
| | | > |
| | | <el-table-column label="ååå·" prop="salesContractNo" width="160" show-overflow-tooltip> |
| | | <template #default="{ row }"> |
| | | <span class="contract-no">{{ row.salesContractNo || '--' }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="åè´§åå·" prop="shippingNo" width="160" show-overflow-tooltip> |
| | | <template #default="{ row }"> |
| | | <span class="shipping-no">{{ row.shippingNo || '--' }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="产ååç§°" prop="productName" min-width="160" show-overflow-tooltip /> |
| | | <el-table-column label="è§æ ¼åå·" prop="model" width="140" show-overflow-tooltip> |
| | | <template #default="{ row }"> |
| | | <span class="model-text">{{ row.model || '--' }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="åè´§æ°é" prop="shippingQuantity" align="right" width="100"> |
| | | <template #default="{ row }"> |
| | | <span class="quantity">{{ formatNumber(row.shippingQuantity) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="åè´§éé¢" prop="shippingAmount" align="right" width="130"> |
| | | <template #default="{ row }"> |
| | | <span class="amount">Â¥{{ formatMoney(row.shippingAmount) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="åºåºæ¹å·" prop="batchNo" width="160" show-overflow-tooltip> |
| | | <template #default="{ row }"> |
| | | <span class="batch-no">{{ row.batchNo || '--' }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="åè´§æ¥æ" prop="shippingDate" width="120" align="center"> |
| | | <template #default="{ row }"> |
| | | <span class="date-text">{{ row.shippingDate || '--' }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="审æ¹ç¶æ" prop="approvalStatus" width="100" align="center"> |
| | | <template #default="{ row }"> |
| | | <el-tag |
| | | :type="row.approvalStatus === 1 ? 'success' : 'warning'" |
| | | size="small" |
| | | effect="light" |
| | | round |
| | | > |
| | | {{ row.approvalStatus === 1 ? '已审' : 'å¾
审' }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <div class="pagination-wrapper"> |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | :page="queryParams.pageNum" |
| | | :limit="queryParams.pageSize" |
| | | @pagination="handlePagination" |
| | | /> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, watch, computed } from 'vue' |
| | | import { customerTransactionsShipments } from '@/api/salesManagement/indicatorStats.js' |
| | | import Pagination from '@/components/PIMTable/Pagination.vue' |
| | | |
| | | const props = defineProps({ |
| | | customerId: { |
| | | type: [Number, String], |
| | | required: true |
| | | } |
| | | }) |
| | | |
| | | const loading = ref(false) |
| | | const list = ref([]) |
| | | const total = ref(0) |
| | | const queryParams = ref({ |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | customerId: null |
| | | }) |
| | | |
| | | const tableHeight = computed(() => `calc(100vh - 32em)`) |
| | | |
| | | const getList = () => { |
| | | loading.value = true |
| | | queryParams.value.customerId = props.customerId |
| | | customerTransactionsShipments(queryParams.value) |
| | | .then(res => { |
| | | if (res.code === 200) { |
| | | list.value = res.data?.records || [] |
| | | total.value = res.data?.total || 0 |
| | | } |
| | | }) |
| | | .finally(() => { |
| | | loading.value = false |
| | | }) |
| | | } |
| | | |
| | | const handlePagination = ({ page, limit }) => { |
| | | queryParams.value.pageNum = page |
| | | queryParams.value.pageSize = limit |
| | | getList() |
| | | } |
| | | |
| | | const formatMoney = (value) => { |
| | | if (!value) return '0.00' |
| | | return Number(value).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) |
| | | } |
| | | |
| | | const formatNumber = (value) => { |
| | | if (!value) return '0' |
| | | return Number(value).toLocaleString('zh-CN') |
| | | } |
| | | |
| | | watch(() => props.customerId, (val) => { |
| | | if (val) { |
| | | queryParams.value.pageNum = 1 |
| | | getList() |
| | | } |
| | | }, { immediate: true }) |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .shipment-table-container { |
| | | .custom-table { |
| | | border-radius: 8px; |
| | | overflow: hidden; |
| | | |
| | | :deep(.el-table__header-wrapper) { |
| | | th { |
| | | background: #f8f9fb !important; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | } |
| | | } |
| | | |
| | | :deep(.el-table__row) { |
| | | transition: all 0.2s; |
| | | |
| | | &:hover > td { |
| | | background: #f5f7fa !important; |
| | | } |
| | | } |
| | | |
| | | .contract-no { |
| | | color: #409eff; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .shipping-no { |
| | | color: #909399; |
| | | font-size: 12px; |
| | | } |
| | | |
| | | .model-text { |
| | | color: #606266; |
| | | } |
| | | |
| | | .quantity { |
| | | font-weight: 500; |
| | | color: #303133; |
| | | } |
| | | |
| | | .amount { |
| | | font-weight: 600; |
| | | color: #67c23a; |
| | | } |
| | | |
| | | .batch-no { |
| | | color: #606266; |
| | | font-size: 12px; |
| | | } |
| | | |
| | | .date-text { |
| | | color: #606266; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .pagination-wrapper { |
| | | padding: 16px 0 0; |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="customer-detail-page"> |
| | | <!-- é¡¶é¨å¯¼èªæ --> |
| | | <div class="page-header"> |
| | | <div class="header-left"> |
| | | <el-button @click="goBack" :icon="ArrowLeft" circle /> |
| | | <div class="customer-info"> |
| | | <span class="customer-name">{{ summary.customerName || '客æ·å¾æ¥è¯¦æ
' }}</span> |
| | | <span class="customer-tag">客æ·å¾æ¥ç»è®¡</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- ç»è®¡å¡çåº --> |
| | | <div class="stats-section" v-loading="summaryLoading"> |
| | | <div class="stats-grid"> |
| | | <div class="stat-card primary"> |
| | | <div class="stat-icon"> |
| | | <el-icon><Document /></el-icon> |
| | | </div> |
| | | <div class="stat-content"> |
| | | <div class="stat-label">ååæ»éé¢</div> |
| | | <div class="stat-value"> |
| | | <span class="currency">Â¥</span> |
| | | <span class="number">{{ formatMoney(summary.contractAmounts) }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="stat-card success"> |
| | | <div class="stat-icon"> |
| | | <el-icon><Tickets /></el-icon> |
| | | </div> |
| | | <div class="stat-content"> |
| | | <div class="stat-label">ååæ°é</div> |
| | | <div class="stat-value"> |
| | | <span class="number">{{ summary.contractCount || 0 }}</span> |
| | | <span class="unit">份</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="stat-card info"> |
| | | <div class="stat-icon"> |
| | | <el-icon><Van /></el-icon> |
| | | </div> |
| | | <div class="stat-content"> |
| | | <div class="stat-label">åè´§éé¢</div> |
| | | <div class="stat-value"> |
| | | <span class="currency">Â¥</span> |
| | | <span class="number">{{ formatMoney(summary.shippedAmounts) }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="stat-card danger"> |
| | | <div class="stat-icon"> |
| | | <el-icon><Clock /></el-icon> |
| | | </div> |
| | | <div class="stat-content"> |
| | | <div class="stat-label">æªåè´§éé¢</div> |
| | | <div class="stat-value"> |
| | | <span class="currency">Â¥</span> |
| | | <span class="number">{{ formatMoney(summary.unshippedAmounts) }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="stat-card progress-card"> |
| | | <div class="stat-content-full"> |
| | | <div class="progress-header"> |
| | | <span class="stat-label">åè´§è¿åº¦</span> |
| | | <span class="progress-value">{{ summary.shippedRate || 0 }}%</span> |
| | | </div> |
| | | <el-progress |
| | | :percentage="summary.shippedRate || 0" |
| | | :stroke-width="12" |
| | | :show-text="false" |
| | | :color="getProgressColor(summary.shippedRate)" |
| | | /> |
| | | <div class="progress-footer"> |
| | | <span>å·²åè´§: Â¥{{ formatMoney(summary.shippedAmounts) }}</span> |
| | | <span>æ»é¢: Â¥{{ formatMoney(summary.contractAmounts) }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- Tab 忢 --> |
| | | <div class="table-section"> |
| | | <el-tabs v-model="activeTab" class="custom-tabs"> |
| | | <el-tab-pane label="产åæç»" name="products"> |
| | | <ProductTable :customerId="customerId" v-if="customerId && activeTab === 'products'" /> |
| | | </el-tab-pane> |
| | | <!-- <el-tab-pane label="åè´§æç»" name="shipments"> |
| | | <ShipmentTable :customerId="customerId" v-if="customerId && activeTab === 'shipments'" /> |
| | | </el-tab-pane> --> |
| | | </el-tabs> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, onMounted } from 'vue' |
| | | import { useRoute, useRouter } from 'vue-router' |
| | | import { ArrowLeft, Document, Tickets, Van, Clock } from '@element-plus/icons-vue' |
| | | import { customerTransactionsSummary } from '@/api/salesManagement/indicatorStats.js' |
| | | import ProductTable from './components/ProductTable.vue' |
| | | // import ShipmentTable from './components/ShipmentTable.vue' |
| | | |
| | | const route = useRoute() |
| | | const router = useRouter() |
| | | |
| | | const customerId = ref(null) |
| | | const summary = ref({}) |
| | | const summaryLoading = ref(false) |
| | | const activeTab = ref('products') |
| | | |
| | | const getSummary = () => { |
| | | if (!customerId.value) return |
| | | summaryLoading.value = true |
| | | customerTransactionsSummary({ customerId: customerId.value }) |
| | | .then(res => { |
| | | if (res.code === 200) { |
| | | summary.value = res.data || {} |
| | | } |
| | | }) |
| | | .finally(() => { |
| | | summaryLoading.value = false |
| | | }) |
| | | } |
| | | |
| | | const formatMoney = (value) => { |
| | | if (!value) return '0.00' |
| | | return Number(value).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) |
| | | } |
| | | |
| | | const getProgressColor = (rate) => { |
| | | if (!rate || rate < 30) return '#f56c6c' |
| | | if (rate < 60) return '#e6a23c' |
| | | if (rate < 80) return '#409eff' |
| | | return '#67c23a' |
| | | } |
| | | |
| | | const goBack = () => { |
| | | router.push('/salesManagement/receiptPaymentLedger') |
| | | } |
| | | |
| | | onMounted(() => { |
| | | customerId.value = route.query.customerId |
| | | if (customerId.value) { |
| | | getSummary() |
| | | } |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .customer-detail-page { |
| | | background: #f5f7fa; |
| | | min-height: calc(100vh - 84px); |
| | | padding: 20px; |
| | | } |
| | | |
| | | .page-header { |
| | | background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
| | | border-radius: 12px; |
| | | padding: 20px 24px; |
| | | margin-bottom: 20px; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3); |
| | | |
| | | .header-left { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 16px; |
| | | |
| | | .el-button { |
| | | background: rgba(255, 255, 255, 0.2); |
| | | border: none; |
| | | color: white; |
| | | |
| | | &:hover { |
| | | background: rgba(255, 255, 255, 0.3); |
| | | } |
| | | } |
| | | |
| | | .customer-info { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 4px; |
| | | |
| | | .customer-name { |
| | | font-size: 20px; |
| | | font-weight: 600; |
| | | color: white; |
| | | } |
| | | |
| | | .customer-tag { |
| | | font-size: 12px; |
| | | color: rgba(255, 255, 255, 0.8); |
| | | background: rgba(255, 255, 255, 0.2); |
| | | padding: 2px 10px; |
| | | border-radius: 10px; |
| | | width: fit-content; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .stats-section { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .stats-grid { |
| | | display: grid; |
| | | grid-template-columns: repeat(5, 1fr); |
| | | gap: 16px; |
| | | |
| | | @media (max-width: 1400px) { |
| | | grid-template-columns: repeat(3, 1fr); |
| | | } |
| | | |
| | | @media (max-width: 1000px) { |
| | | grid-template-columns: repeat(2, 1fr); |
| | | } |
| | | } |
| | | |
| | | .stat-card { |
| | | background: white; |
| | | border-radius: 12px; |
| | | padding: 20px; |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 16px; |
| | | box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05); |
| | | transition: all 0.3s ease; |
| | | position: relative; |
| | | overflow: hidden; |
| | | |
| | | &::before { |
| | | content: ''; |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | width: 4px; |
| | | height: 100%; |
| | | } |
| | | |
| | | &:hover { |
| | | transform: translateY(-2px); |
| | | box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | &.primary::before { background: linear-gradient(180deg, #667eea, #764ba2); } |
| | | &.success::before { background: linear-gradient(180deg, #67c23a, #4a9c2d); } |
| | | &.warning::before { background: linear-gradient(180deg, #e6a23c, #c78a2f); } |
| | | &.info::before { background: linear-gradient(180deg, #409eff, #2d7dd2); } |
| | | &.danger::before { background: linear-gradient(180deg, #f56c6c, #c45656); } |
| | | &.progress-card::before { background: linear-gradient(180deg, #909399, #606266); } |
| | | |
| | | .stat-icon { |
| | | width: 52px; |
| | | height: 52px; |
| | | border-radius: 12px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | font-size: 24px; |
| | | flex-shrink: 0; |
| | | } |
| | | |
| | | &.primary .stat-icon { background: linear-gradient(135deg, rgba(102, 126, 234, 0.15), rgba(118, 75, 162, 0.15)); color: #667eea; } |
| | | &.success .stat-icon { background: linear-gradient(135deg, rgba(103, 194, 58, 0.15), rgba(74, 156, 45, 0.15)); color: #67c23a; } |
| | | &.warning .stat-icon { background: linear-gradient(135deg, rgba(230, 162, 60, 0.15), rgba(199, 138, 47, 0.15)); color: #e6a23c; } |
| | | &.info .stat-icon { background: linear-gradient(135deg, rgba(64, 158, 255, 0.15), rgba(45, 125, 210, 0.15)); color: #409eff; } |
| | | &.danger .stat-icon { background: linear-gradient(135deg, rgba(245, 108, 108, 0.15), rgba(196, 86, 86, 0.15)); color: #f56c6c; } |
| | | &.progress-card .stat-icon { display: none; } |
| | | |
| | | .stat-content { |
| | | flex: 1; |
| | | min-width: 0; |
| | | } |
| | | |
| | | .stat-label { |
| | | font-size: 13px; |
| | | color: #909399; |
| | | margin-bottom: 6px; |
| | | } |
| | | |
| | | .stat-value { |
| | | .currency { |
| | | font-size: 14px; |
| | | color: #606266; |
| | | margin-right: 2px; |
| | | } |
| | | |
| | | .number { |
| | | font-size: 22px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | } |
| | | |
| | | .unit { |
| | | font-size: 14px; |
| | | color: #909399; |
| | | margin-left: 4px; |
| | | } |
| | | } |
| | | |
| | | &.progress-card { |
| | | grid-column: span 1; |
| | | |
| | | @media (max-width: 1600px) { |
| | | grid-column: span 1; |
| | | } |
| | | |
| | | .stat-content-full { |
| | | width: 100%; |
| | | } |
| | | |
| | | .progress-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 10px; |
| | | |
| | | .stat-label { |
| | | margin-bottom: 0; |
| | | } |
| | | |
| | | .progress-value { |
| | | font-size: 18px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | } |
| | | } |
| | | |
| | | .progress-footer { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | margin-top: 10px; |
| | | font-size: 12px; |
| | | color: #909399; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .table-section { |
| | | background: white; |
| | | border-radius: 12px; |
| | | padding: 20px; |
| | | box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05); |
| | | |
| | | .custom-tabs { |
| | | :deep(.el-tabs__header) { |
| | | margin-bottom: 0; |
| | | |
| | | .el-tabs__nav-wrap::after { |
| | | height: 1px; |
| | | } |
| | | |
| | | .el-tabs__item { |
| | | font-size: 15px; |
| | | padding: 0 24px; |
| | | height: 44px; |
| | | line-height: 44px; |
| | | |
| | | &.is-active { |
| | | font-weight: 600; |
| | | } |
| | | } |
| | | |
| | | .el-tabs__active-bar { |
| | | height: 3px; |
| | | border-radius: 2px; |
| | | } |
| | | } |
| | | |
| | | :deep(.el-tabs__content) { |
| | | padding-top: 20px; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | </div> |
| | | </div> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <!-- 左侧客æ·å表 --> |
| | | <el-col :span="8"> |
| | | <div class="table_list" |
| | | style="width: 100%"> |
| | | <el-table :data="tableData" |
| | |
| | | prop="contractAmounts" |
| | | show-overflow-tooltip |
| | | :formatter="formattedNumber" |
| | | width="200" /> |
| | | <el-table-column label="忬¾éé¢(å
)" |
| | | width="150" /> |
| | | <el-table-column label="æ¶æ¬¾éé¢(å
)" |
| | | prop="receiptPaymentAmount" |
| | | show-overflow-tooltip |
| | | :formatter="formattedNumber" |
| | | width="200" /> |
| | | width="150" /> |
| | | <el-table-column label="åºæ¶éé¢(å
)" |
| | | prop="receiptableAmount" |
| | | show-overflow-tooltip |
| | | width="200"> |
| | | <template #default="{ row, column }"> |
| | | <el-text type="danger"> |
| | | {{ formattedNumber(row, column, row.receiptableAmount) }} |
| | | </el-text> |
| | | width="150"> |
| | | <template #default="{ row }"> |
| | | <span :style="{ color: row.receiptableAmount > 0 ? '#f56c6c' : '#606266' }"> |
| | | {{ formattedNumber(null, null, row.receiptableAmount) }} |
| | | </span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" width="100" align="center" fixed="right"> |
| | | <template #default="{ row }"> |
| | | <el-button type="primary" link size="small" @click="viewDetail(row)">æ¥çæç»</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | <!-- <el-table-column label="åºæ¶éé¢(å
)"--> |
| | | <!-- prop="receiptableAmount"--> |
| | | <!-- show-overflow-tooltip--> |
| | | <!-- width="150">--> |
| | | <!-- <template #default="{ row, column }">--> |
| | | <!-- <el-text type="danger">--> |
| | | <!-- {{ formattedNumber(row, column, row.receiptableAmount) }}--> |
| | | <!-- </el-text>--> |
| | | <!-- </template>--> |
| | | <!-- </el-table-column>--> |
| | | </el-table> |
| | | <pagination v-show="total > 0" |
| | | :total="total" |
| | |
| | | @pagination="paginationChange" /> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <!-- å³ä¾§è®¢åä¿¡æ¯ --> |
| | | <el-col :span="16"> |
| | | <div class="table_list" |
| | | style="width: 100%"> |
| | | <el-table :data="receiptRecord" |
| | | |
| | | <el-table :data="orderRecord" |
| | | border |
| | | :row-key="(row) => row.id" |
| | | show-summary |
| | | :summary-method="summarizeMainTable1" |
| | | height="calc(100vh - 18.5em)"> |
| | | v-loading="orderLoading" |
| | | height="calc(100vh - 20em)"> |
| | | <el-table-column align="center" |
| | | label="åºå·" |
| | | type="index" |
| | | width="60" /> |
| | | <el-table-column label="ååç¾è®¢æ¥æ" |
| | | prop="executionDate" |
| | | show-overflow-tooltip |
| | | width="110" /> |
| | | <el-table-column label="éå®ååå·" |
| | | <el-table-column label="éå®è®¢å" |
| | | prop="salesContractNo" |
| | | show-overflow-tooltip |
| | | width="200" /> |
| | | <el-table-column label="ååéé¢(å
)" |
| | | prop="contractAmount" |
| | | width="150" /> |
| | | <!-- <el-table-column label="å货订åå·" |
| | | prop="shippingNo" |
| | | show-overflow-tooltip |
| | | :formatter="formattedNumber" |
| | | width="200" /> |
| | | <el-table-column label="忬¾éé¢(å
)" |
| | | prop="receiptPaymentAmount" |
| | | width="150" /> --> |
| | | <el-table-column label="客æ·åç§°" |
| | | prop="customerName" |
| | | show-overflow-tooltip |
| | | :formatter="formattedNumber" |
| | | width="200" /> |
| | | <el-table-column label="åºæ¶éé¢(å
)" |
| | | prop="receiptableAmount" |
| | | width="150" /> |
| | | <el-table-column label="产ååç§°" |
| | | prop="productName" |
| | | show-overflow-tooltip |
| | | width="200"> |
| | | <template #default="{ row, column }"> |
| | | <el-text type="danger"> |
| | | {{ formattedNumber(row, column, row.receiptableAmount) }} |
| | | </el-text> |
| | | width="150" /> |
| | | <el-table-column label="è§æ ¼åå·" |
| | | prop="specificationModel" |
| | | show-overflow-tooltip |
| | | width="120" /> |
| | | <el-table-column label="åè´§æ¶é´" |
| | | prop="shippingDate" |
| | | show-overflow-tooltip |
| | | width="110" /> |
| | | <el-table-column label="åè´§æ°é" |
| | | prop="totalQuantity" |
| | | show-overflow-tooltip |
| | | width="100" /> |
| | | <!-- <el-table-column label="å货车çå·" |
| | | prop="shippingCarNumber" |
| | | show-overflow-tooltip |
| | | width="120" /> |
| | | <el-table-column label="å¿«éå
¬å¸" |
| | | prop="expressCompany" |
| | | show-overflow-tooltip |
| | | width="120" /> |
| | | <el-table-column label="å¿«éåå·" |
| | | prop="expressNumber" |
| | | show-overflow-tooltip |
| | | width="150" /> --> |
| | | <el-table-column label="åè´§ç¶æ" |
| | | prop="status" |
| | | align="center" |
| | | width="100"> |
| | | <template #default="{ row }"> |
| | | <el-tag :type="getApprovalStatusType(row.status)"> |
| | | {{ getApprovalStatusText(row.status) }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="åºåºåå·" |
| | | prop="outboundBatches" |
| | | show-overflow-tooltip |
| | | width="130" /> |
| | | </el-table> |
| | | <pagination v-show="recordTotal > 0" |
| | | :total="recordTotal" |
| | | <pagination v-show="orderTotal > 0" |
| | | :total="orderTotal" |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | :page="recordPage.current" |
| | | :limit="recordPage.size" |
| | | @pagination="recordPaginationChange" /> |
| | | :page="orderPage.current" |
| | | :limit="orderPage.size" |
| | | @pagination="orderPaginationChange" /> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { onMounted, ref, reactive, toRefs, getCurrentInstance } from "vue"; |
| | | import { useRouter } from "vue-router"; |
| | | import { |
| | | customewTransactions, |
| | | customewTransactionsDetails, |
| | | } from "@/api/salesManagement/indicatorStats.js"; |
| | | import { deliveryLedgerListPage } from "@/api/salesManagement/deliveryLedger.js"; |
| | | import Pagination from "../../../components/PIMTable/Pagination.vue"; |
| | | |
| | | const { proxy } = getCurrentInstance(); |
| | | const router = useRouter(); |
| | | const tableData = ref([]); |
| | | const receiptRecord = ref([]); |
| | | const orderRecord = ref([]); |
| | | const tableLoading = ref(false); |
| | | const orderLoading = ref(false); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | }); |
| | | const recordPage = reactive({ |
| | | const orderPage = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | }); |
| | | const total = ref(0); |
| | | const recordTotal = ref(0); |
| | | const orderTotal = ref(0); |
| | | const data = reactive({ |
| | | searchForm: { |
| | | searchText: "", |
| | |
| | | }); |
| | | const customerId = ref(""); |
| | | const { searchForm } = toRefs(data); |
| | | const originReceiptRecord = ref([]); |
| | | |
| | | // æ¥è¯¢å表 |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | |
| | | tableData.value = res.data.records; |
| | | total.value = res.data.total; |
| | | if (tableData.value.length > 0) { |
| | | recordPage.current = 1; |
| | | orderPage.current = 1; |
| | | customerId.value = tableData.value[0].customerId; |
| | | receiptPaymentList(customerId.value); |
| | | getOrderList(customerId.value); |
| | | } else { |
| | | orderRecord.value = []; |
| | | customerId.value = ""; |
| | | } |
| | | }); |
| | | }; |
| | |
| | | const summarizeMainTable = param => { |
| | | return proxy.summarizeTable( |
| | | param, |
| | | ["invoiceTotal", "receiptPaymentAmount", "unReceiptPaymentAmount"], |
| | | ["contractAmounts", "receiptableAmount"], |
| | | { |
| | | ticketsNum: { noDecimal: true }, // ä¸ä¿çå°æ° |
| | | futureTickets: { noDecimal: true }, // ä¸ä¿çå°æ° |
| | | ticketsNum: { noDecimal: true }, |
| | | futureTickets: { noDecimal: true }, |
| | | } |
| | | ); |
| | | }; |
| | | // å表åè®¡æ¹æ³ |
| | | const summarizeMainTable1 = param => { |
| | | var summarizeTable = proxy.summarizeTable( |
| | | param, |
| | | ["contractAmount", "receiptPaymentAmount", "receiptableAmount"], |
| | | { |
| | | ticketsNum: { noDecimal: true }, // ä¸ä¿çå°æ° |
| | | futureTickets: { noDecimal: true }, // ä¸ä¿çå°æ° |
| | | } |
| | | ); |
| | | return summarizeTable; |
| | | }; |
| | | |
| | | const receiptPaymentList = id => { |
| | | const param = { |
| | | // è·å订ååè¡¨ï¼æ ¹æ®å®¢æ·IDæ¥è¯¢åè´§å°è´¦ï¼ |
| | | const getOrderList = async (id) => { |
| | | orderLoading.value = true; |
| | | try { |
| | | // ä½¿ç¨ deliveryLedgerListPage æ¥å£æ ¹æ® customerId æ¥è¯¢ |
| | | const res = await deliveryLedgerListPage({ |
| | | customerId: id, |
| | | current: recordPage.current, |
| | | size: recordPage.size, |
| | | }; |
| | | customewTransactionsDetails(param).then(res => { |
| | | if (Array.isArray(res.data)) { |
| | | originReceiptRecord.value = res.data; |
| | | recordTotal.value = res.data.length; |
| | | handlePagination({ page: 1, limit: recordPage.size }); |
| | | } else { |
| | | receiptRecord.value = res.data.records; |
| | | recordTotal.value = res.data.total; |
| | | } |
| | | current: 1, |
| | | size: 1000, |
| | | }); |
| | | let orders = []; |
| | | if (res.data) { |
| | | if (Array.isArray(res.data)) { |
| | | orders = res.data; |
| | | } else if (res.data.records && Array.isArray(res.data.records)) { |
| | | orders = res.data.records; |
| | | } |
| | | } |
| | | |
| | | orderTotal.value = orders.length; |
| | | handleOrderPagination({ page: orderPage.current, limit: orderPage.size }, orders); |
| | | } catch (error) { |
| | | console.error('è·å订åå表失败:', error); |
| | | orderRecord.value = []; |
| | | } finally { |
| | | orderLoading.value = false; |
| | | } |
| | | }; |
| | | |
| | | // æ±æ¬¾è®°å½å表å页 |
| | | const recordPaginationChange = pagination => { |
| | | recordPage.current = pagination.page; |
| | | recordPage.size = pagination.limit; |
| | | receiptPaymentList(customerId.value); |
| | | // 订åå表å页 |
| | | const orderPaginationChange = pagination => { |
| | | orderPage.current = pagination.page; |
| | | orderPage.size = pagination.limit; |
| | | getOrderList(customerId.value); |
| | | }; |
| | | |
| | | const handleOrderPagination = ({ page, limit }, allOrders) => { |
| | | const start = (page - 1) * limit; |
| | | const end = start + limit; |
| | | orderRecord.value = allOrders.slice(start, end); |
| | | }; |
| | | |
| | | const rowClickMethod = row => { |
| | | customerId.value = row.customerId; |
| | | receiptPaymentList(customerId.value); |
| | | orderPage.current = 1; |
| | | getOrderList(customerId.value); |
| | | }; |
| | | |
| | | const handlePagination = ({ page, limit }) => { |
| | | recordPage.current = page; |
| | | recordPage.size = limit; |
| | | // æ¥çæç» |
| | | const viewDetail = (row) => { |
| | | router.push({ |
| | | path: '/customer-transactions-detail', |
| | | query: { customerId: row.customerId } |
| | | }); |
| | | }; |
| | | |
| | | const start = (page - 1) * limit; |
| | | const end = start + limit; |
| | | // å®¡æ ¸ç¶ææ ç¾ç±»å |
| | | const getApprovalStatusType = (status) => { |
| | | const statusMap = { |
| | | 'å·²åè´§': 'success', |
| | | 'å®¡æ ¸éè¿': 'success', |
| | | 'å®¡æ ¸ä¸': 'warning', |
| | | 'å®¡æ ¸ä¸éè¿': 'danger', |
| | | }; |
| | | return statusMap[status] || 'info'; |
| | | }; |
| | | |
| | | receiptRecord.value = originReceiptRecord.value.slice(start, end); |
| | | // å®¡æ ¸ç¶æææ¬ |
| | | const getApprovalStatusText = (status) => { |
| | | const statusMap = { |
| | | 'å·²åè´§': 'å·²åè´§', |
| | | 'å®¡æ ¸éè¿': 'å®¡æ ¸éè¿', |
| | | 'å®¡æ ¸ä¸': 'å®¡æ ¸ä¸', |
| | | 'å®¡æ ¸ä¸éè¿': 'å®¡æ ¸ä¸éè¿', |
| | | }; |
| | | return statusMap[status] || status || '--'; |
| | | }; |
| | | |
| | | onMounted(() => { |
| | |
| | | |
| | | <style scoped lang="scss"> |
| | | .table_list { |
| | | width: 50%; |
| | | width: 100%; |
| | | } |
| | | |
| | | </style> |
| | |
| | | ); |
| | | deliveryForm.value = { |
| | | shippingCarNumber: "", |
| | | expressCompany: "", |
| | | expressCompany: "顺丰快é", |
| | | expressNumber: "", |
| | | type: "货车", |
| | | type: "å¿«é", |
| | | batchNo: [], |
| | | batchNoList, |
| | | }; |