From 45c5ff14bebbba8eb3496871ed3f41ee4e36f835 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期三, 28 一月 2026 11:31:49 +0800
Subject: [PATCH] 安全规程与资质管理模块
---
src/api/safeProduction/safeQualifications.js | 61 +++
src/views/safeProduction/safeQualifications/index.vue | 860 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 921 insertions(+), 0 deletions(-)
diff --git a/src/api/safeProduction/safeQualifications.js b/src/api/safeProduction/safeQualifications.js
new file mode 100644
index 0000000..bde2443
--- /dev/null
+++ b/src/api/safeProduction/safeQualifications.js
@@ -0,0 +1,61 @@
+// 鍙戣揣鍙拌处椤甸潰鎺ュ彛
+import request from "@/utils/request";
+
+// 鍒嗛〉鏌ヨ
+export function qualificationsListPage(query) {
+ return request({
+ url: "/safeCertification/page",
+ method: "get",
+ params: query,
+ });
+}
+
+// 鏂板瀹夊叏瑙勭▼涓庤祫璐ㄧ鐞�
+export function safeCertificationAdd(query) {
+ return request({
+ url: '/safeCertification',
+ method: 'post',
+ data: query
+ })
+}
+// 淇敼瀹夊叏瑙勭▼涓庤祫璐ㄧ鐞�
+export function safeCertificationUpdate(query) {
+ return request({
+ url: '/safeCertification',
+ method: 'put',
+ data: query
+ })
+}
+// 鍒犻櫎瀹夊叏瑙勭▼涓庤祫璐ㄧ鐞�
+export function safeCertificationDel(ids) {
+ return request({
+ url: '/safeCertification/' + ids,
+ method: 'delete',
+ data: ids
+ })
+}
+
+// 鏌ヨ闄勪欢鍒楄〃
+export function fileListPage(query) {
+ return request({
+ url: "/safeCertificationFile/listPage",
+ method: "get",
+ params: query,
+ });
+}
+// 娣诲姞闄勪欢
+export function safeCertificationFileAdd(query) {
+ return request({
+ url: '/safeCertificationFile/add',
+ method: 'post',
+ data: query
+ })
+}
+// 鍒犻櫎闄勪欢
+export function safeCertificationFileDel(ids) {
+ return request({
+ url: '/safeCertificationFile/del',
+ method: 'delete',
+ data: ids
+ })
+}
\ No newline at end of file
diff --git a/src/views/safeProduction/safeQualifications/index.vue b/src/views/safeProduction/safeQualifications/index.vue
new file mode 100644
index 0000000..8bf320b
--- /dev/null
+++ b/src/views/safeProduction/safeQualifications/index.vue
@@ -0,0 +1,860 @@
+<template>
+ <div class="app-container">
+ <div class="search_form">
+ <el-form :model="searchForm"
+ :inline="true">
+ <el-form-item label="瑙勭▼璧勮川鍚嶇О锛�">
+ <el-input v-model="searchForm.name"
+ placeholder="璇疯緭鍏�"
+ clearable
+ prefix-icon="Search"
+ @change="handleQuery" />
+ </el-form-item>
+ <el-form-item label="瑙勭▼璧勮川绫诲瀷锛�">
+ <el-select v-model="searchForm.type"
+ placeholder="璇烽�夋嫨"
+ clearable
+ style="width: 200px"
+ prefix-icon="Search"
+ @change="handleQuery">
+ <el-option v-for="item in type_qualification"
+ :key="item.value"
+ :label="item.label"
+ :value="item.value" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="瑙勭▼璧勮川缂栧彿锛�">
+ <el-input v-model="searchForm.code"
+ placeholder="璇疯緭鍏�"
+ clearable
+ prefix-icon="Search"
+ @change="handleQuery" />
+ </el-form-item>
+ <el-form-item>
+ <el-button type="primary"
+ @click="handleQuery"> 鎼滅储 </el-button>
+ </el-form-item>
+ </el-form>
+ </div>
+ <div class="table_list">
+ <div class="actions">
+ <div></div>
+ <div>
+ <el-button type="primary"
+ @click="openForm('add')">
+ 鏂板瑙勭▼璧勮川
+ </el-button>
+ <!-- <el-button type="primary"
+ plain
+ @click="handleImport">瀵煎叆</el-button>
+ <el-button @click="handleOut">瀵煎嚭</el-button> -->
+ <el-button type="danger"
+ plain
+ @click="handleDelete">鍒犻櫎</el-button>
+ <!-- <el-button type="primary"
+ plain
+ @click="handlePrint">鎵撳嵃</el-button> -->
+ </div>
+ </div>
+ <el-table :data="tableData"
+ border
+ v-loading="tableLoading"
+ @selection-change="handleSelectionChange"
+ :expand-row-keys="expandedRowKeys"
+ :row-key="(row) => row.id"
+ :row-class-name="getRowClass"
+ style="width: 100%"
+ height="calc(100vh - 18.5em)">
+ <el-table-column align="center"
+ type="selection"
+ width="55"
+ fixed="left" />
+ <el-table-column align="center"
+ label="搴忓彿"
+ type="index"
+ width="60" />
+ <el-table-column label="瑙勭▼璧勮川鍚嶇О"
+ prop="name"
+ width="180"
+ show-overflow-tooltip />
+ <el-table-column label="瑙勭▼璧勮川缂栧彿"
+ prop="code"
+ show-overflow-tooltip />
+ <el-table-column label="瑙勭▼璧勮川绫诲瀷"
+ prop="type"
+ show-overflow-tooltip />
+ <el-table-column label="鐗堟湰鍙�"
+ prop="version"
+ width="180"
+ show-overflow-tooltip />
+ <el-table-column label="澶囨敞"
+ prop="remark"
+ show-overflow-tooltip />
+ <el-table-column label="鏈夋晥鏈�"
+ prop="effectiveTime"
+ 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="downLoadFile(scope.row)">闄勪欢</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ <pagination v-show="total > 0"
+ :total="total"
+ layout="total, sizes, prev, pager, next, jumper"
+ :page="page.current"
+ :limit="page.size"
+ @pagination="paginationChange" />
+ </div>
+ <FormDialog v-model="dialogFormVisible"
+ :title="operationType === 'add' ? '鏂板瑙勭▼璧勮川椤甸潰' : '缂栬緫瑙勭▼璧勮川椤甸潰'"
+ :width="'70%'"
+ :operation-type="operationType"
+ @close="closeDia"
+ @confirm="submitForm"
+ @cancel="closeDia">
+ <el-form :model="form"
+ label-width="140px"
+ label-position="top"
+ :rules="rules"
+ ref="formRef">
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="瑙勭▼璧勮川鍚嶇О锛�"
+ prop="name">
+ <el-input v-model="form.name"
+ placeholder="璇疯緭鍏�"
+ clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="瑙勭▼璧勮川缂栧彿锛�"
+ prop="code">
+ <el-input v-model="form.code"
+ placeholder="璇疯緭鍏�"
+ clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="瑙勭▼璧勮川绫诲瀷锛�"
+ prop="type">
+ <el-select v-model="form.type"
+ placeholder="璇烽�夋嫨"
+ clearable>
+ <el-option v-for="item in type_qualification"
+ :key="item.value"
+ :label="item.label"
+ :value="item.value" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鐗堟湰鍙凤細"
+ prop="version">
+ <el-input v-model="form.version"
+ placeholder="璇疯緭鍏�"
+ clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="鏈夋晥鏈燂細"
+ prop="effectiveTime">
+ <el-date-picker style="width: 100%"
+ v-model="form.effectiveTime"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ type="date"
+ placeholder="璇烽�夋嫨"
+ clearable
+ :disabled="operationType === 'view'" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="澶囨敞路锛�"
+ prop="remark">
+ <el-input v-model="form.remark"
+ placeholder="璇疯緭鍏�"
+ clearable
+ type="textarea"
+ :rows="1"
+ :disabled="operationType === 'view'" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+ </FormDialog>
+ <!-- 闄勪欢鍒楄〃寮圭獥 -->
+ <FileListDialog ref="fileListRef"
+ v-model="fileListDialogVisible"
+ :show-upload-button="true"
+ :show-delete-button="true"
+ :upload-method="handleUpload"
+ :delete-method="handleFileDelete"
+ title="闄勪欢鍒楄〃" />
+ </div>
+</template>
+
+<script setup>
+ import { getToken } from "@/utils/auth";
+ import pagination from "@/components/PIMTable/Pagination.vue";
+ import { onMounted, ref, getCurrentInstance } from "vue";
+ import { ElMessageBox, ElMessage } 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 {
+ qualificationsListPage,
+ safeCertificationAdd,
+ safeCertificationUpdate,
+ safeCertificationDel,
+ fileListPage,
+ safeCertificationFileAdd,
+ safeCertificationFileDel,
+ } from "@/api/safeProduction/safeQualifications.js";
+ import useFormData from "@/hooks/useFormData.js";
+ import request from "@/utils/request";
+ import dayjs from "dayjs";
+
+ const userStore = useUserStore();
+ const { proxy } = getCurrentInstance();
+ const tableData = ref([]);
+ const selectedRows = ref([]);
+ const userList = ref([]);
+ const tableLoading = ref(false);
+ const page = reactive({
+ current: 1,
+ size: 100,
+ });
+ const total = ref(0);
+
+ // 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
+ const operationType = ref("");
+ const dialogFormVisible = ref(false);
+ const data = reactive({
+ searchForm: {
+ name: "", // 瑙勭▼璧勮川鍚嶇О
+ code: "", // 瑙勭▼璧勮川缂栧彿
+ type: "", // 瑙勭▼璧勮川绫诲瀷
+ },
+ form: {
+ salesContractNo: "",
+ salesman: "",
+ customerId: "",
+ entryPerson: "",
+ entryDate: "",
+ maintenanceTime: "",
+ executionDate: "",
+ },
+ rules: {
+ code: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ name: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ type: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ effectiveTime: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ version: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ },
+ });
+ // 瑙勭▼璧勮川绫诲瀷閫夐」
+ const { type_qualification } = proxy.useDict("type_qualification");
+ const { form, rules } = toRefs(data);
+ const { form: searchForm } = useFormData(data.searchForm);
+ // 浜у搧琛ㄥ崟寮规鏁版嵁
+ const productFormVisible = ref(false);
+
+ const quotationLoading = ref(false);
+ const quotationList = ref([]);
+ const quotationSearchForm = reactive({
+ quotationNo: "",
+ customer: "",
+ });
+
+ // 瀵煎叆鐩稿叧
+ const importUploadRef = ref(null);
+ const importUpload = reactive({
+ title: "瀵煎叆閿�鍞彴璐�",
+ open: false,
+ url: import.meta.env.VITE_APP_BASE_API + "/sales/ledger/import",
+ headers: { Authorization: "Bearer " + getToken() },
+ isUploading: false,
+ beforeUpload: file => {
+ const isExcel = file.name.endsWith(".xlsx") || file.name.endsWith(".xls");
+ const isLt10M = file.size / 1024 / 1024 < 10;
+ if (!isExcel) {
+ proxy.$modal.msgError("涓婁紶鏂囦欢鍙兘鏄� xlsx/xls 鏍煎紡!");
+ return false;
+ }
+ if (!isLt10M) {
+ proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃 10MB!");
+ return false;
+ }
+ return true;
+ },
+ onChange: (file, fileList) => {
+ console.log("鏂囦欢鐘舵�佹敼鍙�", file, fileList);
+ },
+ onProgress: (event, file, fileList) => {
+ console.log("涓婁紶涓�...", event.percent);
+ },
+ onSuccess: (response, file, fileList) => {
+ console.log("涓婁紶鎴愬姛", response, file, fileList);
+ importUpload.isUploading = false;
+ if (response.code === 200) {
+ proxy.$modal.msgSuccess("瀵煎叆鎴愬姛");
+ importUpload.open = false;
+ if (importUploadRef.value) {
+ importUploadRef.value.clearFiles();
+ }
+ getList();
+ } else {
+ proxy.$modal.msgError(response.msg || "瀵煎叆澶辫触");
+ }
+ },
+ onError: (error, file, fileList) => {
+ console.error("涓婁紶澶辫触", error, file, fileList);
+ importUpload.isUploading = false;
+ proxy.$modal.msgError("瀵煎叆澶辫触锛岃閲嶈瘯");
+ },
+ });
+
+ // 鏌ヨ鍒楄〃
+ /** 鎼滅储鎸夐挳鎿嶄綔 */
+ const handleQuery = () => {
+ // 鍙湁鍦ㄧ偣鍑绘悳绱㈡寜閽椂鎵嶉噸缃〉鐮佸埌绗竴椤�
+ // 閬垮厤琛ㄥ崟瀛楁change浜嬩欢骞叉壈鍒嗛〉
+ if (arguments.length === 0) {
+ page.current = 1;
+ }
+ expandedRowKeys.value = [];
+ getList();
+ };
+ const paginationChange = obj => {
+ page.current = obj.page;
+ page.size = obj.limit;
+ getList();
+ };
+ const getList = () => {
+ tableLoading.value = true;
+ const { entryDate, ...rest } = searchForm;
+ // 灏嗚寖鍥存棩鏈熷瓧娈典紶閫掔粰鍚庣
+ const params = { ...rest, ...page };
+ // 绉婚櫎褰曞叆鏃ユ湡鐨勯粯璁ゅ�艰缃紝鍙繚鐣欒寖鍥存棩鏈熷瓧娈�
+ delete params.entryDate;
+ return qualificationsListPage(params)
+ .then(res => {
+ tableLoading.value = false;
+ tableData.value = res.data.records;
+ total.value = res.data.total;
+ return res;
+ })
+ .catch(() => {
+ tableLoading.value = false;
+ });
+ };
+
+ const findNodeById = (nodes, productId) => {
+ for (let i = 0; i < nodes.length; i++) {
+ if (nodes[i].value === productId) {
+ return nodes[i].label; // 鎵惧埌鑺傜偣锛岃繑鍥炶鑺傜偣
+ }
+ if (nodes[i].children && nodes[i].children.length > 0) {
+ const foundNode = findNodeById(nodes[i].children, productId);
+ if (foundNode) {
+ return foundNode; // 鍦ㄥ瓙鑺傜偣涓壘鍒帮紝杩斿洖璇ヨ妭鐐�
+ }
+ }
+ }
+ return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
+ };
+ // 琛ㄦ牸閫夋嫨鏁版嵁
+ const handleSelectionChange = selection => {
+ selectedRows.value = selection;
+ console.log("selection", selectedRows.value);
+ };
+ const expandedRowKeys = ref([]);
+ // 鎵撳紑寮规
+ const openForm = async (type, row) => {
+ operationType.value = type;
+ if (type === "add") {
+ form.value = {
+ salesContractNo: "",
+ salesman: "",
+ customerId: "",
+ entryPerson: "",
+ entryDate: "",
+ maintenanceTime: "",
+ executionDate: "",
+ };
+ } else {
+ form.value = row;
+ }
+ dialogFormVisible.value = true;
+ };
+
+ 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 submitForm = () => {
+ proxy.$refs["formRef"].validate(valid => {
+ if (valid) {
+ if (operationType.value === "add") {
+ safeCertificationAdd(form.value).then(res => {
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ closeDia();
+ getList();
+ });
+ } else {
+ safeCertificationUpdate(form.value).then(res => {
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ closeDia();
+ getList();
+ });
+ }
+ }
+ });
+ };
+ // 鍏抽棴寮规
+ const closeDia = () => {
+ proxy.resetForm("formRef");
+ dialogFormVisible.value = false;
+ };
+ // 鍏抽棴浜у搧寮规
+ const closeProductDia = () => {
+ proxy.resetForm("productFormRef");
+ productFormVisible.value = false;
+ };
+ // 鍒犻櫎
+ const handleDelete = () => {
+ let ids = [];
+ if (selectedRows.value.length > 0) {
+ ids = selectedRows.value.map(item => item.id);
+ } else {
+ proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+ return;
+ }
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ safeCertificationDel(ids).then(res => {
+ proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+ getList();
+ });
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
+ };
+
+ /**
+ * 鍒ゆ柇鏄惁鍙互鍙戣揣
+ * 鍙湁鍦ㄤ骇鍝佺姸鎬佹槸鍏呰冻锛屽彂璐х姸鎬佹槸寰呭彂璐у拰瀹℃牳鎷掔粷鐨勬椂鍊欐墠鍙互鍙戣揣
+ * @param row 琛屾暟鎹�
+ */
+ const canShip = row => {
+ // 浜у搧鐘舵�佸繀椤绘槸鍏呰冻锛坅pproveStatus === 1锛�
+ if (row.approveStatus !== 1) {
+ return false;
+ }
+
+ // 鑾峰彇鍙戣揣鐘舵��
+ const shippingStatus = row.shippingStatus;
+
+ // 濡傛灉宸插彂璐э紙鏈夊彂璐ф棩鏈熸垨杞︾墝鍙凤級锛屼笉鑳藉啀娆″彂璐�
+ if (row.shippingDate || row.shippingCarNumber) {
+ return false;
+ }
+
+ // 鍙戣揣鐘舵�佸繀椤绘槸"寰呭彂璐�"鎴�"瀹℃牳鎷掔粷"
+ const statusStr = shippingStatus ? String(shippingStatus).trim() : "";
+ return statusStr === "寰呭彂璐�" || statusStr === "瀹℃牳鎷掔粷";
+ };
+
+ /**
+ * 涓嬭浇鏂囦欢
+ *
+ * @param row 涓嬭浇鏂囦欢鐨勭浉鍏充俊鎭璞�
+ */
+ const fileListRef = ref(null);
+ const fileListDialogVisible = ref(false);
+ const currentFileRow = ref(null);
+ const downLoadFile = row => {
+ currentFileRow.value = row;
+ fileListPage({ safeCertificationId: row.id }).then(res => {
+ if (fileListRef.value) {
+ fileListRef.value.open(res.data.records);
+ }
+ });
+ };
+ const currentFactoryName = ref("");
+ const getCurrentFactoryName = async () => {
+ let res = await userStore.getInfo();
+ currentFactoryName.value = res.user.currentFactoryName;
+ };
+
+ /**
+ * 鑾峰彇琛岀被鍚嶏紝鐢ㄤ簬鍒ゆ柇褰撳墠鏃ユ湡鏄惁鎺ヨ繎鏈夋晥鏈�15澶╁唴
+ * @param row 琛屾暟鎹�
+ * @returns 绫诲悕
+ */
+ const getRowClass = ({ row }) => {
+ if (!row.effectiveTime) return "";
+
+ const now = new Date();
+ const effectiveTime = new Date(row.effectiveTime);
+ const diffTime = effectiveTime - now;
+ const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
+
+ if (diffDays >= 0 && diffDays <= 15) {
+ return "warning-row";
+ }
+
+ return "";
+ };
+
+ onMounted(() => {
+ getList();
+ userListNoPage().then(res => {
+ userList.value = res.data;
+ });
+ getCurrentFactoryName();
+ });
+ // 涓婁紶闄勪欢
+ const handleUpload = async () => {
+ if (!currentFileRow.value) {
+ proxy.$modal.msgWarning("璇峰厛閫夋嫨鏁版嵁");
+ return null;
+ }
+
+ return new Promise(resolve => {
+ // 鍒涘缓涓�涓殣钘忕殑鏂囦欢杈撳叆鍏冪礌
+ const input = document.createElement("input");
+ input.type = "file";
+ input.style.display = "none";
+ input.onchange = async e => {
+ const file = e.target.files[0];
+ if (!file) {
+ resolve(null);
+ return;
+ }
+
+ try {
+ // 浣跨敤 FormData 涓婁紶鏂囦欢
+ const formData = new FormData();
+ formData.append("file", file);
+
+ const uploadRes = await request({
+ url: "/file/upload",
+ method: "post",
+ data: formData,
+ headers: {
+ "Content-Type": "multipart/form-data",
+ Authorization: `Bearer ${getToken()}`,
+ },
+ });
+
+ if (uploadRes.code === 200) {
+ // 淇濆瓨闄勪欢淇℃伅
+ const fileData = {
+ safeCertificationId: currentFileRow.value.id,
+ name: uploadRes.data.originalName || file.name,
+ url: uploadRes.data.tempPath || uploadRes.data.url,
+ };
+
+ const saveRes = await safeCertificationFileAdd(fileData);
+ if (saveRes.code === 200) {
+ proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
+ // 閲嶆柊鍔犺浇鏂囦欢鍒楄〃
+ const listRes = await fileListPage({
+ safeCertificationId: currentFileRow.value.id,
+ });
+ if (listRes.code === 200 && fileListRef.value) {
+ const fileList = (listRes.data?.records || []).map(item => ({
+ name: item.name,
+ url: item.url,
+ id: item.id,
+ ...item,
+ }));
+ fileListRef.value.setList(fileList);
+ }
+ // 杩斿洖鏂版枃浠朵俊鎭�
+ resolve({
+ name: fileData.name,
+ url: fileData.url,
+ id: saveRes.data?.id,
+ });
+ } else {
+ proxy.$modal.msgError(saveRes.msg || "鏂囦欢淇濆瓨澶辫触");
+ resolve(null);
+ }
+ } else {
+ proxy.$modal.msgError(uploadRes.msg || "鏂囦欢涓婁紶澶辫触");
+ resolve(null);
+ }
+ } catch (error) {
+ proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
+ resolve(null);
+ } finally {
+ document.body.removeChild(input);
+ }
+ };
+
+ document.body.appendChild(input);
+ input.click();
+ });
+ };
+ // 鍒犻櫎闄勪欢
+ const handleFileDelete = async row => {
+ try {
+ const res = await safeCertificationFileDel([row.id]);
+ if (res.code === 200) {
+ proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+ // 閲嶆柊鍔犺浇鏂囦欢鍒楄〃
+ if (currentFileRow.value && fileListRef.value) {
+ const listRes = await fileListPage({
+ safeCertificationId: currentFileRow.value.id,
+ });
+ if (listRes.code === 200) {
+ const fileList = (listRes.data?.records || []).map(item => ({
+ name: item.name,
+ url: item.url,
+ id: item.id,
+ ...item,
+ }));
+ fileListRef.value.setList(fileList);
+ }
+ }
+ return true; // 杩斿洖 true 琛ㄧず鍒犻櫎鎴愬姛锛岀粍浠朵細鏇存柊鍒楄〃
+ } else {
+ proxy.$modal.msgError(res.msg || "鍒犻櫎澶辫触");
+ return false;
+ }
+ } catch (error) {
+ proxy.$modal.msgError("鍒犻櫎澶辫触");
+ return false;
+ }
+ };
+</script>
+
+<style scoped lang="scss">
+ .ml-10 {
+ margin-left: 10px;
+ }
+
+ .table_list {
+ margin-top: unset;
+ }
+
+ :deep(.warning-row) {
+ background-color: #fef0f0 !important;
+ }
+
+ :deep(.warning-row td) {
+ // color: #cf1322 !important;
+ }
+
+ .actions {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 10px;
+ }
+ .print-preview-dialog {
+ .el-dialog__body {
+ padding: 0;
+ max-height: 80vh;
+ overflow-y: auto;
+ }
+ }
+
+ .print-preview-container {
+ .print-preview-header {
+ padding: 15px;
+ border-bottom: 1px solid #e4e7ed;
+ text-align: center;
+
+ .el-button {
+ margin: 0 10px;
+ }
+ }
+
+ .print-preview-content {
+ padding: 20px;
+ background-color: #f5f5f5;
+ min-height: 400px;
+ }
+ }
+
+ .print-page {
+ width: 220mm;
+ height: 90mm;
+ padding: 10mm;
+ margin: 0 auto;
+ background: white;
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
+ margin-bottom: 10px;
+ box-sizing: border-box;
+ }
+
+ .delivery-note {
+ width: 100%;
+ height: 100%;
+ font-family: "SimSun", serif;
+ font-size: 10px;
+ line-height: 1.2;
+ display: flex;
+ flex-direction: column;
+ }
+
+ .header {
+ text-align: center;
+ margin-bottom: 8px;
+
+ .company-name {
+ font-size: 18px;
+ font-weight: bold;
+ margin-bottom: 4px;
+ }
+
+ .document-title {
+ font-size: 16px;
+ font-weight: bold;
+ }
+ }
+
+ .info-section {
+ margin-bottom: 8px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+
+ .info-row {
+ line-height: 20px;
+
+ .label {
+ font-weight: bold;
+ width: 60px;
+ font-size: 14px;
+ }
+
+ .value {
+ margin-right: 20px;
+ min-width: 80px;
+ font-size: 14px;
+ }
+ }
+ }
+
+ .table-section {
+ margin-bottom: 4px;
+ flex: 1;
+
+ .product-table {
+ width: 100%;
+ border-collapse: collapse;
+ border: 1px solid #000;
+
+ th,
+ td {
+ border: 1px solid #000;
+ padding: 6px;
+ text-align: center;
+ font-size: 14px;
+ line-height: 1.4;
+ }
+
+ th {
+ font-weight: bold;
+ }
+
+ .total-label {
+ text-align: right;
+ font-weight: bold;
+ }
+
+ .total-value {
+ font-weight: bold;
+ }
+ }
+ }
+
+ .footer-section {
+ .footer-row {
+ display: flex;
+ margin-bottom: 3px;
+ line-height: 20px;
+ justify-content: space-between;
+
+ .footer-item {
+ display: flex;
+ margin-right: 20px;
+
+ .label {
+ font-weight: bold;
+ width: 80px;
+ font-size: 14px;
+ }
+
+ .value {
+ min-width: 80px;
+ font-size: 14px;
+ }
+
+ &.address-item {
+ .address-value {
+ min-width: 200px;
+ }
+ }
+ }
+ }
+ }
+
+ @media print {
+ .app-container {
+ display: none;
+ }
+
+ .print-page {
+ box-shadow: none;
+ margin: 0;
+ padding: 10mm;
+ padding-left: 20mm;
+ page-break-inside: avoid;
+ page-break-after: always;
+ }
+ .print-page:last-child {
+ page-break-after: avoid;
+ }
+ }
+</style>
--
Gitblit v1.9.3