| | |
| | | prefix-icon="Search" |
| | | @change="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="产品宽(mm):"> |
| | | <el-input v-model="searchForm.width" |
| | | placeholder="请输入" |
| | | clearable |
| | | prefix-icon="Search" |
| | | @change="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="产品高(mm):"> |
| | | <el-input v-model="searchForm.height" |
| | | 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" |
| | |
| | | width="220" |
| | | show-overflow-tooltip |
| | | :formatter="formattedNumber" /> |
| | | <el-table-column label="面积" |
| | | prop="productTotalArea" |
| | | width="120" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="数量" |
| | | prop="productTotalQuantity" |
| | | width="120" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="发货状态" |
| | | width="140" |
| | | align="center"> |
| | |
| | | label-width="140px" |
| | | label-position="top" |
| | | :rules="rules" |
| | | @keydown.capture="handleTabScrollFollow" |
| | | ref="formRef"> |
| | | <!-- 报价单导入入口:放在表单顶部,选择后反显客户/业务员等 --> |
| | | <el-row v-if="operationType === 'add'" |
| | |
| | | customerName: "", // 客户名称 |
| | | customerId: "", // 客户ID(查询下拉) |
| | | salesContractNo: "", // 销售合同编号 |
| | | width: undefined, // 产品宽(mm) |
| | | height: undefined, // 产品高(mm) |
| | | entryDate: null, // 录入日期 |
| | | entryDateStart: undefined, |
| | | entryDateEnd: undefined, |
| | |
| | | delete params.customerName; |
| | | } |
| | | } |
| | | const widthValue = |
| | | params.width != null ? String(params.width).trim() : ""; |
| | | if (widthValue) { |
| | | params.width = widthValue; |
| | | } else { |
| | | delete params.width; |
| | | } |
| | | const heightValue = |
| | | params.height != null ? String(params.height).trim() : ""; |
| | | if (heightValue) { |
| | | params.height = heightValue; |
| | | } else { |
| | | delete params.height; |
| | | } |
| | | const shouldAutoExpandBySize = Boolean(params.width || params.height); |
| | | delete params.customerId; |
| | | return ledgerListPage(params) |
| | | .then(res => { |
| | | .then(async res => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.records; |
| | | tableData.value.map(item => { |
| | | item.children = []; |
| | | }); |
| | | if (shouldAutoExpandBySize && tableData.value.length > 0) { |
| | | const loadChildrenTasks = tableData.value.map(item => |
| | | productList({ salesLedgerId: item.id, type: 1 }) |
| | | .then(productRes => { |
| | | item.children = Array.isArray(productRes?.data) |
| | | ? productRes.data |
| | | : []; |
| | | }) |
| | | .catch(() => { |
| | | item.children = []; |
| | | }) |
| | | ); |
| | | await Promise.all(loadChildrenTasks); |
| | | expandedRowKeys.value = tableData.value.map(item => item.id); |
| | | } |
| | | total.value = res.total; |
| | | return res; |
| | | }) |
| | |
| | | const num = Number(cellValue); |
| | | return Number.isFinite(num) ? num.toFixed(2) : ""; |
| | | }; |
| | | |
| | | const scrollElementIntoVisibleArea = target => { |
| | | if (!target || !(target instanceof HTMLElement)) return; |
| | | let parent = target.parentElement; |
| | | while (parent && parent !== document.body) { |
| | | const style = window.getComputedStyle(parent); |
| | | const canScrollX = |
| | | (style.overflowX === "auto" || |
| | | style.overflowX === "scroll" || |
| | | style.overflowX === "overlay") && |
| | | parent.scrollWidth > parent.clientWidth; |
| | | const canScrollY = |
| | | (style.overflowY === "auto" || |
| | | style.overflowY === "scroll" || |
| | | style.overflowY === "overlay") && |
| | | parent.scrollHeight > parent.clientHeight; |
| | | |
| | | if (canScrollX || canScrollY) { |
| | | const parentRect = parent.getBoundingClientRect(); |
| | | const targetRect = target.getBoundingClientRect(); |
| | | if (canScrollX) { |
| | | const targetCenterX = targetRect.left + targetRect.width / 2; |
| | | const parentCenterX = parentRect.left + parentRect.width / 2; |
| | | const deltaX = targetCenterX - parentCenterX; |
| | | if (Math.abs(deltaX) > 2) { |
| | | parent.scrollLeft += deltaX; |
| | | } |
| | | } |
| | | |
| | | if (canScrollY) { |
| | | const targetCenterY = targetRect.top + targetRect.height / 2; |
| | | const parentCenterY = parentRect.top + parentRect.height / 2; |
| | | const deltaY = targetCenterY - parentCenterY; |
| | | if (Math.abs(deltaY) > 2) { |
| | | parent.scrollTop += deltaY; |
| | | } |
| | | } |
| | | } |
| | | |
| | | parent = parent.parentElement; |
| | | } |
| | | }; |
| | | |
| | | const handleTabScrollFollow = e => { |
| | | if (!e || e.key !== "Tab") return; |
| | | requestAnimationFrame(() => { |
| | | const active = document.activeElement; |
| | | if (active instanceof HTMLElement) { |
| | | scrollElementIntoVisibleArea(active); |
| | | } |
| | | }); |
| | | }; |
| | | // 获取tree子数据 |
| | | const getModels = value => { |
| | | // 产品大类变化时,重置规格型号与厚度,避免旧值残留 |
| | |
| | | const summarizeMainTable = param => { |
| | | return proxy.summarizeTable(param, [ |
| | | "contractAmount", |
| | | "productTotalQuantity", |
| | | "productTotalArea", |
| | | "taxInclusiveTotalPrice", |
| | | "taxExclusiveTotalPrice", |
| | | ]); |