From d43d7b9c90ae36c2d369f5c52b207b5549675766 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 03 二月 2026 15:33:07 +0800
Subject: [PATCH] 双奇点改造 1.产品维护添加图片、高度等字段
---
multiple/config.json | 20 +-
src/views/basicData/product/index.vue | 326 ++++++++++++++++++++++++++++++++++++++++++++--
multiple/assets/favicon/SQDico.ico | 0
multiple/assets/screen/SQDView.png | 0
src/views/basicData/product/ImportExcel/index.vue | 59 +++++++-
multiple/assets/logo/SQDLogo.png | 0
6 files changed, 370 insertions(+), 35 deletions(-)
diff --git a/multiple/assets/favicon/SQDico.ico b/multiple/assets/favicon/SQDico.ico
new file mode 100644
index 0000000..cd34955
--- /dev/null
+++ b/multiple/assets/favicon/SQDico.ico
Binary files differ
diff --git a/multiple/assets/logo/SQDLogo.png b/multiple/assets/logo/SQDLogo.png
new file mode 100644
index 0000000..271f835
--- /dev/null
+++ b/multiple/assets/logo/SQDLogo.png
Binary files differ
diff --git a/multiple/assets/screen/SQDView.png b/multiple/assets/screen/SQDView.png
new file mode 100644
index 0000000..f53a22f
--- /dev/null
+++ b/multiple/assets/screen/SQDView.png
Binary files differ
diff --git a/multiple/config.json b/multiple/config.json
index 7ad6795..a760667 100644
--- a/multiple/config.json
+++ b/multiple/config.json
@@ -3,19 +3,19 @@
"env": {
"VITE_APP_TITLE": "鑺浜戯紙绠$悊淇℃伅绯荤粺锛�"
},
- "screen": "screen/JZYJView.png",
- "logo": "logo/HYSNLogo.png",
- "favicon": "favicon/HYSNico.ico"
+ "screen": "screen/SQDView.png",
+ "logo": "logo/SQDLogo.png",
+ "favicon": "favicon/SQDico.ico"
},
- "TEST": {
+ "SQD": {
"env": {
- "VITE_APP_TITLE": "涓皬浼佷笟鏁板瓧鍖栬浆鍨嬩簩绾у椁愬寘",
- "VITE_BASE_API": "http://1.15.17.182:9003",
- "VITE_JAVA_API": "http://1.15.17.182:9002"
+ "VITE_APP_TITLE": "澶╂触鍙屽鐐圭鐞嗙郴缁�",
+ "VITE_BASE_API": "http://114.132.189.42:9042",
+ "VITE_JAVA_API": "http://114.132.189.42:9044"
},
- "screen": "screen/HYSNView.png",
- "logo": "logo/ZGLTLogo.png",
- "favicon": "favicon/favicon.ico"
+ "screen": "screen/SQDView.png",
+ "logo": "logo/SQDLogo.png",
+ "favicon": "favicon/SQDico.ico"
},
"screen": "/src/assets/images/login-background.png",
"logo": "/src/assets/logo/logo.png",
diff --git a/src/views/basicData/product/ImportExcel/index.vue b/src/views/basicData/product/ImportExcel/index.vue
index c25d254..68b6913 100644
--- a/src/views/basicData/product/ImportExcel/index.vue
+++ b/src/views/basicData/product/ImportExcel/index.vue
@@ -3,15 +3,36 @@
瀵煎叆
</el-button>
<el-dialog v-model="upload.open" :title="upload.title">
- <FileUpload
- ref="fileUploadRef"
+ <el-upload
+ ref="uploadRef"
+ :limit="1"
accept=".xlsx, .xls"
:headers="upload.headers"
:action="upload.url + '?updateSupport=' + upload.updateSupport"
:disabled="upload.isUploading"
- :showTip="false"
- @success="handleFileSuccess"
- />
+ :before-upload="upload.beforeUpload"
+ :on-progress="upload.onProgress"
+ :on-success="upload.onSuccess"
+ :on-error="upload.onError"
+ :on-change="upload.onChange"
+ :auto-upload="false"
+ drag
+ >
+ <el-icon class="el-icon--upload"><UploadFilled /></el-icon>
+ <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
+ <template #tip>
+ <div class="el-upload__tip text-center">
+ <span>浠呭厑璁稿鍏ls銆亁lsx鏍煎紡鏂囦欢銆�</span>
+ <el-link
+ type="primary"
+ :underline="false"
+ style="font-size: 12px; vertical-align: baseline"
+ @click="handleDownloadTemplate"
+ >涓嬭浇妯℃澘</el-link
+ >
+ </div>
+ </template>
+ </el-upload>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button>
@@ -22,17 +43,18 @@
</template>
<script setup>
-import { reactive } from "vue";
+import { reactive, ref, getCurrentInstance } from "vue";
import { getToken } from "@/utils/auth.js";
-import { FileUpload } from "@/components/Upload";
import { ElMessage } from "element-plus";
+import { UploadFilled } from "@element-plus/icons-vue";
defineOptions({
name: "浜у搧缁存姢瀵煎叆",
});
const emits = defineEmits(["uploadSuccess"]);
-const fileUploadRef = ref();
+const uploadRef = ref();
+const { proxy } = getCurrentInstance();
const upload = reactive({
// 鏄惁鏄剧ず寮瑰嚭灞傦紙渚涘簲鍟嗗鍏ワ級
open: false,
@@ -44,6 +66,20 @@
headers: { Authorization: "Bearer " + getToken() },
// 涓婁紶鐨勫湴鍧�
url: import.meta.env.VITE_APP_BASE_API + "/system/supplier/import",
+ updateSupport: false,
+ beforeUpload: () => {
+ upload.isUploading = true;
+ },
+ onProgress: () => {},
+ onChange: () => {},
+ onError: () => {
+ upload.isUploading = false;
+ ElMessage({ message: "涓婁紶澶辫触", type: "error" });
+ },
+ onSuccess: (response) => {
+ upload.isUploading = false;
+ handleFileSuccess(response);
+ },
});
// 鐐瑰嚮瀵煎叆
const handleImport = () => {
@@ -51,8 +87,13 @@
upload.title = "浜у搧瀵煎叆";
};
+// 涓嬭浇瀵煎叆妯℃澘
+const handleDownloadTemplate = () => {
+ proxy.download("/basic/product/downloadTemplate", {}, "浜у搧瀵煎叆妯℃澘.xlsx");
+};
+
const submitFileForm = () => {
- fileUploadRef.value.uploadApi();
+ uploadRef.value.submit();
};
const handleFileSuccess = (response) => {
diff --git a/src/views/basicData/product/index.vue b/src/views/basicData/product/index.vue
index c9058aa..4b36793 100644
--- a/src/views/basicData/product/index.vue
+++ b/src/views/basicData/product/index.vue
@@ -92,7 +92,18 @@
@selection-change="handleSelectionChange"
:tableLoading="tableLoading"
@pagination="pagination"
- ></PIMTable>
+ >
+ <template #productImage="{ row }">
+ <img
+ v-if="row.url"
+ class="upload-img"
+ :src="javaApiUrl + row.url"
+ @click="previewImage(row.url)"
+ style="cursor: pointer"
+ />
+ <span v-else style="color: #909399">鏆傛棤鍥剧墖</span>
+ </template>
+ </PIMTable>
</div>
<el-dialog v-model="productDia" title="浜у搧" width="400px" @keydown.enter.prevent>
<el-form
@@ -127,7 +138,7 @@
<el-dialog
v-model="modelDia"
title="瑙勬牸鍨嬪彿"
- width="400px"
+ width="600px"
@close="closeModelDia"
@keydown.enter.prevent
>
@@ -138,8 +149,8 @@
:rules="modelRules"
ref="modelFormRef"
>
- <el-row>
- <el-col :span="24">
+ <el-row :gutter="20">
+ <el-col :span="12">
<el-form-item label="瑙勬牸鍨嬪彿锛�" prop="model">
<el-input
v-model="modelForm.model"
@@ -149,9 +160,7 @@
/>
</el-form-item>
</el-col>
- </el-row>
- <el-row>
- <el-col :span="24">
+ <el-col :span="12">
<el-form-item label="鍗曚綅锛�" prop="unit">
<el-input
v-model="modelForm.unit"
@@ -159,6 +168,79 @@
clearable
@keydown.enter.prevent
/>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="楂樺害锛�" prop="height">
+ <el-input
+ v-model="modelForm.height"
+ placeholder="璇疯緭鍏ラ珮搴�"
+ clearable
+ @keydown.enter.prevent
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="姣忎欢鏁伴噺/鏀細" prop="boxNum">
+ <el-input-number
+ :step="1"
+ :min="0"
+ style="width: 100%"
+ v-model="modelForm.boxNum"
+ @change="calculateTotalPrice"
+ placeholder="璇疯緭鍏ユ瘡浠舵暟閲�"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="鍗曚环(鍏�)/浠讹細" prop="taxInclusiveUnitPrice">
+ <el-input-number
+ :step="0.01"
+ :min="0"
+ style="width: 100%"
+ v-model="modelForm.taxInclusiveUnitPrice"
+ @change="calculateTotalPrice"
+ placeholder="璇疯緭鍏ュ崟浠�"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鍗曚环(缇庡厓)/浠讹細" prop="dollarPrice">
+ <el-input-number
+ :step="0.01"
+ :min="0"
+ style="width: 100%"
+ v-model="modelForm.dollarPrice"
+ placeholder="璇疯緭鍏ョ編鍏冨崟浠�"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="24">
+ <el-form-item label="浜у搧鍥剧墖锛�" prop="url">
+ <el-upload
+ :action="uploadUrl"
+ :before-upload="handleBeforeUpload"
+ :on-success="(res, file) => handleUploadSuccess(res, file)"
+ :on-error="handleUploadError"
+ name="file"
+ :show-file-list="false"
+ :headers="headers"
+ accept="image/*"
+ :data="{ type: 13 }"
+ >
+ <img
+ v-if="modelForm.url"
+ class="upload-img-dialog"
+ :src="javaApiUrl + modelForm.url"
+ />
+ <el-icon v-else class="avatar-uploader-icon-dialog"><Plus /></el-icon>
+ </el-upload>
</el-form-item>
</el-col>
</el-row>
@@ -174,8 +256,10 @@
</template>
<script setup>
-import { ref } from "vue";
+import { ref, reactive, toRefs, getCurrentInstance, nextTick } from "vue";
import { ElMessageBox } from "element-plus";
+import { Plus } from "@element-plus/icons-vue";
+import { getToken } from "@/utils/auth";
import {
addOrEditProduct,
addOrEditProductModel,
@@ -185,6 +269,7 @@
productTreeList,
} from "@/api/basicData/product.js";
import ImportExcel from "./ImportExcel/index.vue";
+import PIMTable from "@/components/PIMTable/PIMTable.vue";
const { proxy } = getCurrentInstance();
const tree = ref(null);
@@ -202,12 +287,40 @@
const expandedKeys = ref([]);
const tableColumn = ref([
{
+ label: "浜у搧鍥剧墖",
+ prop: "url",
+ dataType: "slot",
+ slot: "productImage",
+ align: "center",
+ width: 100,
+ },
+ {
label: "瑙勬牸鍨嬪彿",
prop: "model",
},
{
label: "鍗曚綅",
prop: "unit",
+ },
+ {
+ label: "楂樺害",
+ prop: "height",
+ width: 120,
+ },
+ {
+ label: "姣忎欢鏁伴噺/鏀�",
+ prop: "boxNum",
+ width: 120,
+ },
+ {
+ label: "鍗曚环(鍏�)/浠�",
+ prop: "taxInclusiveUnitPrice",
+ width: 120,
+ },
+ {
+ label: "鍗曚环(缇庡厓)/浠�",
+ prop: "dollarPrice",
+ width: 130,
},
{
dataType: "action",
@@ -228,6 +341,11 @@
const tableLoading = ref(false);
const isShowButton = ref(false);
const selectedRows = ref([]);
+
+// 涓婁紶閰嶇疆
+const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/file/upload"); // 涓婁紶鐨勫浘鐗囨湇鍔″櫒鍦板潃
+const headers = ref({ Authorization: "Bearer " + getToken() });
+const javaApiUrl = proxy.javaApi || import.meta.env.VITE_APP_BASE_API;
const page = reactive({
current: 1,
size: 10,
@@ -246,10 +364,20 @@
modelForm: {
model: "",
unit: "",
+ url: "",
+ height: "",
+ boxNum: null,
+ taxInclusiveUnitPrice: null,
+ dollarPrice: null,
},
modelRules: {
- model: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ model: [{ required: true, message: "璇疯緭鍏ヨ鏍煎瀷鍙�", trigger: "blur" }],
+ unit: [{ required: true, message: "璇疯緭鍏ュ崟浣�", trigger: "blur" }],
+ url: [{ required: true, message: "璇蜂笂浼犱骇鍝佸浘鐗�", trigger: "change" }],
+ height: [{ required: true, message: "璇疯緭鍏ラ珮搴�", trigger: "blur" }],
+ boxNum: [{ required: true, message: "璇疯緭鍏ユ瘡浠舵暟閲�/鏀�", trigger: "change" }],
+ taxInclusiveUnitPrice: [{ required: true, message: "璇疯緭鍏ュ崟浠�(鍏�)/浠�", trigger: "change" }],
+ dollarPrice: [{ required: true, message: "璇疯緭鍏ュ崟浠�(缇庡厓)/浠�", trigger: "change" }],
},
});
const { form, rules, modelForm, modelRules } = toRefs(data);
@@ -285,11 +413,30 @@
const openModelDia = (type, data) => {
modelOperationType.value = type;
modelDia.value = true;
- modelForm.value.model = "";
- modelForm.value.model = "";
- modelForm.value.id = "";
- if (type === "edit") {
- modelForm.value = { ...data };
+ // 閲嶇疆琛ㄥ崟
+ modelForm.value = {
+ model: "",
+ unit: "",
+ url: "",
+ height: "",
+ boxNum: null,
+ taxInclusiveUnitPrice: null,
+ dollarPrice: null,
+ id: "",
+ };
+ if (type === "edit" && data) {
+ // 濡傛灉 url 鏄� Windows 璺緞锛岄渶瑕佽浆鎹�
+ let url = data.url || "";
+ if (url && url.indexOf("\\") > -1) {
+ url = processFileUrl(url);
+ }
+ modelForm.value = {
+ ...data,
+ url: url,
+ boxNum: data.boxNum || null,
+ taxInclusiveUnitPrice: data.taxInclusiveUnitPrice || null,
+ dollarPrice: data.dollarPrice || null,
+ };
}
};
// 鎻愪氦浜у搧鍚嶇О淇敼
@@ -391,10 +538,107 @@
size: page.size,
}).then((res) => {
console.log("res", res);
- tableData.value = res.records;
+ // 澶勭悊杩斿洖鐨勬暟鎹紝杞崲 Windows 璺緞涓哄彲璁块棶鐨� URL
+ tableData.value = (res.records || []).map((item) => {
+ if (item.url && item.url.indexOf("\\") > -1) {
+ item.url = processFileUrl(item.url);
+ }
+ return item;
+ });
page.total = res.total;
tableLoading.value = false;
});
+};
+
+// 涓婁紶鍓嶆牎楠�
+const handleBeforeUpload = (file) => {
+ const isImage = file.type.startsWith("image/");
+ const isLt5M = file.size / 1024 / 1024 < 5;
+
+ if (!isImage) {
+ proxy.$modal.msgError("涓婁紶鏂囦欢鍙兘鏄浘鐗囨牸寮�!");
+ return false;
+ }
+ if (!isLt5M) {
+ proxy.$modal.msgError("涓婁紶鍥剧墖澶у皬涓嶈兘瓒呰繃 5MB!");
+ return false;
+ }
+ return true;
+};
+
+// 澶勭悊鏂囦欢璺緞锛氬皢 Windows 璺緞杞崲涓哄彲璁块棶鐨� URL
+const processFileUrl = (filePath) => {
+ if (!filePath) return "";
+
+ // 濡傛灉璺緞鏄� Windows 璺緞鏍煎紡锛堝寘鍚弽鏂滄潬锛夛紝闇�瑕佽浆鎹�
+ if (filePath && filePath.indexOf("\\") > -1) {
+ // 鏌ユ壘 temp 鎴� uploads 鍏抽敭瀛楃殑浣嶇疆
+ const tempIndex = filePath.toLowerCase().indexOf("temp");
+ const uploadsIndex = filePath.toLowerCase().indexOf("uploads");
+
+ if (tempIndex > -1) {
+ // 浠� temp 寮�濮嬫彁鍙栫浉瀵硅矾寰勶紝骞跺皢鍙嶆枩鏉犳浛鎹负姝f枩鏉�
+ const relativePath = filePath.substring(tempIndex).replace(/\\/g, "/");
+ filePath = "/" + relativePath;
+ } else if (uploadsIndex > -1) {
+ // 浠� uploads 寮�濮嬫彁鍙栫浉瀵硅矾寰�
+ const relativePath = filePath.substring(uploadsIndex).replace(/\\/g, "/");
+ filePath = "/" + relativePath;
+ } else {
+ // 濡傛灉娌℃湁鎵惧埌鍏抽敭瀛楋紝鎻愬彇鏂囦欢鍚�
+ const parts = filePath.split("\\");
+ const fileName = parts[parts.length - 1];
+ filePath = "/temp/uploads/" + fileName;
+ }
+ }
+
+ // 纭繚璺緞浠� / 寮�澶�
+ if (filePath && !filePath.startsWith("/")) {
+ filePath = "/" + filePath;
+ }
+
+ return filePath;
+};
+
+// 涓婁紶鎴愬姛
+const handleUploadSuccess = (res, file) => {
+ if (res.code === 200) {
+ // 浠� res.data 涓幏鍙� tempPath锛屽苟杞崲涓哄彲璁块棶鐨� URL
+ const tempPath = res.data?.tempPath || res.tempPath;
+ if (tempPath) {
+ const relativePath = processFileUrl(tempPath);
+ modelForm.value.url = relativePath;
+ proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
+ // 瑙﹀彂琛ㄥ崟楠岃瘉
+ nextTick(() => {
+ proxy.$refs.modelFormRef?.validateField("url");
+ });
+ } else {
+ proxy.$modal.msgError("涓婁紶鎴愬姛浣嗘湭杩斿洖鏂囦欢璺緞");
+ }
+ } else {
+ proxy.$modal.msgError(res.msg || "涓婁紶澶辫触");
+ }
+};
+
+// 涓婁紶澶辫触
+const handleUploadError = () => {
+ proxy.$modal.msgError("涓婁紶澶辫触锛岃閲嶈瘯");
+};
+
+// 璁$畻鎬讳环
+const calculateTotalPrice = () => {
+ // 濡傛灉闇�瑕佽绠楁�讳环锛屽彲浠ュ湪杩欓噷娣诲姞閫昏緫
+ // if (modelForm.value.boxNum && modelForm.value.taxInclusiveUnitPrice) {
+ // modelForm.value.totalPrice = modelForm.value.boxNum * modelForm.value.taxInclusiveUnitPrice;
+ // }
+};
+
+// 棰勮鍥剧墖
+const previewImage = (url) => {
+ if (url) {
+ window.open(javaApiUrl + url, "_blank");
+ }
};
// 鍒犻櫎瑙勬牸鍨嬪彿
const handleDelete = () => {
@@ -529,4 +773,54 @@
.product-tree-scroll::-webkit-scrollbar-thumb:hover {
background: #909399;
}
+
+.upload-img {
+ width: 50px;
+ height: 50px;
+ object-fit: cover;
+ cursor: pointer;
+ border-radius: 4px;
+}
+
+.avatar-uploader-icon {
+ font-size: 28px;
+ color: #8c939d;
+ width: 50px;
+ height: 50px;
+ line-height: 50px;
+ text-align: center;
+ border: 1px dashed #d9d9d9;
+ border-radius: 4px;
+ cursor: pointer;
+}
+
+.avatar-uploader-icon:hover {
+ border-color: #409eff;
+}
+
+.upload-img-dialog {
+ width: 100px;
+ height: 100px;
+ object-fit: cover;
+ cursor: pointer;
+ border-radius: 4px;
+ border: 1px solid #dcdfe6;
+}
+
+.avatar-uploader-icon-dialog {
+ font-size: 28px;
+ color: #8c939d;
+ width: 100px;
+ height: 100px;
+ line-height: 100px;
+ text-align: center;
+ border: 1px dashed #d9d9d9;
+ border-radius: 4px;
+ cursor: pointer;
+ display: block;
+}
+
+.avatar-uploader-icon-dialog:hover {
+ border-color: #409eff;
+}
</style>
--
Gitblit v1.9.3