提交 b55ed24e authored 作者: 龙菲's avatar 龙菲

修改批量上传逻辑;审核增加审批意见、增加展览基本详情展示

上级 00636e6f
<template>
<span>
<el-tag v-if="showTag" :type="tagType">{{ dictText }}</el-tag>
<span v-else>{{ dictText }}</span>
</span>
</template>
<script>
import { mapGetters } from "vuex";
export default {
props: {
// 字典名称,必填
name: {
type: String,
default: "",
require: true,
},
// 字典值,必填
dictValue: {
type: String,
default: "",
require: true,
},
// 是否要展示为tag
showTag: {
type: Boolean,
default: false,
},
// 标签类别,非必填
tagType: {
type: String,
default: "primary",
},
},
computed: {
...mapGetters(["dicts"]),
},
data() {
return {
dictText: "", //最终翻译显示的文本
};
},
async created() {
const { name, dictValue } = this;
await this.$store.dispatch("dict/getDictList", [name]);
this.dictText = this.dicts[name][dictValue];
},
};
</script>
<style scoped lang="scss"></style>
......@@ -48,7 +48,6 @@
<template v-else-if="item.prop == 'checkStatus'">
<slot name="checkStatus" :scope="scope.row"></slot>
</template>
<template v-else-if="item.prop == 'years'">
<slot name="years" :scope="scope.row"></slot>
</template>
......
<template>
<!-- 有些富文本可能是白色,需要统一修改 -->
<span v-html="richText" class="rich-text"></span>
</template>
<script>
export default {
props: {
richText: {
type: String,
default: "",
},
},
};
</script>
<style lang="scss">
.rich-text p {
color: #333 !important;
}
</style>
......@@ -41,7 +41,7 @@ export default {
.online_3d_viewer {
width: 100%;
height: 100%;
min-height: 300px;
min-height: 600px;
min-width: 300px;
}
</style>
import DictText from './DictText/index.vue'//字典文字显示
import TextShow from './TextShow/index.vue'//富文本文字显示
export default {
install(Vue) {
//注册全局组件
Vue.component('DictText', DictText)
Vue.component('TextShow', TextShow)
}
}
\ No newline at end of file
// 关于展览的常量
export const THEME_TYPE = {
NORMAL_STYLE: {
value: '1',
......
export const SOURCE_TYPE = {
展览: 'biz_exhibition',
文物: 'biz_cultural_relic'
}
\ No newline at end of file
import Vue from 'vue'
import 'normalize.css/normalize.css' // A modern alternative to CSS resets
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import '@/styles/index.scss' // global css
import App from './App'
import store from './store'
import router from './router'
import '@/icons' // icon
import '@/permission' // permission control
import VideoPlayer from 'vue-video-player'
import 'video.js/dist/video-js.css'
import 'vue-video-player/src/custom-theme.css'
import {
getFullUrl
} from '@/utils/index'
import { file } from '@/utils/file'
import * as echarts from 'echarts';
import Components from '@/components'
Vue.use(VideoPlayer)
Vue.use(Components)
Vue.prototype.$getFullUrl = getFullUrl
Vue.prototype.$echarts = echarts
Vue.prototype.$file = file
Vue.use(ElementUI)
Vue.use(VideoPlayer)
Vue.config.productionTip = false
......
<template>
<el-dialog
:visible="visible"
width="60%"
style="height: 98%"
:before-close="handleClose"
top="5vh"
lock-scroll
>
<div class="title" slot="title">
<div class="divider"></div>
<span class="label">批量上传文件</span>
<span class="tips">
<i class="el-icon-info"></i
>提示:上传过程中请勿关闭此弹窗或刷新页面等操作
</span>
</div>
<el-form
:model="form"
ref="form"
:rules="rules"
size="mini"
label-width="80px"
>
<el-form-item label="标题" prop="uploadTitle">
<el-input
placeholder="请输入标题(必填)"
v-model="form.uploadTitle"
></el-input>
</el-form-item>
<el-form-item label="上传文件">
<el-upload
ref="upload"
class="upload-area"
name="zipFile"
accept=".zip"
:action="importZipUrl"
:headers="headers"
:on-success="handleSuccess"
:on-change="handleChange"
:auto-upload="false"
drag
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">
将文件拖到此处,或<em>点击上传</em>,
只能上传zip文件,一次只能传一个文件
</div>
</el-upload>
</el-form-item>
<el-form-item>
<el-button size="mini" type="primary" @click="handleUpload"
>确定上传</el-button
>
<el-button type="primary" size="mini" plain @click.native="handleClose"
>关闭</el-button
>
</el-form-item>
</el-form>
<el-card
class="upload-progress"
shadow="never"
v-if="displayList.length > 0"
>
<h3>上传列表</h3>
<el-table :data="displayList" fit v-loading="loading">
<el-table-column prop="name" label="标题"> </el-table-column>
<el-table-column prop="size" label="文件大小">
<template slot-scope="scope">
{{ getSize(scope.row.size) }}
</template>
</el-table-column>
<el-table-column prop="progress" label="进度" width="300">
<template slot-scope="scope">
<el-progress
:percentage="scope.row.percent"
v-if="!isNaN(parseInt(scope.row.percent))"
:status="scope.row.status"
:text-inside="true"
:stroke-width="16"
></el-progress>
</template>
</el-table-column>
<el-table-column prop="operation" label="操作" width="100">
<template slot-scope="scope">
<el-button
type="text"
size="mini"
@click.native="handleCancel(scope.$index)"
v-if="scope.row.status == null"
>取消</el-button
>
<!-- <el-button
type="text"
size="mini"
@click.native="handleRestart(scope.$index)"
v-if="scope.row.status == 'exception'"
>重新上传</el-button
> -->
</template>
</el-table-column>
</el-table>
</el-card>
</el-dialog>
</template>
<script>
import TablePage from "@/components/Table/TablePage";
import { importZip } from "@/utils/file";
import { getToken } from "@/utils/auth";
export default {
name: "UploadListDialog",
components: {
TablePage,
},
data() {
return {
dialogVisible: false,
isUpLoading: false,
percentState: 0,
list: {
records: [],
current: 1,
size: 10,
},
progressStatus: null,
visible: false, //控制批量上传弹窗显示
fileList: [], //上传当中的文件队列
displayList: [], //用于显示下方的文件队列
uploadCount: 0, //处于上传中的文件数量,当等于fileList的时候就关闭弹窗,请求完毕一个就++
cancelUploadArr: [], //保存每个文件上传接口对应的取消请求的函数[fn,fn,fn...],点叉叉关闭弹窗就遍历这个全部执行一遍就取消了所以请求
importZipUrl: process.env.VUE_APP_BASE_API + "/bizImport/importZip",
headers: {
authorization: getToken(),
},
loading: false,
form: {
uploadTitle: "",
},
rules: {
uploadTitle: [
{
required: true,
message: "请输入上传标题",
trigger: "change",
},
],
},
};
},
computed: {
getSize(size) {
return (size) => {
return (size / 1024 / 1024).toFixed(2) + "M"; //1M=1024Kb=1024*1024byte
};
},
},
methods: {
// 取消编辑
cancelForm() {
this.handleClose();
},
// 提交上传
handleUpload(file) {
this.$refs.form.validate((valid) => {
if (valid) {
if (file && file instanceof File) {
this.fileList = [file];
} else {
this.fileList = this.$refs.upload.uploadFiles;
}
console.log("this.fileList", this.fileList);
// return
for (let i = 0; i < this.fileList.length; i++) {
this.uploadSelf(this.fileList[i].raw, i); //弹窗显示的时候,就根据文件队列的数量调用上传接口
}
}
});
},
// 保证一次只能传一个,覆盖上一次
handleChange(file, fileList) {
if (fileList.length > 1) {
fileList[0] = fileList[1];
fileList.splice(1, 1);
}
},
// 上传函数实现逻辑
uploadSelf(file, index) {
this.loading = true;
let formData = new FormData();
formData.append("type", "biz_cultural_relic");
formData.append("zipFile", file);
formData.append("title", this.form.uploadTitle);
this.loading = false;
importZip(
formData,
(progressEvent) => this.uploadUnderWayCallback(progressEvent, index),
(cancelCallback) => this.cancelCallBack(cancelCallback, index)
)
.then((res) => {
const { code, msg } = res.data;
if (code == 0) {
this.$set(this.fileList[index], "status", "success");
this.$set(this.fileList[index], "desc", "上传成功");
this.$message.success("文件" + file.name + "上传成功!");
this.$emit("update");
} else {
this.$set(this.fileList[index], "status", "exception");
this.$set(this.fileList[index], "desc", "上传失败" + msg);
this.$message.error("上传失败:" + msg);
this.$emit("update");
}
// 删除已经上传成功的,并向display中新增一条
this.displayList.push(this.fileList[index]);
this.fileList.splice(index, 1);
this.$refs.form.resetFields();
})
.catch((err) => {
console.log("err", err);
});
},
// 文件上传进度回调
uploadUnderWayCallback(progressEvent, index) {
let completeVal =
(progressEvent.loaded / progressEvent.total) * 100 - 1 || 0; //处理成组件库进度组件需要的格式
this.$set(this.fileList[index], "percent", Math.floor(completeVal)); //直接改变数组某一项不是响应式的,因此我们需要用到这个api,将其响应式化,添加到数组中
},
// 文件取消回调
cancelCallBack(cancelCallback, index) {
this.$set(this.cancelUploadArr, index, cancelCallback); //添加取消队列中,关闭弹窗批量取消
this.uploadCount = 0;
},
// 关闭弹窗回调
handleClose() {
// 文件列表中如果Status为null,则代表有仍在上传中
let isUpLoading = false;
this.fileList.map((item) => {
if (item.status == null) {
isUpLoading = true;
return;
}
});
let title = isUpLoading ? "当前有上传任务,是否取消上传" : "确认关闭?";
let confirmButtonText = isUpLoading ? "关闭并取消上传" : "确定";
let cancelButtonText = isUpLoading ? "否" : "取消";
let that = this;
this.$confirm(title, "提示", {
confirmButtonText,
cancelButtonText,
type: "warning",
})
.then(() => {
// 点击取消上传
if (that.isUpLoading) {
this.handleCancelAllUpLoad();
this.$message.warning("已取消上传!");
}
this.visible = false; //最后关闭
})
.catch(() => {
console.log("用户取消操作");
});
},
// 取消单个上传任务
handleCancel(index) {
if (this.cancelUploadArr[index]) {
this.cancelUploadArr[index](); //取消上传
this.cancelUploadArr.splice(index, 1); //从取消队列中删除
}
if (this.displayList[index]) {
this.displayList.splice(index, 1);
}
this.handleReset();
this.$message.info("已取消上传!");
},
// // 重新上传
// handleRestart(index) {
// // debugger
// const { name } = this.displayList[index];
// this.form.uploadTitle = name;
// this.handleUpload(this.displayList[index]);
// },
// 全部取消上传
handleCancelAllUpLoad() {
this.cancelUploadArr.forEach((cancelCallBack) => cancelCallBack()); //批量取消上传
},
// 上传成功的回调
handleSuccess(res) {
res.Success && this.$Message.success("上传成功"); //提示
this.fileList = [];
},
// 恢复初始值
handleReset() {
this.fileList = [];
this.uploadCount = 0;
this.cancelUploadArr = [];
},
},
};
</script>
<style lang="scss" scoped>
.title {
display: flex;
align-items: center;
.divider {
width: 8px;
height: 16px;
border-left: 4px solid #409eff;
margin-right: 8px;
}
.label {
font-weight: bold;
}
.tips {
font-size: 14px;
color: #666;
margin-left: 10px;
}
}
.upload-area {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
margin-bottom: 30px;
::v-deep .el-upload,
::v-deep .el-upload-dragger {
width: 100%;
}
}
.upload-progress {
margin-bottom: 30px;
}
.upload-records {
margin-bottom: 30px;
}
.dialog-footer {
margin-top: 30px;
display: flex;
justify-content: flex-end;
}
.el-dialog__body {
padding: 0 20px 30px 20px;
}
::v-deep .el-upload-list {
display: flex;
justify-content: flex-start;
width: 100%;
}
</style>
<template>
<el-dialog
:visible="dialogVisible"
width="60%"
style="height: 98%"
:before-close="handleClose"
top="5vh"
lock-scroll
>
<div class="title" slot="title">
<div class="divider"></div>
<span class="label">上传列表</span>
<span class="tips">
<i class="el-icon-info"></i
>提示:上传过程中请勿关闭此弹窗或刷新页面等操作
</span>
</div>
<div class="upload-progress">
<el-table :data="filesList" fit>
<el-table-column prop="name" label="文件名"> </el-table-column>
<el-table-column prop="size" label="文件大小">
<template slot-scope="scope">
{{ getSize(scope.row.size) }}
</template>
</el-table-column>
<el-table-column prop="progress" label="进度" width="300">
<template slot-scope="scope">
<el-progress
:percentage="scope.row.percent"
v-if="!isNaN(parseInt(scope.row.percent))"
:status="scope.row.status"
></el-progress>
</template>
</el-table-column>
<el-table-column prop="operation" label="操作" width="100">
<template slot-scope="scope">
<el-button
type="text"
size="mini"
icon="el-icon-circle-close"
@click.native="handleCancel(scope.$index)"
v-if="scope.row.status == null"
></el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="dialog-footer">
<el-button type="primary" size="mini" @click.native="handleClose">关闭</el-button>
</div>
</el-dialog>
</template>
<script>
import TablePage from "@/components/Table/TablePage";
export default {
name: "UploadListDialog",
components: {
TablePage,
},
props: {
visible: {
type: Boolean,
default: false,
},
filesList: {
type: Array,
default: () => [],
},
},
watch: {
visible: {
handler: function (value) {
this.dialogVisible = value;
},
deep: true,
immediate: true,
},
filesList(value) {
// console.log("value", value);
},
},
data() {
return {
dialogVisible: false,
isUpLoading: false,
percentState: 0,
list: {
records: [],
current: 1,
size: 10,
},
progressStatus: null,
};
},
computed: {
getSize(size) {
return (size) => {
return (size / 1024 / 1024).toFixed(2) + "M"; //1M=1024Kb=1024*1024byte
};
},
},
mounted() {
// this.loadData();
},
methods: {
// 取消编辑
cancelForm() {
this.handleClose();
},
handleCancel(index) {
this.$emit("handleCancel", index);
},
handleClose() {
this.$emit("handleClose");
},
},
};
</script>
<style lang='scss' scoped>
.title {
display: flex;
align-items: center;
.divider {
width: 8px;
height: 16px;
border-left: 4px solid #409eff;
margin-right: 8px;
}
.label {
font-weight: bold;
}
.tips{
font-size: 14px;
color: #666;
margin-left: 10px;
}
}
.dialog-content {
padding: 0 32px;
display: flex;
flex-direction: column;
.upload-area {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
margin-bottom: 30px;
}
.upload-progress {
margin-bottom: 30px;
}
.upload-records {
margin-bottom: 30px;
}
}
.dialog-footer {
margin-top: 30px;
display: flex;
justify-content: flex-end;
}
.el-dialog__body {
padding: 0 20px 30px 20px;
}
</style>
\ No newline at end of file
......@@ -2,7 +2,7 @@
<el-dialog
:visible="visible"
width="70%"
style="height: 50vh"
style="height: 80vh"
:before-close="handleClose"
top="5vh"
lock-scroll
......
export const title = [{
export const passedTitle = [{
prop: "name",
label: "名称",
columnAlign: 'center',
showOverFlowToolTip: true,
},
// {
// prop: "level",
// label: "文物级别",
// columnAlign: 'center',
// },
// {
// prop: "detailSize",
// label: "尺寸",
// columnAlign: 'center',
// },
// {
// prop: "textureType",
// label: "质地",
// columnAlign: 'center',
// },
// {
// prop: "type",
// label: "类别",
// width: 100,
// columnAlign: 'center',
// isCulturalRelicType:true
// },
// {
// prop: "createId",
// label: "创建人",
// columnAlign: 'center',
// },
// {
// prop: "createTime",
// label: "创建时间",
// columnAlign: 'center',
// },
{
prop: "deptName",
label: "馆藏单位",
columnAlign: 'center',
showOverFlowToolTip: true,
},
// {
// prop: "regionName",
// label: "所属地",
// columnAlign: 'center',
// showOverFlowToolTip: true,
// },
// {
// prop: "intro",
// label: "馆藏介绍",
// columnAlign: 'center',
// showOverFlowToolTip: true,
// width: 120,
// },
// {
// prop: "themeWord",
// label: "主题词",
// columnAlign: 'center',
// showOverFlowToolTip: true,
// },
{
prop: "faceImageUrl",
label: "封面",
columnAlign: 'center',
isFaceImage: true,
},
{
prop: "status",
label: "上下架状态",
width: 100,
columnAlign: 'center',
isStatus: true
},
// {
// prop: "num",
// label: "数量",
// columnAlign: 'center',
// },
{
prop: "loveCount",
label: "点赞量",
columnAlign: 'center',
sortable: true
},
{
prop: "collectCount",
label: "收藏量",
columnAlign: 'center', sortable: true
},
{
prop: "browseCount",
label: "浏览量",
columnAlign: 'center', sortable: true
},
{
prop: "sourceWay",
label: "来源方式",
columnAlign: 'center',
showOverFlowToolTip: true,
},
{
prop: "checkStatus",
label: "审核状态",
columnAlign: 'center',
},
{
prop: "checkRemark",
label: "审核意见",
columnAlign: 'center',
showOverFlowToolTip: true,
},
{
prop: "remark",
label: "备注",
columnAlign: 'center',
},
// directory 文件夹
// flag3d 是否有3d图片
// updateId 更新人
]
export const unPassedTitle = [{
prop: "name",
label: "名称",
columnAlign: 'center',
......
<template>
<div class="app-container" v-loading="loading">
<div class="top-bar">
<SearchBar :config="searchConfig" @search="search" @reset="reset" />
</div>
<SearchBar
:config="searchConfig"
@search="search"
@reset="reset"
class="search-bar"
/>
<div class="tools">
<div class="tools-item">
<el-button
......@@ -34,102 +37,83 @@
>
添加</el-button
>
<el-upload
class="upload-button"
:action="importZipUrl"
:headers="headers"
accept=".zip"
:show-file-list="false"
:before-upload="handleUpload"
:on-success="handleSuccess"
multiple
<el-button
size="mini"
type="success"
@click.native="handleOperation({ type: 'multiAdd' })"
icon="el-icon-upload"
>
批量导入</el-button
>
<el-button
size="mini"
type="success"
@click.native="handleOperation({ type: 'multiAdd' })"
icon="el-icon-upload"
>
批量导入</el-button
>
</el-upload>
</div>
</div>
<TablePage
:data="list.records"
:tableTitle="tableTitle"
:operates="tableOperates"
>
<template v-slot:status="data">
<el-popconfirm
:title="getStatusTitle(data.scope.status)"
@confirm="handleChangeStatus(data.scope)"
>
<el-switch
slot="reference"
:value="Boolean(Number(data.scope.status))"
></el-switch>
</el-popconfirm>
</template>
<template v-slot:faceImageUrl="data">
<img
:src="
$getFullUrl(data.scope.faceImagePressUrl || data.scope.faceImageUrl)
"
alt="暂无图片"
style="
cursor: pointer;
width: 80px;
height: 80px;
object-fit: contain;
"
@click="handelPreviewImages(data.scope.faceImageUrl)"
/>
</template>
<template v-slot:years="data">
{{ dicts.cultural_relic_years[data.scope.years] }}
</template>
<template v-slot:level="data">
{{ dicts.cultural_relic_level[data.scope.level] }}
</template>
<template v-slot:textureType="data">
{{ dicts.cultural_relic_texture[data.scope.textureType] }}
</template>
<template v-slot:type="data">
{{ dicts.cultural_relic_type[data.scope.type] }}
</template>
<template v-slot:operates="scope">
<TableOperation
:operations="tableOperations"
:rawData="scope.scope.row"
@handleOperation="handleOperation"
></TableOperation>
</template>
</TablePage>
<el-pagination
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="Number(list.current)"
:page-sizes="[10, 20, 40, 50]"
:page-size="Number(list.size)"
layout="total, sizes, prev, pager, next, jumper"
:total="Number(list.total)"
class="pagination"
>
</el-pagination>
<div class="list">
<el-tabs v-model="tabActive">
<el-tab-pane label="待办" name="unPassed"></el-tab-pane>
<el-tab-pane label="已审核通过" name="passed"></el-tab-pane>
</el-tabs>
<TablePage
:data="list.records"
:tableTitle="passedTitle"
:operates="operates"
>
<template v-slot:status="data">
<el-popconfirm
:title="getStatusTitle(data.scope.status)"
@confirm="handleChangeStatus(data.scope)"
>
<el-switch
slot="reference"
:value="Boolean(Number(data.scope.status))"
></el-switch>
</el-popconfirm>
</template>
<template v-slot:faceImageUrl="data">
<img
:src="
$getFullUrl(
data.scope.faceImagePressUrl || data.scope.faceImageUrl
)
"
alt="暂无图片"
style="
cursor: pointer;
width: 80px;
height: 80px;
object-fit: contain;
"
@click="handelPreviewImages(data.scope.faceImageUrl)"
/>
</template>
<template v-slot:operates="scope">
<TableOperation
:operations="operations"
:rawData="scope.scope.row"
@handleOperation="handleOperation"
></TableOperation>
</template>
</TablePage>
<el-pagination
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="Number(list.current)"
:page-sizes="[10, 20, 40, 50]"
:page-size="Number(list.size)"
layout="total, sizes, prev, pager, next, jumper"
:total="Number(list.total)"
class="pagination"
>
</el-pagination>
</div>
<InfoEditDialog
:visible="editVisible"
:form="form"
@handleClose="handleEditClose"
@refresh="loadData"
/>
<UploadListDialog
:visible="multiUploadVisible"
:filesList="filesList"
@handleClose="handleMultiUploadClose"
@handleCancel="handleMultiUploadCancel"
/>
<UploadDialog ref="UploadDialog" @update="loadData"/>
<ImportRecordDialog
:visible="importRecordVisible"
......@@ -155,7 +139,7 @@
import TablePage from "@/components/Table/TablePage.vue";
import TableOperation from "@/components/Table/TableOperation.vue";
import SearchBar from "@/components/SearchBar";
import { title, operates, operations } from "./config";
import { passedTitle, unPassedTitle, operates, operations } from "./config";
import {
getCulturalRelicListPer,
getRCDetailById,
......@@ -163,11 +147,10 @@ import {
editCulturalRelic,
} from "@/api/culturalRelic";
import InfoEditDialog from "./components/InfoEditDialog";
import UploadListDialog from "./components/UploadListDialog";
import UploadDialog from "./components/UploadDialog";
import ImportRecordDialog from "./components/ImportRecordDialog";
import View3dDialog from "./components/View3dDialog";
import { importZip } from "@/utils/file";
import { getToken } from "@/utils/auth";
export default {
components: {
TablePage,
......@@ -175,7 +158,7 @@ export default {
InfoEditDialog,
SearchBar,
ImportRecordDialog,
UploadListDialog,
UploadDialog,
View3dDialog,
"el-image-viewer": () =>
import("element-ui/packages/image/src/image-viewer"),
......@@ -248,48 +231,44 @@ export default {
},
loading: false,
imgViewerVisible: false,
importRecordVisible: false, //上传记录
imgList: [],
importZipUrl: process.env.VUE_APP_BASE_API + "/bizImport/importZip",
headers: {
authorization: getToken(),
},
isUpLoading: false,
multiUploadVisible: false, //控制批量上传弹窗显示
importRecordVisible: false, //上传记录
filesList: [], //上传当中的文件队列
uploadCount: 0, //处于上传中的文件数量,当等于fileList的时候就关闭弹窗,请求完毕一个就++
cancelUploadArr: [], //保存每个文件上传接口对应的取消请求的函数[fn,fn,fn...],点叉叉关闭弹窗就遍历这个全部执行一遍就取消了所以请求
view3dDialogVisible: false, //3D文件在线浏览弹窗可见性
passedTitle,
unPassedTitle,
operates,
operations,
tabActive: "unPassed",
};
},
//watch部分
watch: {
//监听弹窗变化
multiUploadVisible(val) {
//弹窗关闭记得清空,开启执行批量上传
if (val) {
for (let i = 0; i < this.filesList.length; i++) {
this.uploadSelf(this.filesList[i].file, i); //弹窗显示的时候,就根据文件队列的数量调用上传接口
}
// //监听弹窗变化
// multiUploadVisible(val) {
// //弹窗关闭记得清空,开启执行批量上传
// if (val) {
// for (let i = 0; i < this.filesList.length; i++) {
// this.uploadSelf(this.filesList[i].file, i); //弹窗显示的时候,就根据文件队列的数量调用上传接口
// }
// } else {
// //弹窗关闭,还原数据到初始位置
// this.filesList = [];
// this.uploadCount = 0;
// this.cancelUploadArr = [];
// }
// },
// 监听Tab值不同调取不同的接口
tabActive(value) {
if (value == "passed") {
console.log("passed to do");
} else {
//弹窗关闭,还原数据到初始位置
this.filesList = [];
this.uploadCount = 0;
this.cancelUploadArr = [];
console.log("unPassed to do");
}
},
},
computed: {
tableTitle() {
return title;
},
tableOperates() {
return operates;
},
tableOperations() {
return operations;
},
getStatusTitle(status) {
return (status) => {
if (Number(status)) {
......@@ -303,9 +282,6 @@ export default {
async created() {
this.loadData();
},
mounted() {
// this.tableHeight = 500
},
methods: {
async search(form) {
var params = {
......@@ -367,7 +343,7 @@ export default {
break;
case "multiAdd":
// debugger
// this.multiUploadVisible = true;
this.$refs.UploadDialog.visible = true;
// console.log("this.multiUploadVisible", this.multiUploadVisible);
break;
......@@ -393,109 +369,6 @@ export default {
this.loading = false;
},
// // 文件个数超出
// handleExceed() {
// this.$message.error(`超出上传文件个数,请删除以后再上传!`);
// },
handleUpload(file) {
this.multiUploadVisible = true; //显示弹窗
this.filesList.push({
file,
name: file.name,
size: file.size,
status: null,
desc: null,
});
return false; //阻止自动上传
},
uploadSelf(file, index) {
let formData = new FormData();
formData.append("type", "biz_cultural_relic");
formData.append("zipFile", file);
importZip(
formData,
(progressEvent) => this.uploadUnderWayCallback(progressEvent, index),
(c) => this.cancelCallBack(c, index)
).then((res) => {
if (res.data.code == 0) {
this.$set(this.filesList[index], "status", "success");
this.$set(this.filesList[index], "desc", "上传成功");
this.$message.success("文件" + file.name + "上传成功!");
this.loadData();
} else {
this.$set(this.filesList[index], "status", "warning");
this.$set(this.filesList[index], "desc", "上传失败" + res.data.msg);
this.$message.error("上传失败:" + res.data.msg);
this.loadData();
}
});
},
// 文件上传进度回调
uploadUnderWayCallback(progressEvent, index) {
let completeVal =
(progressEvent.loaded / progressEvent.total) * 100 - 1 || 0; //处理成组件库进度组件需要的格式
this.$set(this.filesList[index], "percent", Math.floor(completeVal)); //直接改变数组某一项不是响应式的,因此我们需要用到这个api,将其响应式化,添加到数组中
},
// 文件取消回调
cancelCallBack(c, index) {
this.$set(this.cancelUploadArr, index, c); //添加取消队列中,关闭弹窗批量取消
this.uploadCount = 0;
},
handleMultiUploadClose() {
// 文件列表中如果Status为null,则代表有仍在上传中
let isUpLoading = false;
this.filesList.map((item) => {
if (item.status == null) {
isUpLoading = true;
return;
}
});
let title = isUpLoading ? "当前有上传任务,是否取消上传" : "确认关闭?";
let confirmButtonText = isUpLoading ? "关闭并取消上传" : "确定";
let cancelButtonText = isUpLoading ? "否" : "取消";
let that = this;
this.$confirm(title, "提示", {
confirmButtonText,
cancelButtonText,
type: "warning",
})
.then(() => {
// 点击取消上传
if (that.isUpLoading) {
this.handleCancelAllUpLoad();
this.$message.warning("已取消上传!");
}
this.multiUploadVisible = false; //最后关闭
})
.catch(() => {
console.log("用户取消操作");
});
},
handleMultiUploadCancel(index) {
if (this.cancelUploadArr[index]) {
this.cancelUploadArr[index](); //取消上传
this.cancelUploadArr.splice(index, 1); //从取消队列中删除
}
if (this.filesList[index]) {
this.filesList.splice(index, 1);
}
this.$message.info("已取消上传!");
},
handleCancelAllUpLoad() {
this.cancelUploadArr.forEach((cancelCallBack) => cancelCallBack()); //批量取消上传
},
handleSuccess(res) {
res.Success && this.$Message.success("上传成功"); //提示
// this.processModal = false; //成功后关闭弹窗
this.filesList = [];
},
// 关闭预览图片
closeImgViewer() {
this.imgViewerVisible = false;
......@@ -560,8 +433,8 @@ export default {
display: flex;
flex-direction: column;
}
.top-bar {
height: 68px;
.search-bar {
margin-bottom: 16px;
}
.tools {
......
<template>
<el-dialog
:visible.sync="visible"
fullscreen
top="3vh"
:before-close="handleClose"
lock-scroll
>
......@@ -17,14 +17,18 @@
:label="item"
:name="item"
>
<ApprovalInfo :info="aprrovalInfo" v-if="item == '审批详情'" />
<ApprovalInfo
:info="aprrovalInfo"
:isShowApprovalForm="prviewType == 'approval'"
v-if="item == '流程详情'"
/>
<CulturalRelicBaseInfo
:info="culturalRelicBaseInfo"
v-if="item == '文物基本信息'"
/>
<CulturalRelicTable :crList="crList" v-if="item == '文物列表'" />
<DisplayBaseInfo :info="displayInfo" v-if="item == '展览基本信息'" />
<DisplayRender :info="displayInfo" v-if="item == '展览基本信息'" />
<DisplayRender :info="displayInfo" v-if="item == '效果预览'" />
</el-tab-pane>
</el-tabs>
</div>
......@@ -37,6 +41,7 @@ import CulturalRelicBaseInfo from "./culturalRelic/CulturalRelicInfo.vue";
import CulturalRelicTable from "./culturalRelic/CulturalRelicTable.vue";
import DisplayBaseInfo from "./display/DisplayBaseInfo.vue";
import ApprovalInfo from "./approval/ApprovalInfo.vue";
import DisplayRender from "./display/DisplayRender.vue";
import { cr, crList, display } from "../mock";
export default {
name: "PreviewDialog",
......@@ -44,7 +49,8 @@ export default {
CulturalRelicBaseInfo,
CulturalRelicTable,
ApprovalInfo,
DisplayBaseInfo
DisplayBaseInfo,
DisplayRender,
},
props: {
// 预览类型,view or approval
......@@ -60,7 +66,7 @@ export default {
computed: {
...mapGetters(["dicts"]),
tabs() {
const tabs = ["审批详情"];
const tabs = ["流程详情"];
const { sourceType, addWay } = this.aprrovalInfo;
switch (sourceType) {
case "展览":
......@@ -80,7 +86,7 @@ export default {
data() {
return {
visible: false,
activeName: "审批详情",
activeName: "流程详情",
culturalRelicBaseInfo: cr, //单个文物的信息
crList,
displayInfo: display,
......@@ -89,9 +95,15 @@ export default {
methods: {
handleClose(done) {
this.visible = false;
this.activeName = "流程详情";
},
},
};
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
::v-deep .el-tabs__content {
max-height: 60vh;
overflow: auto;
}
</style>
<template>
<div>
<div class="approval-form">
<!-- 审批表单 -->
<el-button
<el-form
size="mini"
@click.native="handleCancel"
style="margin-right: 6px"
>取消</el-button
:model="dialogForm"
prop="remark"
:rules="rules"
ref="form"
>
<el-popover
placement="top-end"
width="400"
trigger="manual"
v-model="popoverVisible"
>
<div>
<el-form
<el-form-item label="审批意见:">
<el-radio-group
v-model="checkStatus"
size="mini"
:model="dialogForm"
prop="remark"
:rules="rules"
ref="form"
style="margin-bottom: 20px"
>
<el-form-item label="驳回意见" prop="remark">
<el-input
type="textarea"
placeholder="驳回意见"
v-model="dialogForm.remark"
size="mini"
:rows="4"
>
</el-input>
<el-button
size="mini"
type="primary"
style="float: right; margin-top: 16px"
@click.native="handleCheck(-2)"
>确定</el-button
>
</el-form-item>
</el-form>
</div>
<el-button
size="mini"
slot="reference"
type="danger"
icon="el-icon-close"
@click.native="handleShowPopover"
>驳回</el-button
>
</el-popover>
<el-button
size="mini"
style="margin-left: 6px"
type="primary"
icon="el-icon-check"
@click.native="handleCheck(1)"
>同意</el-button
>
<el-radio :label="1" border>同意</el-radio>
<el-radio :label="-2" border>驳回</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="驳回意见:" prop="remark" v-if="checkStatus == -2">
<el-input
type="textarea"
placeholder="驳回意见"
v-model="dialogForm.remark"
size="mini"
:rows="4"
>
</el-input>
</el-form-item>
<el-form-item>
<el-button
size="mini"
style="margin:0; width: 100%"
type="primary"
icon="el-icon-check"
@click.native="handleCheck"
>确定</el-button
>
</el-form-item>
</el-form>
</div>
</template>
......@@ -64,6 +46,10 @@
export default {
data() {
return {
checkStatus: 1,
dialogForm: {
remark: "", //驳回意见
},
rules: {
remark: [
{
......@@ -76,7 +62,8 @@ export default {
};
},
methods: {
async handleCheck(checkStatus) {
async handleCheck() {
const { checkStatus } = this;
if (checkStatus == -2) {
this.$refs.form.validate(async (valid) => {
if (valid) {
......@@ -123,4 +110,4 @@ export default {
};
</script>
<style></style>
<style lang="scss" scoped></style>
......@@ -2,7 +2,7 @@
<!-- 审核的基本信息 -->
<div>
<el-card class="card" shadow="hover">
<el-descriptions title="审核基本详情">
<el-descriptions title="流程基本信息">
<el-descriptions-item
:label="item.label"
v-for="(item, index) in approvleTableTitle"
......@@ -11,8 +11,8 @@
>
</el-descriptions>
</el-card>
<el-card shadow="hover">
<h3>审核流程</h3>
<el-card shadow="hover" class="card">
<h3>详细流程节点</h3>
<el-steps :active="historyChecks.length">
<el-step
v-for="(item, index) in historyChecks"
......@@ -28,20 +28,33 @@
</el-step>
</el-steps>
</el-card>
<el-card v-if="isShowApprovalForm">
<h3>请审批</h3>
<ApprovalForm />
</el-card>
</div>
</template>
<script>
import { approvleTableTitle } from "../../config";
import { historyChecks } from "../../mock";
import ApprovalForm from "./ApprovalForm.vue";
export default {
name: "AprrovalInfo",
components: {
ApprovalForm,
},
props: {
// 审核的信息
info: {
type: Object,
default: () => ({}),
},
// 是否展示审核的表单
isShowApprovalForm: {
type: Boolean,
default: false,
},
},
computed: {
getStepTitle(item) {
......
......@@ -13,15 +13,17 @@
v-if="item.prop == 'faceImagePressUrl'"
:src="info['faceImagePressUrl']"
fit="contain"
:preview-src-list="[info['faceImageUrl']]"
>
</el-image>
<div v-else-if="item.prop == 'imagesVo'">
<div v-else-if="item.prop == 'imagesVo' && info.imagesVo.length > 0">
<el-image
v-for="(v, i) in info['imagesVo']"
:key="i"
class="image"
:src="v.pressUrl"
fit="contain"
:preview-src-list="imgsList"
>
</el-image>
</div>
......@@ -48,7 +50,7 @@
<el-table-column prop="source" label="来源"></el-table-column>
<el-table-column prop="source" label="操作">
<template slot-scope="scope">
<el-button type='text'>预览</el-button>
<el-button type="text">预览</el-button>
</template>
</el-table-column>
</el-table>
......@@ -76,6 +78,14 @@ export default {
default: () => ({}),
},
},
computed: {
// 大图预览的
imgsList() {
return this.info.imagesVo.map((item) => {
return item.url;
});
},
},
data() {
return {
crTabletitle,
......@@ -101,8 +111,8 @@ export default {
border-radius: 4px;
}
.video {
width: 200px;
height: 200px;
width: 400px;
height: 400px;
border: 1px solid #dadada;
border-radius: 4px;
}
......
......@@ -10,9 +10,7 @@
</template>
<template v-slot:faceImagePressUrl="data">
<img
:src="
$getFullUrl(data.scope.faceImagePressUrl)
"
:src="$getFullUrl(data.scope.faceImagePressUrl)"
alt="暂无图片"
style="
cursor: pointer;
......
......@@ -2,7 +2,7 @@
<!-- 文物基本信息 -->
<div>
<el-card shadow="hover">
<el-descriptions title="文物基本详情" :column="1" labelClassName="label">
<el-descriptions title="展览基本详情" :column="1" labelClassName="label">
<el-descriptions-item
:label="item.label"
v-for="(item, index) in displayTabletitle"
......@@ -13,47 +13,67 @@
v-if="item.prop == 'faceImagePressUrl'"
:src="info['faceImagePressUrl']"
fit="contain"
:preview-src-list="[info['faceImageUrl']]"
>
</el-image>
<div v-else-if="item.prop == 'imagesVo'">
<el-image
v-for="(v, i) in info['imagesVo']"
:key="i"
class="image"
:src="v.pressUrl"
fit="contain"
>
</el-image>
<div v-if="info['imagesVo'].length > 0">
<el-image
v-for="(v, i) in info['imagesVo']"
:key="i"
class="image"
:src="v.pressUrl"
fit="contain"
:preview-src-list="imgsList"
>
</el-image>
</div>
<span v-else>暂无音频</span>
</div>
<div v-else-if="item.prop == 'videosVo'">
<VideoPlayer
class="video"
v-for="(v, i) in info['videosVo']"
:key="i"
:src="v.url"
/>
<div v-if="info['videosVo'].length > 0">
<VideoPlayer
class="video"
v-for="(v, i) in info['videosVo']"
:key="i"
:src="v.url"
/>
</div>
<span v-else>暂无音频</span>
</div>
<div v-else-if="item.prop == 'audiosVo'">
<AudioPlayer
v-for="(v, i) in info['audiosVo']"
:key="i"
:url="v.url"
ref="AudioPlayer"
/>
<div v-if="info['audiosVo'].length > 0">
<AudioPlayer
v-for="(v, i) in info['audiosVo']"
:key="i"
:url="v.url"
ref="AudioPlayer"
/>
</div>
<span v-else>暂无音频</span>
</div>
<div v-else-if="item.prop == 'literatureVo'">
<el-table stripe border :data="info['literatureVo']">
<el-table-column prop="name" label="名称"></el-table-column>
<el-table-column prop="authors" label="作者"></el-table-column>
<el-table-column prop="source" label="来源"></el-table-column>
<el-table-column prop="source" label="操作">
<template slot-scope="scope">
<el-button type='text'>预览</el-button>
</template>
</el-table-column>
</el-table>
<div v-if="info['literatureVo'].length > 0">
<el-table stripe border :data="info['literatureVo']">
<el-table-column prop="name" label="名称"></el-table-column>
<el-table-column prop="authors" label="作者"></el-table-column>
<el-table-column prop="source" label="来源"></el-table-column>
<el-table-column prop="source" label="操作">
<template slot-scope="scope">
<el-button type="text">预览</el-button>
</template>
</el-table-column>
</el-table>
</div>
<span v-else>暂无文献</span>
</div>
<TextShow
v-else-if="item.prop === 'intro'"
:richText="info['intro']"
></TextShow>
<div v-else-if="item.prop === 'type'">
<DictText name="displayType" :dictValue="info['type']" />
</div>
<div v-else-if="item.prop === 'intro'" v-html="info['intro']"></div>
<span v-else>{{ info[item.prop] || "无" }}</span>
</el-descriptions-item>
</el-descriptions>
......@@ -76,6 +96,14 @@ export default {
default: () => ({}),
},
},
computed: {
// 大图预览的数组
imgsList() {
return this.info.imagesVo.map((item) => {
return item.url;
});
},
},
data() {
return {
displayTabletitle,
......@@ -101,8 +129,8 @@ export default {
border-radius: 4px;
}
.video {
width: 200px;
height: 200px;
width: 400px;
height: 400px;
border: 1px solid #dadada;
border-radius: 4px;
}
......
<template>
<!-- 展览效果预览图 -->
<div class="container" v-if="dicts && Object.keys(displayDetail).length > 0">
<div class="container">
<NavBar />
<NormalStyle
v-if="displayDetail.themeType == NORMAL_STYLE.value"
:displayDetail="displayDetail"
v-if="info.themeType == NORMAL_STYLE.value"
:displayDetail="info"
:dicts="dicts"
/>
<ChStyle
v-if="displayDetail.themeType == CH_STYLE.value"
:displayDetail="displayDetail"
v-if="info.themeType == CH_STYLE.value"
:displayDetail="info"
:dicts="dicts"
/>
<RedStyle
v-if="displayDetail.themeType == RED_STYLE.value"
:displayDetail="displayDetail"
v-if="info.themeType == RED_STYLE.value"
:displayDetail="info"
:dicts="dicts"
/>
<Footer />
......
......@@ -216,13 +216,13 @@ export const crTabletitle = [{
columnAlign: 'center',
isFaceImage: true,
},
{
prop: "statusLabel",
label: "上下架状态",
width: 100,
columnAlign: 'center',
isStatus: true
},
// {
// prop: "statusLabel",
// label: "上下架状态",
// width: 100,
// columnAlign: 'center',
// isStatus: true
// },
{
prop: "num",
label: "数量",
......
......@@ -198,7 +198,7 @@ export const cr = {
"yearsLabel": "隐生代"
}
// 批量文物信息
// 批量文物信息(未对一些字典进行翻译)
export const crList = {
size: 10,
current: 1,
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论