提交 7328c1b0 authored 作者: 龙菲's avatar 龙菲

优化展览新增和编辑

上级 c296348f
...@@ -74,6 +74,7 @@ export default { ...@@ -74,6 +74,7 @@ export default {
data() { data() {
return { return {
fileList: [], fileList: [],
removedIds: [], //被删除的文件Id集合
}; };
}, },
watch: { watch: {
...@@ -175,6 +176,11 @@ export default { ...@@ -175,6 +176,11 @@ export default {
// 文件列表移除文件时的钩子 // 文件列表移除文件时的钩子
handleRemove(file, fileList) { handleRemove(file, fileList) {
let that = this; let that = this;
const { status } = file;
if (status == "success") {
this.removedIds.push(file.fileId);
this.$emit("getRemovedIds", this.removedIds);
}
that.fileList.map(async (item, index) => { that.fileList.map(async (item, index) => {
if (item.uid === file.uid) { if (item.uid === file.uid) {
that.fileList.splice(index, 1); that.fileList.splice(index, 1);
......
// 本文件提供一些前端和后端数据交互和转换的一些方法,可批量使用的 // 本文件提供一些前端和后端数据交互和转换的一些方法,可批量使用的
const transformData = { const bizTransform = {
/** /**
* 转换服务器的封面数据到前端可用的封面数据 * 转换服务器的封面数据到前端可用的封面数据
* @param {String} faceImage 封面文件ID * @param {String} faceImage 封面文件ID
...@@ -19,7 +19,7 @@ const transformData = { ...@@ -19,7 +19,7 @@ const transformData = {
fileId: faceImage || "", fileId: faceImage || "",
}, },
]; ];
console.log('result', result); console.log("result", result);
return result; return result;
}, },
...@@ -49,13 +49,10 @@ const transformData = { ...@@ -49,13 +49,10 @@ const transformData = {
* @returns {String} 提交给服务器需要的以逗号隔开的字符串 * @returns {String} 提交给服务器需要的以逗号隔开的字符串
*/ */
literatureIdArrToStr(arr) { literatureIdArrToStr(arr) {
let str = "";
if (arr.length == 0) { if (arr.length == 0) {
return ""; return "";
} }
const result = arr.join(","); return arr.join(",");
str = result.substring(0, result.length - 1);
return str;
}, },
/** /**
...@@ -125,14 +122,15 @@ const transformData = { ...@@ -125,14 +122,15 @@ const transformData = {
* @returns {String} 部门ID字符串 * @returns {String} 部门ID字符串
*/ */
getDeptIdStr(deptArr) { getDeptIdStr(deptArr) {
let str = ""; if (deptArr instanceof Array) {
if (deptArr.length == 0) { if (deptArr.length == 0) {
return ""; return "";
}
return deptArr.join(",");
} else {
return deptArr;
} }
const result = deptArr.join(",");
str = result.substring(0, result.length - 1);
return str;
}, },
}; };
export default transformData; export default bizTransform;
...@@ -306,8 +306,8 @@ import { addOrUpdateCulturalRelic } from "@/api/culturalRelic"; ...@@ -306,8 +306,8 @@ import { addOrUpdateCulturalRelic } from "@/api/culturalRelic";
import { mapGetters, mapActions } from "vuex"; import { mapGetters, mapActions } from "vuex";
import { uploadV1 } from "@/utils/file"; import { uploadV1 } from "@/utils/file";
import { rules } from "../configs/validateRules"; import { rules } from "../configs/validateRules";
import fileUploadFunctions from "@/utils/fileUploadFuctions"; import fileUploadFunctions from "@/utils/bizUploadFunctions";
import transformData from "@/utils/transformData"; import transformData from "@/utils/bizTransform";
const { const {
faceImageToClient, faceImageToClient,
literatureIdArrToStr, literatureIdArrToStr,
...@@ -667,3 +667,4 @@ export default { ...@@ -667,3 +667,4 @@ export default {
margin: 20px 0; margin: 20px 0;
} }
</style> </style>
@/utils/bizTransform@/utils/bizUploadFunctions
\ No newline at end of file
...@@ -7,27 +7,45 @@ ...@@ -7,27 +7,45 @@
<div class="exhibition-units-tree-node" slot-scope="{ node, data }"> <div class="exhibition-units-tree-node" slot-scope="{ node, data }">
<div style="display: flex; align-items: center"> <div style="display: flex; align-items: center">
<div class="title" @click="handleClickNode(node, data)"> <div class="title" @click="handleClickNode(node, data)">
<el-input placeholder="请输入标题" v-model="data.title" v-if="data.isEditing" :ref="data.euId + 'Title'" <el-input
@blur="() => handleInputBlur(node, data)"> placeholder="请输入标题"
v-model="data.title"
v-if="data.isEditing"
:ref="data.euId + 'Title'"
@blur="() => handleInputBlur(node, data)"
>
</el-input> </el-input>
<span v-else>{{ data.title }}</span> <span v-else>{{ data.title }}</span>
</div> </div>
<span v-if="!isDisableEvent"> <span v-if="!isDisableEvent">
<el-tooltip content="编辑标题" placement="top"> <el-tooltip content="编辑标题" placement="top">
<i v-if="!data.isEditing" class="el-icon-edit plus-peer" @click="() => editNode(node, data)"></i> <i
v-if="!data.isEditing"
class="el-icon-edit plus-peer"
@click="() => editNode(node, data)"
></i>
</el-tooltip> </el-tooltip>
<el-tooltip content="添加子节点" placement="top"> <el-tooltip content="添加子节点" placement="top">
<svg-icon @click="() => appendChild(data)" icon-class="node-child2" class="plus-child" <svg-icon
style="font-size: 32px; color: #409eff"></svg-icon> @click="() => appendChild(data)"
icon-class="node-child2"
class="plus-child"
style="font-size: 32px; color: #409eff"
></svg-icon>
</el-tooltip> </el-tooltip>
<el-tooltip content="添加同级节点" placement="top"> <el-tooltip content="添加同级节点" placement="top">
<i class="el-icon-plus plus-peer" @click="() => appendPeerNode(node, data)"></i> <i
class="el-icon-plus plus-peer"
@click="() => appendPeerNode(node, data)"
></i>
</el-tooltip> </el-tooltip>
<el-tooltip content="删除当前节点" placement="top"> <el-tooltip content="删除当前节点" placement="top">
<i class="el-icon-close delete" @click="() => remove(node, data)"></i> <i
class="el-icon-close delete"
@click="() => remove(node, data)"
></i>
</el-tooltip> </el-tooltip>
</span> </span>
</div> </div>
</div> </div>
</el-tree> </el-tree>
...@@ -39,23 +57,48 @@ ...@@ -39,23 +57,48 @@
</el-input> </el-input>
</el-col> </el-col>
<el-col :span="24" class="mg-bt20"> <el-col :span="24" class="mg-bt20">
<VueQuillEditor v-model="currentData.intro" placeholder="请输入单元介绍" /> <VueQuillEditor
v-model="currentData.intro"
placeholder="请输入单元介绍"
/>
</el-col> </el-col>
<el-col :span="24" class="mg-bt20"> <el-col :span="24" class="mg-bt20">
<div>单元文物:</div> <div>单元文物:</div>
<el-select :disabled="isDisableEvent" v-model="currentData.crIds" multiple filterable remote reserve-keyword <el-select
:placeholder="isDisableEvent ? '无' : '请输入关键词搜索文物'" :remote-method="searchCR" :loading="loading" :disabled="isDisableEvent"
style="width: 100%" ref="remoteSelect"> v-model="currentData.crIds"
<el-option v-for="item in crList" :key="item.crId" :label="item.name" :value="item.crId"> multiple
filterable
remote
reserve-keyword
:placeholder="isDisableEvent ? '无' : '请输入关键词搜索文物'"
:remote-method="searchCR"
:loading="loading"
style="width: 100%"
ref="remoteSelect"
>
<el-option
v-for="item in crList"
:key="item.crId"
:label="item.name"
:value="item.crId"
>
</el-option> </el-option>
</el-select> </el-select>
</el-col> </el-col>
<el-col :span="24"> <el-col :span="24">
<div>单元图片:</div> <div>单元图片:</div>
<span></span> <span></span>
<ManualUploaderBind v-model="currentData.imagesVo" :fileLimit="7" :fileSize="50" <ManualUploaderBind
:fileType="['jpeg', 'jpg', 'png']" listType="picture-card" :ref="'unit-images-' + currentData.euId" v-model="currentData.imagesVo"
:onlyRead="isDisableEvent" /> :fileLimit="7"
:fileSize="50"
:fileType="['jpeg', 'jpg', 'png']"
listType="picture-card"
:ref="'unit-images-' + currentData.euId"
:onlyRead="isDisableEvent"
@getRemovedIds="getRemovedIds"
/>
</el-col> </el-col>
</el-row> </el-row>
<!-- <el-collapse-transition> <!-- <el-collapse-transition>
...@@ -64,14 +107,32 @@ ...@@ -64,14 +107,32 @@
</el-row> </el-row>
</el-collapse-transition> --> </el-collapse-transition> -->
<div class="next-prev"> <div class="next-prev">
<el-button size="mini" type="primary" icon="el-icon-back" @click="handleToUnit('prev')">上一节点</el-button> <el-button
<el-button size="mini" type="primary" icon="el-icon-right" @click="handleToUnit('next')">下一节点</el-button> size="mini"
type="primary"
icon="el-icon-back"
@click="handleToUnit('prev')"
>上一节点</el-button
>
<el-button
size="mini"
type="primary"
icon="el-icon-right"
@click="handleToUnit('next')"
>下一节点</el-button
>
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
<el-button v-if="(!treeData.length > 0 && !isDisableEvent)" type="primary" icon="el-icon-circle-plus-outline" <el-button
@click="handleAddUnit('manual')" size="mini">手动添加展览单元</el-button> v-if="!treeData.length > 0 && !isDisableEvent"
<span v-if="(treeData.length == 0 && isDisableEvent)">暂无</span> type="primary"
icon="el-icon-circle-plus-outline"
@click="handleAddUnit('manual')"
size="mini"
>手动添加展览单元</el-button
>
<span v-if="treeData.length == 0 && isDisableEvent">暂无</span>
<!-- <el-button <!-- <el-button
v-if="!treeData.length > 0" v-if="!treeData.length > 0"
type="success" type="success"
...@@ -111,8 +172,8 @@ export default { ...@@ -111,8 +172,8 @@ export default {
}, },
isDisableEvent: { isDisableEvent: {
type: Boolean, type: Boolean,
default: false default: false,
} },
}, },
watch: { watch: {
exhibitionUnits: { exhibitionUnits: {
...@@ -194,7 +255,9 @@ export default { ...@@ -194,7 +255,9 @@ export default {
handleClickNode(node, data) { handleClickNode(node, data) {
this.currentData = data; this.currentData = data;
this.crList = [...new Set([...this.crList, ...this.currentData.culturalRelics])]; this.crList = [
...new Set([...this.crList, ...this.currentData.culturalRelics]),
];
}, },
editNode(node, data) { editNode(node, data) {
this.$set(data, "isEditing", true); this.$set(data, "isEditing", true);
...@@ -280,12 +343,10 @@ export default { ...@@ -280,12 +343,10 @@ export default {
} }
}, },
handleToUnit(type) { handleToUnit(type) {
// debugger
const { euId } = this.currentData; const { euId } = this.currentData;
let next = {}; let next = {};
let prev = {}; let prev = {};
let that = this; let that = this;
// debugger
traverseTree(this.treeData); traverseTree(this.treeData);
function traverseTree(arr) { function traverseTree(arr) {
if (arr && arr.length > 0) { if (arr && arr.length > 0) {
...@@ -320,6 +381,10 @@ export default { ...@@ -320,6 +381,10 @@ export default {
} }
} }
}, },
getRemovedIds(removedIds) {
this.removedIds = [...new Set([...this.removedIds, ...removedIds])];
console.log("this.removedIds", this.removedIds);
},
}, },
}; };
</script> </script>
...@@ -421,7 +486,7 @@ export default { ...@@ -421,7 +486,7 @@ export default {
} }
::v-deep .images-list { ::v-deep .images-list {
&>div { & > div {
white-space: pre-wrap; white-space: pre-wrap;
} }
} }
...@@ -431,6 +496,3 @@ export default { ...@@ -431,6 +496,3 @@ export default {
justify-content: flex-end; justify-content: flex-end;
} }
</style> </style>
...@@ -372,8 +372,8 @@ import { deleteFiles } from "@/api/file"; ...@@ -372,8 +372,8 @@ import { deleteFiles } from "@/api/file";
import { getVirtualListPer } from "@/api/vitual"; import { getVirtualListPer } from "@/api/vitual";
import { rules } from "../configs/validateRules"; import { rules } from "../configs/validateRules";
import { pageSelectUrl, upLoadAddress } from "../configs/urls"; import { pageSelectUrl, upLoadAddress } from "../configs/urls";
import transformData from "@/utils/transformData"; import transformData from "@/utils/bizTransform";
import fileUploadFunctions from "@/utils/fileUploadFuctions"; import fileUploadFunctions from "@/utils/bizUploadFunctions";
import unitsFunctions from "./units"; import unitsFunctions from "./units";
const { const {
faceImageToClient, faceImageToClient,
...@@ -959,3 +959,4 @@ export default { ...@@ -959,3 +959,4 @@ export default {
right: -8%; right: -8%;
} }
</style> </style>
@/utils/bizTransform@/utils/bizUploadFunctions
\ No newline at end of file
// 单独写上传的处理函数 // 单独写上传的处理函数
import { addOrUpdateDisplayTemp } from "@/api/display";
import fileUploadFuctions from "@/utils/bizUploadFunctions";
import bizTransform from "@/utils/bizTransform";
import { uploadV1 } from "@/utils/file";
const { getNeedUploadFormData, isFileRaw, isFormDataHasData } =
fileUploadFuctions;
const { getDeptIdStr } = bizTransform;
const mediaKeys = ["faceImage", "images", "videos", "audios"];
const getUnitData = ($el) => {
const units = $el.$refs["exhibitionUnits"].getUnitData();
return units;
};
/** /**
* * 添加展览单元的媒体文件至formData
* @param {Boolean} submitFlag 上传的类别,是仅保存还是 * @param {*} $el 当前this对象
* @param {*} $el * @param {FormData} formData 当前this对象
* @returns {Object} form 表单对象
*/ */
const submit = (submitFlag, $el) => { const getFormDataUnits = ($el, formData) => {
// this.loading = true; const units = getUnitData($el);
this.$refs.form.validate(async (valid) => { appendUnitToForm(units, formData);
if (valid) { return formData;
};
params.literature = getLtStrByArr(this.literatureIdArr); //文献
params.status = getStatusNumByBool(this.dialogForm.status); const appendUnitToForm = (arr, formData) => {
params.crIds = that.crIds.join(","); arr.forEach((item) => {
params.bvIds = that.vrIds.join(","); if (item.imagesVo && item.imagesVo.length > 0) {
params.displayCharacter = 1; //传布展 item.imagesVo.forEach((imgFile) => {
params.submitFlag = submitFlag; if (isFileRaw(imgFile)) {
return; const { euId } = item;
addOrUpdateDisplayTemp(params) const { raw } = imgFile;
.then((res) => { formData.append(`unit-images-${euId}`, raw);
if (res.code == 0) { }
setTimeout(() => { });
that.$emit("refresh"); }
that.reload(); if (item.children && item.children.length > 0) {
that.submitLoading = false; appendUnitToForm(item.children, formData);
that.$message.success("提交成功!"); }
that.visible = false; });
}, 1000); };
}
}) /**
.catch((err) => { * 上传文件
that.submitLoading = false; * @param {*} $el 当前this对象
}); * @returns {Object} form 表单对象
*/
const uploadFile = ($el) => {
return new Promise(async (resolve, reject) => {
const formData = getNeedUploadFormData($el, mediaKeys);
const formDataFull = getFormDataUnits($el, formData);
try {
if (isFormDataHasData(formDataFull)) {
const res = await uploadV1(formDataFull);
if (res.code == 0) {
resolve(res);
}
} else {
resolve({});
}
} catch (error) {
reject(error);
}
});
};
const getUnitRemovedIds = ($el) => {
return $el.$refs["exhibitionUnits"].getRemovedIds();
};
const getUnitExsitedObj = ($el, units) => {
const obj = {};
loopUnits(units, obj);
return obj;
function loopUnits(arr, obj) {
arr.forEach((item) => {
if (item.images) {
const { euId } = item;
const key = `unit-images-${euId}`;
const removedIds = getUnitRemovedIds($el);
const imgArr = item.images.split(",");
// 筛选存在在images字符串中,并且没有被删除的id,这些是仍然要保留的
const ids = imgArr.filter((id) => {
return !removedIds.includes(id);
});
obj[key] = ids;
}
if (item.children && item.children.length > 0) {
loopUnits(item.children, obj);
}
});
}
};
const getUploadedIdByKey = (key, res) => {
if (!res.data) {
return [];
}
const items = res.data.filter((item) => {
return item.fileKey == key;
});
if (items.length > 0) {
return items.map((item) => {
return item.fileId;
});
} else {
return [];
}
};
// 获取已经上传了的文件的id集合
const getUnitSuccessObj = ($el, units, res) => {
const obj = {};
loopUnits(units, obj, res);
return obj;
function loopUnits(arr, obj, res) {
arr.forEach((item) => {
// 只有图片长度大于0的才会有新上传的
if (item.imagesVo && item.imagesVo.length) {
// 通过key去查找res中的fileId
const { euId } = item;
const key = `unit-images-${euId}`;
const idsArr = getUploadedIdByKey(key, res);
obj[key] = idsArr;
}
if (item.children && item.children.length > 0) {
loopUnits(item.children, obj, res);
}
});
}
};
const mergeObjects = (objA, objB) => {
let result = {};
// 遍历对象A,复制键值对
for (let key in objA) {
if (objA.hasOwnProperty(key)) {
result[key] = objA[key];
}
}
// 遍历对象B,合并相同的键对应的值
for (let key in objB) {
if (objB.hasOwnProperty(key)) {
if (result.hasOwnProperty(key)) {
if (Array.isArray(result[key])) {
result[key].push(...objB[key]);
} else {
console.log(
`Warning: Key ${key} exists in both objA and objB, but the value is not an array in objA.`
);
} }
} else {
result[key] = objB[key]; // 如果键在result中不存在,就创建一个新的键值对
}
}
}
return result;
};
// 获取最终的布展单元
const getUploadedUnits = ($el, res) => {
const units = getUnitData($el);
const exsitedObj = getUnitExsitedObj($el, units);
const successObj = getUnitSuccessObj($el, units, res);
// 将存在的和新上传的取交集,因为当key重复时,已存在的会被新上传的覆盖,因此需要再和已存在的进行取并集
const mergeObj = mergeObjects(exsitedObj, successObj);
loopUnits(units);
return units;
function loopUnits(arr) {
arr.forEach((item) => {
const { euId } = item;
const key = `unit-images-${euId}`;
if (mergeObj[key]) {
item.images = mergeObj[key].join(",");
}
// 处理关联文物
if (item.crIds && item.crIds instanceof Array) {
item.crIds = item.crIds.join(",");
}
// 删除imagesVo不要传到后台
delete item.imagesVo;
if (item.children && item.length > 0) {
loopUnits(item.children);
}
}); });
} }
export default submit };
\ No newline at end of file
const getFormExsitedObj = ($el) => {
const obj = {};
mediaKeys.forEach((key) => {
// 已存在的不为空再继续
if ($el.dialogForm[key]) {
const removedIds = $el.getRemovedIds();
const arr = $el.dialogForm[key].split(",");
// 筛选存在在媒体字符串中,并且没有被删除的id,这些是仍然要保留的
const ids = arr.filter((id) => {
return !removedIds.includes(id);
});
obj[key] = ids;
}
});
return obj;
};
// 获取已经上传了的文件的id集合
const getFormSuccessObj = ($el, res) => {
const obj = {};
mediaKeys.forEach((key) => {
// 通过key去查找res中的fileId
const idsArr = getUploadedIdByKey(key, res);
obj[key] = idsArr;
});
return obj;
};
const getLtStrByArr = (arr) => {
if (arr.length == 0) {
return "";
}
return arr.join(",");
};
const getStatusNumByBool = (bool) => {
if (!bool instanceof Boolean) {
return;
}
return bool ? 1 : 0;
};
// 获取最终的展览表单
const getUploadedForm = ($el, res, submitFlag) => {
const form = JSON.parse(JSON.stringify($el.dialogForm));
const exsitedObj = getFormExsitedObj($el);
const successObj = getFormSuccessObj($el, res);
// 将存在的和新上传的取交集,因为当key重复时,已存在的会被新上传的覆盖,因此需要再和已存在的进行取并集
const mergeObj = mergeObjects(exsitedObj, successObj);
mediaKeys.forEach((key) => {
if (mergeObj[key] && mergeObj[key].length > 0) {
form[key] = mergeObj[key].join(",");
}
});
form.literature = getLtStrByArr($el.literatureIdArr); //文献
form.status = getStatusNumByBool($el.dialogForm.status);
form.crIds = $el.crIds?.join(",");
form.bvIds = $el.vrIds?.join(",");
form.displayCharacter = 1; //传布展
form.submitFlag = submitFlag;
form.deptId = getDeptIdStr(form.deptId);
return form;
};
/**
*
* @param {Boolean} submitFlag 上传的类别,是仅保存还是
* @param {*} $el 当前this对象
*/
const submit = (submitFlag, $el) => {
// this.loading = true;
$el.$refs.form.validate(async (valid) => {
if (valid) {
const res = await uploadFile($el);
const unitsUploaded = getUploadedUnits($el, res);
const formUploaded = getUploadedForm($el, res, submitFlag);
const params = {
...formUploaded,
exhibitionUnits: unitsUploaded,
};
// console.log("unitsUploaded", unitsUploaded);
// console.log("formUploaded", formUploaded);
addOrUpdateDisplayTemp(params)
.then((res) => {
if (res.code == 0) {
setTimeout(() => {
$el.$emit("refresh");
$el.reload();
$el.submitLoading = false;
$el.$message.success("提交成功!");
$el.visible = false;
// TODO:删除文件
}, 1000);
}
})
.catch((err) => {
$el.submitLoading = false;
});
}
});
};
export default submit;
import fileUploadFuctions from "@/utils/fileUploadFuctions"; import fileUploadFuctions from "@/utils/bizUploadFunctions";
const unitsFunctions = { const unitsFunctions = {
/** /**
* 获取新的布展单元,实装媒体id, * 获取新的布展单元,实装媒体id,
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论