<template>
|
<div>
|
<div class="choose-material" :class="title ? '' : 'has-title'">
|
<div class="add-group" v-if="title">
|
<div>*</div>
|
<span>{{ title }}</span>
|
</div>
|
|
<!-- 动态渲染组件 -->
|
<div
|
v-for="(item, idx) in components"
|
:key="item.id"
|
class="dynamic-component"
|
>
|
<!-- 富文本 -->
|
<div v-if="item.type == 'richText'">
|
<AiEditor
|
:ref="`editor_${item.id}`"
|
v-model="item.data.content"
|
height="200px"
|
placeholder="请输入内容..."
|
/>
|
</div>
|
<!-- 自定义表格 -->
|
<div v-else-if="item.type == 'customTable'" style="flex: 1">
|
<Table
|
:data="item.data.rows"
|
:total="null"
|
:height="null"
|
class="groupTable"
|
>
|
<el-table-column
|
v-for="(header, hidx) in item.data.headers"
|
:key="hidx"
|
:label="header.name"
|
:prop="header.name"
|
>
|
<template slot-scope="scope">
|
<!-- 文本类型 -->
|
<span v-if="header.type === 'text'">{{ scope.row[header.name] }}</span>
|
<!-- 图片类型 -->
|
<div v-else-if="header.type === 'image'" class="image-preview">
|
<el-image
|
v-for="(img, imgIndex) in scope.row[header.name]"
|
:key="imgIndex"
|
:src="img.url"
|
:preview-src-list="[img.url]"
|
fit="cover"
|
class="preview-image"
|
/>
|
</div>
|
<!-- 日期类型 -->
|
<span v-else-if="header.type === 'date'">{{ scope.row[header.name] }}</span>
|
<!-- 用户类型 -->
|
<div v-else-if="header.type === 'user'" class="user-tags">
|
<el-tag
|
v-for="user in scope.row[header.name]"
|
:key="user"
|
class="user-tag"
|
>
|
{{ getUserName(user) }}
|
</el-tag>
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column
|
label="更新时间"
|
prop="updateTime"
|
min-width="180"
|
></el-table-column>
|
</Table>
|
</div>
|
<!-- 文件上传 -->
|
<div v-else-if="item.type == 'fileUpload'">
|
<el-upload
|
action="#"
|
:file-list="item.data.fileList"
|
:disabled="true"
|
list-type="text"
|
>
|
<el-button style="display: none">点击上传</el-button>
|
</el-upload>
|
</div>
|
<!-- 图片上传 -->
|
<div v-else-if="item.type == 'imageUpload'">
|
<el-image
|
v-for="(img, imgIndex) in item.data.images"
|
:key="imgIndex"
|
:src="img.url"
|
:preview-src-list="[img.url]"
|
fit="cover"
|
class="preview-image"
|
/>
|
</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import Table from "../Table/index.vue";
|
import AiEditor from "../AiEditor/index.vue";
|
|
export default {
|
name: "ViewDynamicComponent",
|
components: {
|
Table,
|
AiEditor
|
},
|
props: {
|
title: {
|
type: String,
|
default: "",
|
},
|
components: {
|
type: Array,
|
default: () => [],
|
}
|
},
|
data() {
|
return {
|
userOptions: [
|
{ value: '1', label: '用户1' },
|
{ value: '2', label: '用户2' },
|
{ value: '3', label: '用户3' },
|
{ value: '4', label: '用户4' },
|
{ value: '5', label: '用户5' }
|
]
|
};
|
},
|
methods: {
|
getUserName(userId) {
|
const user = this.userOptions.find(u => u.value === userId);
|
return user ? user.label : userId;
|
}
|
}
|
};
|
</script>
|
|
<style scoped lang="less">
|
.preview-image{
|
width: 120px;
|
height: 120px;
|
border-radius: 4px;
|
object-fit: cover;
|
margin-right: 20px;
|
}
|
.choose-material {
|
background: #eff8fa;
|
padding: 20px;
|
margin-top: 37px;
|
}
|
.has-title{
|
margin-top: 0px !important;
|
}
|
.add-group {
|
display: flex;
|
align-items: center;
|
margin-bottom: 19px;
|
|
div {
|
color: #f56c6c;
|
}
|
|
span {
|
font-weight: 500;
|
font-size: 14px;
|
color: #222222;
|
line-height: 21px;
|
margin: 0 32px 0 8px;
|
}
|
}
|
.dynamic-component {
|
background: #ffffff;
|
padding: 15px 20px;
|
display: flex;
|
justify-content: space-between;
|
margin-bottom: 20px;
|
}
|
|
.rich-text-content {
|
width: 100%;
|
min-height: 200px;
|
padding: 10px;
|
border: 1px solid #dcdfe6;
|
border-radius: 4px;
|
background-color: #f5f7fa;
|
}
|
|
.image-preview {
|
display: flex;
|
flex-wrap: wrap;
|
gap: 8px;
|
|
.preview-image {
|
width: 120px;
|
height: 120px;
|
border-radius: 4px;
|
object-fit: cover;
|
}
|
}
|
|
.user-tags {
|
display: flex;
|
flex-wrap: wrap;
|
gap: 4px;
|
}
|
|
.user-tag {
|
margin-right: 4px;
|
margin-bottom: 4px;
|
}
|
|
|
.uploaf-notice {
|
font-weight: 400;
|
font-size: 14px;
|
color: rgba(0, 0, 0, 0.85);
|
line-height: 22px;
|
margin-top: 8px;
|
}
|
|
.groupTable {
|
width: 100%;
|
margin-top: 10px;
|
::v-deep .el-input__inner {
|
width: unset !important;
|
}
|
}
|
</style>
|