You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

406 lines
13 KiB

3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
  1. <template>
  2. <div class="customer-css">
  3. <!-- 只有附件上传功能 -->
  4. <el-form label-position="top" style="margin-top: -5px;">
  5. <el-row style="margin-top: 10px">
  6. <el-col :span="4">
  7. <el-button class="customer-bun-min" type="primary" @click="handleUpload">Upload</el-button>
  8. </el-col>
  9. </el-row>
  10. <!-- 文件列表表格 -->
  11. <el-table
  12. :height="tableHeight"
  13. :data="fileList"
  14. ref="fileTableRef"
  15. style="width: 100%; margin-top: 10px;">
  16. <el-table-column
  17. prop="fileName"
  18. header-align="center"
  19. align="left"
  20. min-width="200"
  21. label="File">
  22. </el-table-column>
  23. <el-table-column
  24. prop="createdBy"
  25. header-align="center"
  26. align="center"
  27. min-width="100"
  28. label="Upload By">
  29. </el-table-column>
  30. <el-table-column
  31. prop="createDate"
  32. header-align="center"
  33. align="center"
  34. min-width="100"
  35. label="Upload Time">
  36. </el-table-column>
  37. <el-table-column
  38. header-align="center"
  39. align="center"
  40. width="100"
  41. fixed="right"
  42. label="Actions">
  43. <template slot-scope="scope">
  44. <a type="text" size="small" v-if="scope.row.id" @click="handleDownload(scope.row)">View |</a>
  45. <a type="text" size="small" v-if="scope.row.id" @click="deleteFileReal(scope.row)"> delete</a>
  46. <a type="text" size="small" v-else @click="deleteFile(scope.$index)"> delete</a>
  47. </template>
  48. </el-table-column>
  49. </el-table>
  50. </el-form>
  51. <!-- File Upload Dialog -->
  52. <el-dialog title="UpLoad" :visible.sync="ossVisible" v-drag width="400px" append-to-body :close-on-click-modal="false">
  53. <el-form ref="form" class="rq" label-width="80px" label-position="top">
  54. <el-row :gutter="10">
  55. <slot></slot>
  56. <el-col :span="24">
  57. <el-form-item label=" " class="auto">
  58. <el-upload drag :file-list="fileList2"
  59. action="#" ref="upload"
  60. :on-remove="onRemoveFile"
  61. :on-change="onChangeFile"
  62. multiple
  63. :auto-upload="false">
  64. <i class="el-icon-upload"></i>
  65. <div class="el-upload__text">Drag files here, or<em> click to upload</em></div>
  66. </el-upload>
  67. </el-form-item>
  68. </el-col>
  69. <el-col :span="24">
  70. <el-form-item label="Remark" class="auto">
  71. <el-input type="textarea" v-model="ossForm.remark" resize="none" :autosize="{minRows: 3, maxRows: 3}"></el-input>
  72. </el-form-item>
  73. </el-col>
  74. </el-row>
  75. </el-form>
  76. <span slot="footer" class="dialog-footer">
  77. <!-- <el-button type="primary" :loading="uploadLoading" @click="handleUploadFiles">Confirm</el-button> -->
  78. <el-button type="primary" :loading="uploadLoading" @click="submitData">Confirm</el-button>
  79. <el-button @click="ossVisible = false">Close</el-button>
  80. </span>
  81. </el-dialog>
  82. </div>
  83. </template>
  84. <script>
  85. import { removeOssFile } from "../../../api/srm/srmSupplier";
  86. import { downLoadObjectFile } from "../../../api/supplierStock/supplierStockRequest";
  87. import {
  88. ossUploadNoSaveOSSForYJY,
  89. queryOssFilePlus} from "../../../api/oss/oss";
  90. export default {
  91. data() {
  92. return {
  93. height: 200,
  94. tableHeight: 240,
  95. searchData: {
  96. orderRef1: '',
  97. orderRef2: '',
  98. orderRef3: '',
  99. orderReftype: 'part',
  100. height: 240
  101. },
  102. fileList: [],
  103. fileList2: [],
  104. ossVisible: false,
  105. ossForm: {
  106. remark: '',
  107. },
  108. uploadLoading: false,
  109. // staged files selected in upload dialog but not yet persisted
  110. stagedFiles: [],
  111. stagedFileRemark: '',
  112. }
  113. },
  114. mounted() {
  115. this.setTableHeight(this.searchData.height)
  116. },
  117. methods: {
  118. resolveTableHeight (height) {
  119. const value = Number(height)
  120. if (!Number.isFinite(value)) {
  121. return 240
  122. }
  123. return Math.max(Math.floor(value), 180)
  124. },
  125. setTableHeight (height) {
  126. this.tableHeight = this.resolveTableHeight(height)
  127. this.$nextTick(() => {
  128. if (this.$refs.fileTableRef && this.$refs.fileTableRef.doLayout) {
  129. this.$refs.fileTableRef.doLayout()
  130. }
  131. })
  132. },
  133. // 获取基础数据列表S
  134. getBaseList (val, type) {
  135. this.$nextTick(() => {
  136. let strVal = ''
  137. // if (val === 1013) {
  138. // if(type==1) {
  139. // strVal = this.dataForm.partType
  140. // }
  141. // }
  142. this.$refs.baseList.init(val, strVal)
  143. })
  144. },
  145. /* 列表方法的回调 */
  146. getBaseData (val) {
  147. // if (this.tagNo === 1013) {
  148. // if(this.tagNo1==1) {
  149. // this.dataForm.partType = val.Base_id
  150. // this.dataForm.partTypeDesc = val.Base_desc
  151. // }
  152. // }
  153. },
  154. //初始化组件的参数
  155. init(inData) {
  156. //初始化参数
  157. this.searchData = JSON.parse(JSON.stringify(inData));
  158. this.setTableHeight(this.searchData.height)
  159. //刷新表格
  160. this.searchTable();
  161. },
  162. searchTable(){
  163. queryOssFilePlus(this.searchData).then(({data}) => {
  164. //区分请求成功和失败的状况
  165. if (data && data.code == 0) {
  166. this.fileList = data.rows
  167. } else {
  168. this.fileList = [];
  169. }
  170. });
  171. },
  172. // Upload dialog open
  173. handleUpload() {
  174. this.$nextTick(() => {
  175. if (this.$refs.upload) {
  176. this.$refs.upload.clearFiles();
  177. }
  178. })
  179. this.fileList2 = [];
  180. this.ossForm.remark = '';
  181. this.ossVisible = true;
  182. },
  183. onRemoveFile(file, fileList) {
  184. this.fileList2 = fileList;
  185. },
  186. onChangeFile(file, fileList) {
  187. this.fileList2 = fileList;
  188. },
  189. // Stage files on dialog confirm
  190. handleUploadFiles() {
  191. if (this.fileList2.length === 0) {
  192. this.$message.error('Please select file(s)');
  193. return;
  194. }
  195. this.stagedFileRemark = this.ossForm.remark || '';
  196. for (let i = 0; i < this.fileList2.length; i++) {
  197. const f = this.fileList2[i].raw;
  198. this.stagedFiles.push(f);
  199. this.fileList.push({
  200. fileName: f.name,
  201. createdBy: this.$store.state.user.name,
  202. createDate: (this.dayjs ? this.dayjs().format('YYYY-MM-DD HH:mm:ss') : new Date().toISOString()),
  203. _staged: true,
  204. raw: f
  205. });
  206. }
  207. this.fileList2 = [];
  208. this.ossForm.remark = '';
  209. this.ossVisible = false;
  210. this.$message.success('Files staged');
  211. },
  212. // Preview/download
  213. handleDownload(row) {
  214. // 预览文件
  215. let image = ['jpg', 'jpeg', 'png', 'gif', 'bmp'];
  216. let video = ['mp4', 'avi', 'mov', 'wmv', 'flv'];
  217. let office = ['doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx'];
  218. let txt = ['txt'];
  219. let type = '';
  220. let pdf = ['pdf'];
  221. if (image.includes(row.fileType.toLowerCase())) {
  222. type = 'image/' + row.fileType;
  223. downLoadObjectFile(row).then(({ data }) => {
  224. const blob = new Blob([data], { type: type });
  225. const fileURL = URL.createObjectURL(blob);
  226. window.open(fileURL, '_blank');
  227. });
  228. } else if (video.includes(row.fileType.toLowerCase())) {
  229. type = 'video/' + row.fileType;
  230. downLoadObjectFile(row).then(({ data }) => {
  231. const blob = new Blob([data], { type: type });
  232. const fileURL = URL.createObjectURL(blob);
  233. window.open(fileURL, '_blank');
  234. });
  235. } else if (txt.includes(row.fileType.toLowerCase())) {
  236. type = 'text/plain';
  237. downLoadObjectFile(row).then(({ data }) => {
  238. const blob = new Blob([data], { type: type });
  239. const fileURL = URL.createObjectURL(blob);
  240. window.open(fileURL, '_blank');
  241. });
  242. } else if (office.includes(row.fileType.toLowerCase())) {
  243. if (row.fileType.toLowerCase() === 'doc' || row.fileType.toLowerCase() === 'docx') {
  244. type = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
  245. } else if (row.fileType.toLowerCase() === 'ppt' || row.fileType.toLowerCase() === 'pptx') {
  246. type = 'application/vnd.openxmlformats-officedocument.presentationml.presentation';
  247. } else {
  248. type = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
  249. }
  250. downLoadObjectFile(row).then(({ data }) => {
  251. const blob = new Blob([data], { type: 'application/octet-stream;charset=utf-8' });
  252. const fileName = row.fileName;
  253. const linkNode = document.createElement('a');
  254. linkNode.download = fileName;
  255. linkNode.style.display = 'none';
  256. linkNode.href = URL.createObjectURL(blob);
  257. document.body.appendChild(linkNode);
  258. linkNode.click();
  259. URL.revokeObjectURL(linkNode.href);
  260. document.body.removeChild(linkNode);
  261. });
  262. } else if (pdf.includes(row.fileType.toLowerCase())) {
  263. type = 'application/pdf';
  264. downLoadObjectFile(row).then(({ data }) => {
  265. const blob = new Blob([data], { type: type });
  266. const fileURL = URL.createObjectURL(blob);
  267. window.open(fileURL, '_blank');
  268. });
  269. } else {
  270. this.$message({
  271. message: 'Unsupported file type',
  272. type: 'warning'
  273. });
  274. }
  275. },
  276. submitData() {
  277. // 确保 addModelData 存在
  278. if (!this.addModelData) {
  279. this.addModelData = {};
  280. }
  281. // 检查是否有文件
  282. if (this.fileList2.length === 0) {
  283. this.$message.error('请选择文件');
  284. return;
  285. }
  286. this.stagedFileRemark = this.ossForm.remark || '';
  287. this.uploadLoading = true;
  288. // 准备要上传的文件
  289. const stagedFiles = [];
  290. for (let i = 0; i < this.fileList2.length; i++) {
  291. stagedFiles.push(this.fileList2[i].raw);
  292. }
  293. // 立即关闭弹窗
  294. this.ossVisible = false;
  295. this.fileList2 = [];
  296. this.ossForm.remark = '';
  297. // 先上传文件
  298. const uploadStagedFiles = () => {
  299. const formData = new FormData();
  300. for (let i = 0; i < stagedFiles.length; i++) {
  301. formData.append('file', stagedFiles[i]);
  302. }
  303. formData.append('orderRef1', this.searchData.orderRef1);
  304. formData.append('orderRef2', this.searchData.orderRef2 || '');
  305. formData.append('orderRef3', this.searchData.orderRef3);
  306. formData.append('createdBy', this.$store.state.user.name);
  307. formData.append('fileRemark', this.stagedFileRemark || '');
  308. formData.append('orderReftype', 'part');
  309. return ossUploadNoSaveOSSForYJY(formData);
  310. };
  311. uploadStagedFiles()
  312. .then(({ data }) => {
  313. if (data && data.code === 0) {
  314. // 移除临时文件,添加上传成功的文件
  315. this.fileList = this.fileList.filter(f => !f._staged);
  316. for (let i = 0; i < data.rows.length; i++) {
  317. this.fileList.push(data.rows[i]);
  318. }
  319. // 确保 addModelData.fileList 存在后再操作
  320. if (!this.addModelData.fileList) {
  321. this.addModelData.fileList = [];
  322. }
  323. this.addModelData.fileList = this.addModelData.fileList.concat(data.rows);
  324. // 清除暂存数据
  325. this.stagedFiles = [];
  326. this.stagedFileRemark = '';
  327. this.uploadLoading = false;
  328. } else {
  329. this.uploadLoading = false;
  330. this.$message.warning(data.msg || '文件上传失败');
  331. return Promise.reject(new Error(data ? data.msg : '上传失败'));
  332. }
  333. })
  334. .catch(err => {
  335. this.uploadLoading = false;
  336. this.$message.error(err.message || err);
  337. });
  338. },
  339. deleteFileReal(row) {
  340. if (!row || !row.id) return;
  341. this.$confirm('Are you sure you want to delete this file?', 'Delete Confirmation', {
  342. confirmButtonText: 'OK',
  343. cancelButtonText: 'Cancel',
  344. type: 'warning'
  345. }).then(() => {
  346. removeOssFile([row.id]).then(({ data }) => {
  347. if (data && data.code === 0) {
  348. const idx = this.fileList.findIndex(f => f.id === row.id);
  349. if (idx !== -1) this.fileList.splice(idx, 1);
  350. this.$message.success(data.msg || 'File deleted');
  351. } else {
  352. this.$message.warning(data.msg || 'Delete failed');
  353. }
  354. }).catch(err => {
  355. this.$message.error('Delete failed:' + (err.message || err));
  356. });
  357. }).catch(() => { });
  358. },
  359. deleteFile(index) {
  360. const f = this.fileList[index];
  361. if (f && f._staged && f.raw) {
  362. const idx = this.stagedFiles.findIndex(sf => sf.name === f.raw.name && sf.size === f.raw.size);
  363. if (idx !== -1) this.stagedFiles.splice(idx, 1);
  364. }
  365. this.fileList.splice(index, 1);
  366. },
  367. },
  368. }
  369. </script>
  370. <!--当前页面的标签样式-->
  371. <style scoped lang="scss">
  372. .rq .auto /deep/ .el-form-item__content {
  373. height: auto;
  374. line-height: 1.5;
  375. }
  376. </style>