From 9a3f1f9136c1f324d080c8b633494dd7298a4f8d Mon Sep 17 00:00:00 2001
From: yyb <995253665@qq.com>
Date: 星期二, 21 四月 2026 10:45:40 +0800
Subject: [PATCH] 打印标签样式格式调整
---
src/views/procurementManagement/procurementLedger/index.vue | 213 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 212 insertions(+), 1 deletions(-)
diff --git a/src/views/procurementManagement/procurementLedger/index.vue b/src/views/procurementManagement/procurementLedger/index.vue
index 4479251..abe1804 100644
--- a/src/views/procurementManagement/procurementLedger/index.vue
+++ b/src/views/procurementManagement/procurementLedger/index.vue
@@ -33,6 +33,20 @@
prefix-icon="Search"
@change="handleQuery" />
</el-form-item>
+ <el-form-item label="鍏ュ簱鐘舵�侊細">
+ <el-select v-model="searchForm.stockStatus"
+ placeholder="璇烽�夋嫨"
+ clearable
+ style="width: 140px"
+ @change="handleQuery">
+ <el-option label="鏈叆搴�"
+ :value="0" />
+ <el-option label="閮ㄥ垎鍏ュ簱"
+ :value="1" />
+ <el-option label="宸插叆搴�"
+ :value="2" />
+ </el-select>
+ </el-form-item>
<el-form-item label="褰曞叆鏃ユ湡锛�">
<el-date-picker v-model="searchForm.entryDate"
value-format="YYYY-MM-DD"
@@ -96,6 +110,16 @@
prop="availableQuality" />
<el-table-column label="閫�璐ф暟閲�"
prop="returnQuality" />
+ <el-table-column label="鍏ュ簱鐘舵��"
+ width="100px"
+ align="center">
+ <template #default="scope">
+ <el-tag :type="getProductStockStatusType(scope.row.productStockStatus)"
+ size="small">
+ {{ stockStatusText[scope.row.productStockStatus] || '鏈叆搴�' }}
+ </el-tag>
+ </template>
+ </el-table-column>
<el-table-column label="绋庣巼(%)"
prop="taxRate" />
<el-table-column label="鍚◣鍗曚环(鍏�)"
@@ -154,6 +178,16 @@
width="200"
show-overflow-tooltip
:formatter="formattedNumber" />
+ <el-table-column label="鍏ュ簱鐘舵��"
+ width="120"
+ align="center">
+ <template #default="scope">
+ <el-tag :type="getStockStatusType(scope.row.stockStatus)"
+ size="small">
+ {{ stockStatusText[scope.row.stockStatus] || '鏈叆搴�' }}
+ </el-tag>
+ </template>
+ </el-table-column>
<el-table-column label="褰曞叆浜�"
prop="recorderName"
width="120"
@@ -168,7 +202,7 @@
show-overflow-tooltip />
<el-table-column fixed="right"
label="鎿嶄綔"
- width="120"
+ width="200"
align="center">
<template #default="scope">
<el-button link
@@ -178,6 +212,9 @@
<el-button link
type="primary"
@click="downLoadFile(scope.row)">闄勪欢</el-button>
+ <el-button link
+ type="primary"
+ @click="openProcurementQrDialog(scope.row)">浜岀淮鐮�</el-button>
</template>
</el-table-column>
</el-table>
@@ -689,6 +726,24 @@
<FileListDialog ref="fileListRef"
v-model="fileListDialogVisible"
title="闄勪欢鍒楄〃" />
+ <el-dialog v-model="procurementQrDialogVisible"
+ title="閲囪喘鍙拌处浜岀淮鐮�"
+ width="360px"
+ draggable
+ :close-on-click-modal="false">
+ <div class="procurement-qr-dialog">
+ <img v-if="procurementQrCompositeUrl"
+ :src="procurementQrCompositeUrl"
+ alt="閲囪喘鍙拌处浜岀淮鐮�"
+ class="procurement-qr-composite-img" />
+ <el-button type="primary"
+ class="procurement-qr-save-btn"
+ :disabled="!procurementQrCompositeUrl"
+ @click="downloadProcurementQrCode">
+ 淇濆瓨鍥剧墖
+ </el-button>
+ </div>
+ </el-dialog>
</div>
</template>
@@ -732,6 +787,7 @@
delPurchaseTemplate,
} from "@/api/procurementManagement/procurementLedger.js";
import useFormData from "@/hooks/useFormData.js";
+ import QRCode from "qrcode";
const { proxy } = getCurrentInstance();
const tableData = ref([]);
@@ -784,6 +840,33 @@
4: "danger", // 瀹℃壒澶辫触 - 绾㈣壊
};
return typeMap[status] || "";
+ };
+
+ // 鍏ュ簱鐘舵�佹樉绀烘枃鏈�
+ const stockStatusText = {
+ 0: "鏈叆搴�",
+ 1: "閮ㄥ垎鍏ュ簱",
+ 2: "宸插叆搴�",
+ };
+
+ // 鑾峰彇涓昏〃鍏ュ簱鐘舵�佹爣绛剧被鍨�
+ const getStockStatusType = status => {
+ const typeMap = {
+ 0: "info",
+ 1: "success",
+ 2: "success",
+ };
+ return typeMap[status] || "info";
+ };
+
+ // 鑾峰彇浜у搧鍏ュ簱鐘舵�佹爣绛剧被鍨�
+ const getProductStockStatusType = status => {
+ const typeMap = {
+ 0: "info",
+ 1: "warning",
+ 2: "success",
+ };
+ return typeMap[status] || "info";
};
const templateName = ref("");
@@ -897,6 +980,7 @@
purchaseContractNumber: "", // 閲囪喘鍚堝悓缂栧彿
salesContractNo: "", // 閿�鍞悎鍚岀紪鍙�
projectName: "", // 椤圭洰鍚嶇О
+ stockStatus: undefined, // 鍏ュ簱鐘舵��
entryDate: null, // 褰曞叆鏃ユ湡
entryDateStart: undefined,
entryDateEnd: undefined,
@@ -1871,6 +1955,117 @@
}
};
+ const procurementQrDialogVisible = ref(false);
+ const procurementQrCompositeUrl = ref("");
+ const procurementQrDownloadBaseName = ref("");
+
+ const sanitizeProcurementQrFilename = s =>
+ String(s)
+ .replace(/[\\/:*?"<>|]/g, "_")
+ .trim()
+ .slice(0, 80) || "ledger";
+
+ const wrapProcurementQrTextLines = (ctx, text, maxWidth) => {
+ const chars = [...text];
+ const lines = [];
+ let line = "";
+ for (const ch of chars) {
+ const test = line + ch;
+ if (ctx.measureText(test).width > maxWidth && line.length) {
+ lines.push(line);
+ line = ch;
+ } else {
+ line = test;
+ }
+ }
+ if (line) lines.push(line);
+ return lines;
+ };
+
+ const buildProcurementQrCompositeDataUrl = row =>
+ new Promise((resolve, reject) => {
+ const payload = JSON.stringify({
+ id: row.id,
+ purchaseContractNumber: (row.purchaseContractNumber ?? "").trim(),
+ type: "CG",
+ });
+ QRCode.toDataURL(payload, { width: 220, margin: 2 })
+ .then(qrDataUrl => {
+ const contract = (row.purchaseContractNumber ?? "").trim() || "鈥�";
+ const img = new Image();
+ img.onload = () => {
+ const QR_SIZE = 220;
+ const padTop = 16;
+ const gapAfterQr = 14;
+ const bottomPad = 48;
+ const horizontalPad = 20;
+ const lineHeight = 20;
+ const fontSize = 14;
+ const label = `閲囪喘鍚堝悓鍙凤細${contract}`;
+
+ const canvas = document.createElement("canvas");
+ const ctx = canvas.getContext("2d");
+ canvas.width = Math.max(QR_SIZE + horizontalPad * 2, 280);
+ ctx.font = `${fontSize}px "Microsoft YaHei", "PingFang SC", sans-serif`;
+ const lines = wrapProcurementQrTextLines(
+ ctx,
+ label,
+ canvas.width - horizontalPad * 2
+ );
+ const textBlockHeight = lines.length * lineHeight;
+ canvas.height = padTop + QR_SIZE + gapAfterQr + textBlockHeight + bottomPad;
+
+ ctx.fillStyle = "#ffffff";
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
+
+ const qrX = (canvas.width - QR_SIZE) / 2;
+ ctx.drawImage(img, qrX, padTop, QR_SIZE, QR_SIZE);
+
+ ctx.fillStyle = "#606266";
+ ctx.font = `${fontSize}px "Microsoft YaHei", "PingFang SC", sans-serif`;
+ ctx.textAlign = "center";
+ ctx.textBaseline = "top";
+ const textY0 = padTop + QR_SIZE + gapAfterQr;
+ lines.forEach((ln, i) => {
+ ctx.fillText(ln, canvas.width / 2, textY0 + i * lineHeight);
+ });
+
+ const baseName = sanitizeProcurementQrFilename(
+ contract !== "鈥�" ? contract : String(row.id)
+ );
+ resolve({ dataUrl: canvas.toDataURL("image/png"), baseName });
+ };
+ img.onerror = () => reject(new Error("浜岀淮鐮佸浘鐗囧姞杞藉け璐�"));
+ img.src = qrDataUrl;
+ })
+ .catch(reject);
+ });
+
+ const openProcurementQrDialog = async row => {
+ if (row?.id === undefined || row?.id === null || row?.id === "") {
+ ElMessage.warning("鏃犳硶鐢熸垚浜岀淮鐮侊細缂哄皯鍙拌处 ID");
+ return;
+ }
+ procurementQrCompositeUrl.value = "";
+ procurementQrDownloadBaseName.value = "";
+ try {
+ const { dataUrl, baseName } = await buildProcurementQrCompositeDataUrl(row);
+ procurementQrCompositeUrl.value = dataUrl;
+ procurementQrDownloadBaseName.value = baseName;
+ procurementQrDialogVisible.value = true;
+ } catch {
+ ElMessage.error("浜岀淮鐮佺敓鎴愬け璐�");
+ }
+ };
+
+ const downloadProcurementQrCode = () => {
+ if (!procurementQrCompositeUrl.value) return;
+ const a = document.createElement("a");
+ a.href = procurementQrCompositeUrl.value;
+ a.download = `閲囪喘鍙拌处浜岀淮鐮�-${procurementQrDownloadBaseName.value}.png`;
+ a.click();
+ };
+
// 鑾峰彇妯℃澘淇℃伅
const getTemplateList = async () => {
let res = await getPurchaseTemplateList();
@@ -2009,4 +2204,20 @@
transform: scale(1.2);
}
}
+
+ .procurement-qr-dialog {
+ text-align: center;
+ padding-bottom: 8px;
+ }
+
+ .procurement-qr-composite-img {
+ max-width: 100%;
+ height: auto;
+ display: block;
+ margin: 0 auto 28px;
+ }
+
+ .procurement-qr-save-btn {
+ margin-bottom: 12px;
+ }
</style>
--
Gitblit v1.9.3