作者 lixiang

1、物料管理修改

2、库存管理修改
@@ -5,11 +5,21 @@ @@ -5,11 +5,21 @@
5 <a-form layout="inline" @keyup.enter.native="searchQuery"> 5 <a-form layout="inline" @keyup.enter.native="searchQuery">
6 <a-row :gutter="24"> 6 <a-row :gutter="24">
7 <a-col :xl="6" :lg="7" :md="8" :sm="24"> 7 <a-col :xl="6" :lg="7" :md="8" :sm="24">
  8 + <a-form-item label="物料编码">
  9 + <a-input placeholder="请输入物料编码" v-model="queryParam.materialCode"></a-input>
  10 + </a-form-item>
  11 + </a-col>
  12 + <a-col :xl="6" :lg="7" :md="8" :sm="24">
8 <a-form-item label="物料长描述"> 13 <a-form-item label="物料长描述">
9 <a-input placeholder="请输入物料长描述" v-model="queryParam.materialDescription"></a-input> 14 <a-input placeholder="请输入物料长描述" v-model="queryParam.materialDescription"></a-input>
10 </a-form-item> 15 </a-form-item>
11 </a-col> 16 </a-col>
12 <a-col :xl="6" :lg="7" :md="8" :sm="24"> 17 <a-col :xl="6" :lg="7" :md="8" :sm="24">
  18 + <a-form-item label="品牌">
  19 + <a-input placeholder="请输入品牌" v-model="queryParam.brand"></a-input>
  20 + </a-form-item>
  21 + </a-col>
  22 + <a-col :xl="6" :lg="7" :md="8" :sm="24">
13 <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons"> 23 <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
14 <a-button type="primary" @click="searchQuery" icon="search">查询</a-button> 24 <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
15 <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button> 25 <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
@@ -5,18 +5,26 @@ @@ -5,18 +5,26 @@
5 <a-form layout="inline" @keyup.enter.native="searchQuery"> 5 <a-form layout="inline" @keyup.enter.native="searchQuery">
6 <a-row :gutter="24"> 6 <a-row :gutter="24">
7 <a-col :xl="6" :lg="7" :md="8" :sm="24"> 7 <a-col :xl="6" :lg="7" :md="8" :sm="24">
  8 + <a-form-item label="物料编码">
  9 + <a-input placeholder="请输入物料编码" v-model="queryParam.meterialCode"></a-input>
  10 + </a-form-item>
  11 + </a-col>
  12 +
  13 + <a-col :xl="6" :lg="7" :md="8" :sm="24">
8 <a-form-item label="物料长描述"> 14 <a-form-item label="物料长描述">
9 <a-input placeholder="请输入物料长描述" v-model="queryParam.meterialReview"></a-input> 15 <a-input placeholder="请输入物料长描述" v-model="queryParam.meterialReview"></a-input>
10 </a-form-item> 16 </a-form-item>
11 </a-col> 17 </a-col>
  18 +
  19 + <a-col :xl="6" :lg="7" :md="8" :sm="24">
  20 + <a-form-item label="品牌">
  21 + <a-input placeholder="请输入品牌" v-model="queryParam.brand"></a-input>
  22 + </a-form-item>
  23 + </a-col>
12 <a-col :xl="6" :lg="7" :md="8" :sm="24"> 24 <a-col :xl="6" :lg="7" :md="8" :sm="24">
13 <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons"> 25 <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
14 <a-button type="primary" @click="searchQuery" icon="search">查询</a-button> 26 <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
15 <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button> 27 <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
16 - <a @click="handleToggleSearch" style="margin-left: 8px">  
17 - {{ toggleSearchStatus ? '收起' : '展开' }}  
18 - <a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>  
19 - </a>  
20 </span> 28 </span>
21 </a-col> 29 </a-col>
22 </a-row> 30 </a-row>
@@ -27,19 +35,11 @@ @@ -27,19 +35,11 @@
27 <!-- 操作按钮区域 --> 35 <!-- 操作按钮区域 -->
28 <div class="table-operator"> 36 <div class="table-operator">
29 <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button> 37 <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
30 - <!-- <a-button type="primary" icon="download" @click="handleExportXls('贸易管理物料表')">导出</a-button>  
31 - <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">  
32 - <a-button type="primary" icon="import">导入</a-button>  
33 - </a-upload> --> 38 +
34 </div> 39 </div>
35 40
36 <!-- table区域-begin --> 41 <!-- table区域-begin -->
37 <div> 42 <div>
38 - <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">  
39 - <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项  
40 - <a style="margin-left: 24px" @click="onClearSelected">清空</a>  
41 - </div>  
42 -  
43 <a-table 43 <a-table
44 ref="table" 44 ref="table"
45 size="middle" 45 size="middle"
@@ -63,7 +63,8 @@ @@ -63,7 +63,8 @@
63 <template slot="fileSlot" slot-scope="text"> 63 <template slot="fileSlot" slot-scope="text">
64 <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span> 64 <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
65 <div v-else> 65 <div v-else>
66 - {{text}} 66 +<!-- {{text}}-->
  67 + <span :title="text">{{ text.length > 20 ? text.substring(0, 20) + '...' : text }}</span>
67 <a-button 68 <a-button
68 :ghost="true" 69 :ghost="true"
69 type="primary" 70 type="primary"
@@ -107,6 +108,7 @@ @@ -107,6 +108,7 @@
107 import { mixinDevice } from '@/utils/mixin' 108 import { mixinDevice } from '@/utils/mixin'
108 import { JeecgListMixin } from '@/mixins/JeecgListMixin' 109 import { JeecgListMixin } from '@/mixins/JeecgListMixin'
109 import TblTradeMeterialModal from './modules/TblTradeMeterialModal' 110 import TblTradeMeterialModal from './modules/TblTradeMeterialModal'
  111 + import { getFileAccessHttpUrl } from '@api/manage'
110 112
111 export default { 113 export default {
112 name: 'TblTradeMeterialList', 114 name: 'TblTradeMeterialList',
@@ -156,12 +158,9 @@ @@ -156,12 +158,9 @@
156 scopedSlots: {customRender: 'fileSlot'} 158 scopedSlots: {customRender: 'fileSlot'}
157 }, 159 },
158 { 160 {
159 - title:'日期时间', 161 + title:'型号变更说明上传时间',
160 align:"center", 162 align:"center",
161 dataIndex: 'modelChangeDate', 163 dataIndex: 'modelChangeDate',
162 - customRender:function (text) {  
163 - return !text?"":(text.length>10?text.substr(0,10):text)  
164 - }  
165 }, 164 },
166 { 165 {
167 title:'合格证', 166 title:'合格证',
@@ -170,12 +169,9 @@ @@ -170,12 +169,9 @@
170 scopedSlots: {customRender: 'fileSlot'} 169 scopedSlots: {customRender: 'fileSlot'}
171 }, 170 },
172 { 171 {
173 - title:'日期时间', 172 + title:'合格证上传时间',
174 align:"center", 173 align:"center",
175 dataIndex: 'certDate', 174 dataIndex: 'certDate',
176 - customRender:function (text) {  
177 - return !text?"":(text.length>10?text.substr(0,10):text)  
178 - }  
179 }, 175 },
180 { 176 {
181 title:'其他', 177 title:'其他',
@@ -184,12 +180,9 @@ @@ -184,12 +180,9 @@
184 scopedSlots: {customRender: 'fileSlot'} 180 scopedSlots: {customRender: 'fileSlot'}
185 }, 181 },
186 { 182 {
187 - title:'日期时间', 183 + title:'其他文件上传时间',
188 align:"center", 184 align:"center",
189 dataIndex: 'otherDate', 185 dataIndex: 'otherDate',
190 - customRender:function (text) {  
191 - return !text?"":(text.length>10?text.substr(0,10):text)  
192 - }  
193 }, 186 },
194 { 187 {
195 title: '操作', 188 title: '操作',
@@ -221,6 +214,65 @@ @@ -221,6 +214,65 @@
221 }, 214 },
222 }, 215 },
223 methods: { 216 methods: {
  217 + downloadFile(text) {
  218 + if (!text) {
  219 + this.$message.warning("未知的文件");
  220 + return;
  221 + }
  222 +
  223 + // 将 text 按逗号分割成多个文件的 URL
  224 + const fileUrls = text.split(",");
  225 +
  226 + // 遍历每个文件的 URL
  227 + fileUrls.forEach((fileUrl, index) => {
  228 + // 去除 URL 两端的空格
  229 + fileUrl = fileUrl.trim();
  230 +
  231 + // 检查 URL 是否有效
  232 + if (!fileUrl) {
  233 + this.$message.warning(`第 ${index + 1} 个文件 URL 无效`);
  234 + return; // 跳过当前文件,继续下一个
  235 + }
  236 +
  237 + // 生成文件访问 URL
  238 + let url = getFileAccessHttpUrl(fileUrl);
  239 +
  240 + // 检查生成的 URL 是否有效
  241 + if (!url) {
  242 + this.$message.warning(`第 ${index + 1} 个文件无法生成访问链接`);
  243 + return; // 跳过当前文件,继续下一个
  244 + }
  245 +
  246 + // 使用 fetch 下载文件
  247 + fetch(url)
  248 + .then(response => {
  249 + if (!response.ok) {
  250 + throw new Error(`第 ${index + 1} 个文件下载失败`);
  251 + }
  252 + return response.blob(); // 将响应转换为 Blob 对象
  253 + })
  254 + .then(blob => {
  255 + // 创建 Blob URL
  256 + const blobUrl = URL.createObjectURL(blob);
  257 +
  258 + // 创建 <a> 标签并触发下载
  259 + const link = document.createElement("a");
  260 + link.href = blobUrl;
  261 + link.download = fileUrl; // 替换为实际文件名
  262 + link.style.display = "none";
  263 + document.body.appendChild(link);
  264 + link.click();
  265 + document.body.removeChild(link);
  266 +
  267 + // 释放 Blob URL
  268 + URL.revokeObjectURL(blobUrl);
  269 + })
  270 + .catch(error => {
  271 + this.$message.error(`第 ${index + 1} 个文件下载失败`);
  272 + console.error(`下载错误:`, error);
  273 + });
  274 + });
  275 + },
224 initDictConfig(){ 276 initDictConfig(){
225 }, 277 },
226 getSuperFieldList(){ 278 getSuperFieldList(){
@@ -90,10 +90,18 @@ @@ -90,10 +90,18 @@
90 }, 90 },
91 confirmLoading: false, 91 confirmLoading: false,
92 validatorRules: { 92 validatorRules: {
93 - meterialCode: [  
94 - { required: false},  
95 - { validator: (rule, value, callback) => validateDuplicateValue('tbl_trade_meterial', 'meterial_code', value, this.model.id, callback)},  
96 - ], 93 + // meterialCode: [
  94 + // { required: false},
  95 + // { validator: (rule, value, callback) => validateDuplicateValue('tbl_trade_meterial', 'meterial_code', value, this.model.id, callback)},
  96 + // ],
  97 +
  98 + meterialCode: [{ required: true, message: '请输入物料编码!' }],
  99 + meterialReview: [{ required: true, message: '请输入物料长描述!' }],
  100 + unit: [{ required: true, message: '请输入单位!' }],
  101 + brand: [{ required: true, message: '请输入品牌!' }],
  102 + // modelChange: [{ required: true, message: '请输入型号变更说明!' }],
  103 + // cert: [{ required: true, message: '请输入合格证!' }],
  104 + // other: [{ required: true, message: '请输入物料编码!' }],
97 }, 105 },
98 url: { 106 url: {
99 add: "/trade/tblTradeMeterial/add", 107 add: "/trade/tblTradeMeterial/add",