update upload&download

This commit is contained in:
lb 2023-02-10 16:57:29 +08:00
parent 660803f34a
commit 39bf107fbe
5 changed files with 157 additions and 95 deletions

View File

@ -51,9 +51,10 @@
v-if="col.upload" v-if="col.upload"
:key="'upload_' + Math.random()" :key="'upload_' + Math.random()"
:action="col.actionUrl" :action="col.actionUrl"
:file-list="col.fileList" :file-list="dataForm['files']"
:disabled="detailMode || !dataForm.id" :disabled="detailMode || !dataForm.id"
v-bind="col.elparams" v-bind="col.elparams"
@update-file-list="handleFilelistUpdate"
/> />
<quillEditor <quillEditor
@ -142,21 +143,14 @@ export default {
inject: ["urls"], inject: ["urls"],
data() { data() {
const dataForm = {}; const dataForm = {};
const uploadComponentsList = []; //
this.configs.form.rows.forEach((row) => { this.configs.form.rows.forEach((row) => {
row.forEach((col) => { row.forEach((col) => {
// if (col.upload) dataForm[col.prop] = col.default ?? [];
// else dataForm[col.prop] = col.default ?? null;
dataForm[col.prop] = col.default ?? null; dataForm[col.prop] = col.default ?? null;
if (col.upload) {
uploadComponentsList.push(col);
}
if (col.fetchData) if (col.fetchData)
col.fetchData().then(({ data: res }) => { col.fetchData().then(({ data: res }) => {
console.log("[Fetch Data]", res.data.list); console.log("[DialogJustForm fetchData -->]", res.data.list);
if (res.code === 0 && res.data.list) { if (res.code === 0 && res.data.list) {
this.$set( this.$set(
col, col,
@ -172,7 +166,7 @@ export default {
else if (col.fetchTreeData) { else if (col.fetchTreeData) {
// parentId 0 // parentId 0
col.fetchTreeData().then(({ data: res }) => { col.fetchTreeData().then(({ data: res }) => {
console.log("[Fetch Tree Data]", res.data.list); console.log("[DialogJustForm fetchTreeData -->]", res.data.list);
if (res.code === 0 && res.data.list) { if (res.code === 0 && res.data.list) {
// //
const obj = {}; const obj = {};
@ -181,7 +175,6 @@ export default {
}); });
// //
let filteredList = reConstructTreeData(obj); let filteredList = reConstructTreeData(obj);
console.log("** filteredList **", filteredList);
// options // options
this.$set(col, "options", filteredList); this.$set(col, "options", filteredList);
} else { } else {
@ -195,7 +188,6 @@ export default {
loadingStatus: false, loadingStatus: false,
dataForm, dataForm,
detailMode: false, detailMode: false,
uploadComponentsList,
baseDialogConfig: null, baseDialogConfig: null,
defaultQuillConfig: { defaultQuillConfig: {
modules: { modules: {
@ -233,15 +225,14 @@ export default {
}, },
}, },
methods: { methods: {
handleUploadSuccess(response, file, fileList) { handleFilelistUpdate(newFilelist) {
/** 上传成功修改本地展示的文件名 */ // TODO: 访 .files
if (response.code === 0) { this.dataForm.files = newFilelist.map((file) => ({
// const { fileName } = response.data[0]; id: file.id,
const fileName = response.data[0].fileUrl.split("/").pop(); name: file.name,
file.name = fileName; url: file.url,
} else { typeCode: file.typeCode
console.log("response, file, fileList", response, file, fileList); }));
}
}, },
/** utitilities */ /** utitilities */
@ -257,12 +248,11 @@ export default {
resetForm(excludeId = false, immediate = false) { resetForm(excludeId = false, immediate = false) {
setTimeout( setTimeout(
() => { () => {
console.log("[Dialog Just Form] clearing form...");
Object.keys(this.dataForm).forEach((key) => { Object.keys(this.dataForm).forEach((key) => {
if (excludeId && key === "id") return; if (excludeId && key === "id") return;
this.dataForm[key] = null; this.dataForm[key] = null;
}); });
console.log("[Dialog Just Form] cleared form...", this.dataForm); console.log("[DialogJustForm resetForm()] clearing form...");
this.$refs.dataForm.clearValidate(); this.$refs.dataForm.clearValidate();
this.$emit("dialog-closed"); // this.$emit("dialog-closed"); //
}, },
@ -273,13 +263,11 @@ export default {
/** init **/ /** init **/
init(id, detailMode) { init(id, detailMode) {
if (this.$refs.dataForm) { if (this.$refs.dataForm) {
console.log("[dialog REUSE] clearing form validation..."); console.log("[DialogJustForm] clearing form validation...");
// dialog dataForm [0] // dialog dataForm [0]
this.$refs.dataForm.clearValidate(); this.$refs.dataForm.clearValidate();
} }
console.log("[Dialog Just Form] init():", id, detailMode);
this.detailMode = detailMode ?? false; this.detailMode = detailMode ?? false;
this.$nextTick(() => { this.$nextTick(() => {
this.dataForm.id = id || null; this.dataForm.id = id || null;
@ -290,30 +278,35 @@ export default {
// //
this.$http.get(this.urls.base + `/${this.dataForm.id}`).then(({ data: res }) => { this.$http.get(this.urls.base + `/${this.dataForm.id}`).then(({ data: res }) => {
if (res && res.code === 0) { if (res && res.code === 0) {
const dataFormKeys = Object.keys(this.dataForm); this.dataForm = __pick(res.data, Object.keys(this.dataForm));
console.log("keys ===> ", dataFormKeys); /** 格式化文件上传列表 */
if (Array.isArray(this.dataForm.files)) {
// console.log('data form keys: ', dataFormKeys, pick(res.data, dataFormKeys)) this.dataForm.files = this.dataForm.files.map((file) => ({
this.dataForm = __pick(res.data, dataFormKeys); id: file.id,
console.log("pick(res.data, dataFormKeys) ===> ", __pick(res.data, dataFormKeys)); name: file.fileUrl.split("/").pop(),
typeCode: file.typeCode,
url: file.fileUrl,
}));
}
console.log("[DialogJustForm] init():", __pick(res.data, Object.keys(this.dataForm)));
} }
this.loadingStatus = false; this.loadingStatus = false;
}); });
// // //
this.uploadComponentsList.forEach((col) => { // this.uploadComponentsList.forEach((col) => {
this.$http // this.$http
.get(col.fetchUrl, { // .get(col.fetchUrl, {
params: { // params: {
limit: 999, // limit: 999,
page: 1, // page: 1,
[col.paramName]: this.dataForm.id, // [col.paramName]: this.dataForm.id,
}, // },
}) // })
.then(({ data: res }) => { // .then(({ data: res }) => {
console.log("fetch filelist:", res); // console.log("fetch filelist:", res);
}); // });
}); // });
} else { } else {
// //
} }
@ -356,13 +349,23 @@ export default {
this.$refs.dataForm.validate((passed, result) => { this.$refs.dataForm.validate((passed, result) => {
if (passed) { if (passed) {
//
this.loadingStatus = true; this.loadingStatus = true;
const method = payload.name === "add" ? "POST" : "PUT"; const method = payload.name === "add" ? "POST" : "PUT";
let httpPayload = null;
/** 针对有文件上传选项的弹窗提供特殊的 payload */
if (this.dataForm.files) {
httpPayload = {
...this.dataForm,
fileIds: this.dataForm.files.map((file) => file.id),
};
} else {
httpPayload = this.dataForm;
}
/** 发送 */
this.$http({ this.$http({
url: this.urls.base, url: this.urls.base,
method, method,
data: this.dataForm, data: httpPayload,
}) })
.then(({ data: res }) => { .then(({ data: res }) => {
console.log("[add&update] res is: ", res); console.log("[add&update] res is: ", res);

View File

@ -7,8 +7,8 @@
{{ file.name }} {{ file.name }}
</span> </span>
<div class="h-4 space-x-2"> <div class="h-4 space-x-2">
<button class="el-icon-download text-blue-300" @click="handleDownload(file)"></button> <button class="el-icon-download color-blue" @click="handleDownload(file)" title="点击下载"></button>
<button class="el-icon-delete text-red-300" @click="handleDelete(file)"></button> <button class="el-icon-delete color-red" @click="handleDelete(file)" title="点击删除"></button>
</div> </div>
</li> </li>
<li v-if="filteredList.length === 0"></li> <li v-if="filteredList.length === 0"></li>
@ -31,7 +31,7 @@
<!-- </div> --> <!-- </div> -->
<div v-if="label" slot="reference" class="">{{ label }}</div> <div v-if="label" slot="reference" class="">{{ label }}</div>
<div v-else slot="reference" class="el-icon-folder-opened" style="margin-left: 24px; cursor: pointer;"> 已上传文件</div> <div v-else slot="reference" class="el-icon-folder-opened" style="margin-left: 24px; cursor: pointer">已上传文件</div>
</el-popover> </el-popover>
</template> </template>
@ -58,6 +58,13 @@ export default {
searchCondition: "", searchCondition: "",
}; };
}, },
watch: {
fileList(val) {
if (val) {
console.log("[FileList] fileList prop:", val);
}
},
},
computed: { computed: {
filteredList() { filteredList() {
return this.fileList.filter((item) => item.name.startsWith(this.searchCondition)); return this.fileList.filter((item) => item.name.startsWith(this.searchCondition));
@ -65,10 +72,35 @@ export default {
}, },
methods: { methods: {
handleDownload(file) { handleDownload(file) {
console.log("handleDownload", file); console.log("[FileList] handleDownload", file);
this.$http
.get("/pms/attachment/downloadFile", {
params: {
attachmentId: file.id,
type: 1,
},
})
.then(({ data: res }) => {
const blob = new Blob([res]);
if ("download" in document.createElement("a")) {
const alink = document.createElement("a");
alink.download = file.name;
alink.style.display = "none";
alink.target = "_blank";
alink.href = URL.createObjectURL(blob);
document.body.appendChild(alink);
alink.click();
URL.revokeObjectURL(alink.href);
document.body.removeChild(alink);
} else {
navigator.msSaveBlob(blob, fileName);
}
});
}, },
handleDelete(file) { handleDelete(file) {
console.log("handleDelete", file); console.log("[FileList] handleDelete", file);
// TODO:
this.$emit("delete-a-file", file.id);
}, },
handleSearchClick() { handleSearchClick() {
console.log("[FileList] handleSearchClick()"); console.log("[FileList] handleSearchClick()");
@ -126,4 +158,27 @@ li {
width: 24px; width: 24px;
height: 24px; height: 24px;
} }
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
width: 8px;
}
::-webkit-scrollbar-button {
display: none;
}
::-webkit-scrollbar-thumb {
background: rgb(175, 175, 175);
border-radius: 4px;
}
.color-blue {
color: #0b58ff;
cursor: pointer;
}
.color-red {
color: rgba(222, 15, 15, 0.89);
cursor: pointer;
}
</style> </style>

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="" style="position: relative;"> <div class="" style="position: relative">
<el-upload <el-upload
:disabled="disabled" :disabled="disabled"
name="files" name="files"
@ -18,10 +18,8 @@
<span key="uploaded" v-else class="success-msg"> {{ tips.success }} </span> <span key="uploaded" v-else class="success-msg"> {{ tips.success }} </span>
</transition> </transition>
</div> </div>
</el-upload> </el-upload>
<FileList :file-list="fileList" style="display: inline-block; position: absolute; top: 0; left: 72px;" /> <FileList :file-list="uploadedFileList" @delete-a-file="handleRemoveFile" style="display: inline-block; position: absolute; top: 0; left: 72px" />
</div> </div>
</template> </template>
@ -47,7 +45,7 @@ export default {
type: String, type: String,
default: "http://192.168.1.62:8080/pms-am/pms/attachment/uploadFileFormData?typeCode=equipmentType", // default: "http://192.168.1.62:8080/pms-am/pms/attachment/uploadFileFormData?typeCode=equipmentType", //
}, },
fileListProp: { fileList: {
type: Array, type: Array,
default: () => [], default: () => [],
}, },
@ -58,7 +56,17 @@ export default {
}, },
components: { FileList }, components: { FileList },
data() { data() {
return { showMsg: false, fileList: [] }; return { showMsg: false, uploadedFileList: [] };
},
watch: {
// fileList: {
// handler: (arr) => {
// if (arr && arr.length > 0) {
// this.uploadedFileList = arr;
// }
// },
// immediate: true,
// },
}, },
computed: { computed: {
uploadHeaders() { uploadHeaders() {
@ -67,28 +75,34 @@ export default {
}; };
}, },
}, },
watch: { mounted() {
fileListProp(list) { console.log("[UploadBtn] mounted()", this.fileList, this.uploadedFileList);
this.fileList = list; this.uploadedFileList = this.fileList ?? [];
},
}, },
methods: { methods: {
handleRemoveFile(fileId) {
this.uploadedFileList = this.uploadedFileList.filter((file) => file.id.toString() !== fileId.toString());
this.$emit("update-file-list", this.uploadedFileList);
},
handleUploadSuccess(response, file, fileList) { handleUploadSuccess(response, file, fileList) {
/** 上传成功修改本地展示的文件名 */ console.log("[UploadBtn] uploadedFileList", response, file, fileList, this.uploadedFileList);
if (response.code === 0) { if (response.code === 0) {
// const { fileName } = response.data[0]; const uploadedFile = response.data[0];
const fileName = response.data[0].fileUrl.split("/").pop(); const fileItem = {
file.name = fileName; id: uploadedFile.id,
name: uploadedFile.fileUrl.split("/").pop(),
url: uploadedFile.fileUrl,
typeCode: file.typeCode,
};
this.uploadedFileList.push(fileItem);
this.$emit("update-file-list", this.uploadedFileList);
this.showMsg = true; this.showMsg = true;
setTimeout(() => { setTimeout(() => {
this.showMsg = false; this.showMsg = false;
}, 3000); }, 3000);
} else {
console.log("response, file, fileList", response, file, fileList);
} }
this.fileList = fileList;
console.log("[vue] fileList", this.fileList);
}, },
}, },
}; };
@ -114,19 +128,6 @@ export default {
transition: opacity 500ms ease-out; transition: opacity 500ms ease-out;
} }
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
width: 8px;
}
::-webkit-scrollbar-button {
display: none;
}
::-webkit-scrollbar-thumb {
background: rgb(175, 175, 175);
border-radius: 4px;
}
.success-msg { .success-msg {
color: #67c23a; color: #67c23a;
} }

View File

@ -98,11 +98,8 @@ export default function () {
[{ [{
upload: true, upload: true,
actionUrl: window.SITE_CONFIG['apiURL'] + '/pms/attachment/uploadFileFormData?typeCode=equipmentType', actionUrl: window.SITE_CONFIG['apiURL'] + '/pms/attachment/uploadFileFormData?typeCode=equipmentType',
fetchUrl: '/pms/equipmentTypeFile/page',
label: "上传资料", label: "上传资料",
fileList: [], prop: "files",
prop: "upload",
paramName: 'equipmentTypeId',
elparams: null elparams: null
}], }],
], ],

View File

@ -13,8 +13,10 @@ export default function () {
{ prop: "type", label: "物料类型" }, { prop: "type", label: "物料类型" },
{ prop: "enName", label: "英文名称" }, { prop: "enName", label: "英文名称" },
{ prop: "enAb", label: "英文缩写" }, { prop: "enAb", label: "英文缩写" },
{ prop: "description", label: "详情", subcomponent: TableTextComponent }, { prop: "density", label: "堆积密度" },
{ prop: "remark", label: "备注" }, // { prop: "description", label: "详情", subcomponent: TableTextComponent },
{ prop: "description", label: "原料描述", },
{ prop: "remark", label: "中文描述" },
/** TODO: parentId 是用来前端重构成树形结构的... */ /** TODO: parentId 是用来前端重构成树形结构的... */
{ {
prop: "operations", prop: "operations",
@ -81,7 +83,8 @@ export default function () {
rules: { required: true, message: "not empty", trigger: "blur" }, rules: { required: true, message: "not empty", trigger: "blur" },
elparams: { placeholder: "请输入物料编码" }, elparams: { placeholder: "请输入物料编码" },
}, },
{ input: true, label: "规格", prop: "specifications", elparams: { placeholder: "规格" } }, { input: true, label: "堆积密度(g/cm3)", prop: "density", elparams: { placeholder: "堆积密度" } },
], ],
[ [
{ {
@ -152,7 +155,10 @@ export default function () {
}, },
], ],
[{ textarea: true, label: "备注", prop: "remark", elparams: { placeholder: "备注" } }], [
{ input: true, label: "原料描述", prop: "description", elparams: { placeholder: "原料描述" } },
],
[{ input: true, label: "中文描述", prop: "remark", elparams: { placeholder: "备注" } }],
], ],
operations: [ operations: [
{ name: "add", label: "保存", type: "primary", permission: "pms:material:save", showOnEdit: false }, { name: "add", label: "保存", type: "primary", permission: "pms:material:save", showOnEdit: false },