<template>
|
<el-dialog
|
title="添加表数据"
|
:visible.sync="dialogVisible"
|
width="60%"
|
:close-on-click-modal="false"
|
@close="handleClose"
|
>
|
<div class="sample-dialog">
|
<div class="sample-content">
|
<div class="form-content">
|
<el-form ref="form" :model="form" :rules="rules" label-position="top">
|
<el-row :gutter="20">
|
<el-col :span="12">
|
<el-form-item label="更新时间" prop="updateTime">
|
<el-input
|
v-model="form.updateTime"
|
placeholder="更新时间"
|
disabled
|
/>
|
</el-form-item>
|
</el-col>
|
<el-col
|
:span="12"
|
v-for="(header, index) in headerList"
|
:key="index"
|
>
|
<el-form-item
|
:label="header.name"
|
:prop="header.name"
|
:rules="{
|
required: header.required === true || header.required === 'true',
|
message: header.message || `请输入${header.name}`,
|
trigger: ['blur', 'change']
|
}"
|
v-if="header.type == 'text'"
|
>
|
<el-input
|
v-model="form[header.name]"
|
:placeholder="'请输入' + header.name"
|
/>
|
</el-form-item>
|
<el-form-item
|
:label="header.name"
|
:prop="header.name"
|
:rules="{
|
required: header.required === true || header.required === 'true',
|
message: header.message || `请输入${header.name}`,
|
trigger: ['blur', 'change']
|
}"
|
v-if="header.type == 'image'"
|
>
|
<el-upload
|
class="upload-demo"
|
action="#"
|
:file-list="spectrumList"
|
:auto-upload="false"
|
list-type="picture-card"
|
:on-change="handleSpectrumChange"
|
:on-remove="handleSpectrumRemove"
|
>
|
<i class="el-icon-plus"></i>
|
</el-upload>
|
</el-form-item>
|
<el-form-item
|
:label="header.name"
|
:prop="header.name"
|
:rules="{
|
required: header.required === true || header.required === 'true',
|
message: header.message || `请输入${header.name}`,
|
trigger: ['blur', 'change']
|
}"
|
v-if="header.type == 'date'"
|
>
|
<el-date-picker
|
v-model="form[header.name]"
|
type="datetime"
|
placeholder="选择日期时间"
|
value-format="yyyy-MM-dd HH:mm:ss"
|
:picker-options="{
|
shortcuts: [{
|
text: '今天',
|
onClick(picker) {
|
picker.$emit('pick', new Date());
|
}
|
}, {
|
text: '昨天',
|
onClick(picker) {
|
const date = new Date();
|
date.setTime(date.getTime() - 3600 * 1000 * 24);
|
picker.$emit('pick', date);
|
}
|
}, {
|
text: '一周前',
|
onClick(picker) {
|
const date = new Date();
|
date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
|
picker.$emit('pick', date);
|
}
|
}]
|
}"
|
/>
|
</el-form-item>
|
<el-form-item
|
:label="header.name"
|
:prop="header.name"
|
:rules="{
|
required: header.required === true || header.required === 'true',
|
message: header.message || `请输入${header.name}`,
|
trigger: ['blur', 'change']
|
}"
|
v-if="header.type == 'user'"
|
>
|
<el-select
|
v-model="form[header.name]"
|
multiple
|
filterable
|
placeholder="请选择用户"
|
>
|
<el-option
|
v-for="item in userOptions"
|
:key="item.value"
|
:label="item.label"
|
:value="item.value"
|
/>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
</el-form>
|
</div>
|
</div>
|
</div>
|
<div slot="footer" class="dialog-footer select-member-footer">
|
<el-button @click="handleClose">取 消</el-button>
|
<el-button type="primary" @click="handleSubmit">确 定</el-button>
|
</div>
|
</el-dialog>
|
</template>
|
|
<script>
|
export default {
|
name: "AddDialog",
|
props: {
|
visible: {
|
type: Boolean,
|
default: false,
|
},
|
headerList: {
|
type: Array,
|
default: () => [],
|
},
|
editData: {
|
type: Object,
|
default: () => ({}),
|
},
|
isEdit: {
|
type: Boolean,
|
default: false,
|
}
|
},
|
data() {
|
return {
|
isIPad: /iPad/i.test(navigator.userAgent),
|
showHeaderList: [{"name":"sd","type":"text","required":true,"message":"请输入表头名称","role":[]}],
|
form: {},
|
rules: {},
|
photoList: [],
|
spectrumList: [],
|
userOptions: [
|
{ value: '1', label: '用户1' },
|
{ value: '2', label: '用户2' },
|
{ value: '3', label: '用户3' },
|
{ value: '4', label: '用户4' },
|
{ value: '5', label: '用户5' }
|
]
|
};
|
},
|
computed: {
|
dialogVisible: {
|
get() {
|
return this.visible;
|
},
|
set(val) {
|
this.$emit("update:visible", val);
|
},
|
},
|
},
|
watch: {
|
visible: {
|
handler(newVal) {
|
if (newVal) {
|
console.log('弹窗打开,初始化数据');
|
this.showHeaderList = JSON.parse(JSON.stringify(this.headerList));
|
this.$forceUpdate();
|
if (this.isEdit && this.editData) {
|
// 编辑模式:设置回显数据
|
this.setFormData(this.editData);
|
} else {
|
// 新增模式:初始化空表单
|
this.initFormData();
|
}
|
this.initRules();
|
console.log('初始化后的表单数据:', this.form);
|
console.log('初始化后的校验规则:', this.rules);
|
}
|
},
|
},
|
headerList: {
|
immediate: true,
|
handler(newVal) {
|
if (newVal && newVal.length) {
|
console.log('headerList变化,重新初始化');
|
if (this.isEdit && this.editData) {
|
this.setFormData(this.editData);
|
} else {
|
this.initFormData();
|
}
|
this.initRules();
|
}
|
},
|
},
|
showHeaderList: {
|
immediate: true,
|
handler(newVal) {
|
if (newVal ) {
|
|
console.log("222222222222222222", JSON.stringify(newVal));
|
|
}
|
},
|
},
|
},
|
methods: {
|
initRules() {
|
// 初始化校验规则
|
const rules = {};
|
if (this.headerList && this.headerList.length) {
|
this.headerList.forEach(header => {
|
// 处理required可能是字符串的情况
|
const isRequired = header.required === true || header.required === 'true';
|
if (isRequired) {
|
rules[header.name] = [{
|
required: true,
|
message: header.message || `请输入${header.name}`,
|
trigger: ['blur', 'change']
|
}];
|
}
|
});
|
}
|
console.log('生成的校验规则:', rules);
|
this.rules = rules;
|
},
|
initFormData() {
|
// 初始化基础表单数据
|
const formData = {
|
updateTime: this.formatDateTime(new Date()),
|
};
|
|
// 根据headerList初始化表单数据
|
if (this.headerList && this.headerList.length) {
|
this.headerList.forEach(header => {
|
if (header.type === 'user') {
|
formData[header.name] = [];
|
} else {
|
formData[header.name] = '';
|
}
|
});
|
}
|
|
// 使用Vue.set确保响应式
|
Object.keys(formData).forEach(key => {
|
this.$set(this.form, key, formData[key]);
|
});
|
|
console.log('初始化后的表单数据:', this.form);
|
},
|
setFormData(data) {
|
// 设置基础表单数据
|
const formData = {
|
updateTime: this.formatDateTime(new Date()),
|
};
|
|
// 根据headerList设置表单数据
|
if (this.headerList && this.headerList.length) {
|
this.headerList.forEach(header => {
|
if (header.type === 'user') {
|
formData[header.name] = data[header.name] || [];
|
} else {
|
formData[header.name] = data[header.name] || '';
|
}
|
});
|
}
|
|
// 使用Vue.set确保响应式
|
Object.keys(formData).forEach(key => {
|
this.$set(this.form, key, formData[key]);
|
});
|
|
// 设置照片列表
|
if (data.photos && data.photos.length) {
|
this.photoList = data.photos.map((photo) => ({
|
name: photo.name,
|
url: photo.url,
|
status: "success",
|
}));
|
} else {
|
this.photoList = [];
|
}
|
|
// 设置图谱列表
|
if (data.spectrums && data.spectrums.length) {
|
this.spectrumList = data.spectrums.map((spectrum) => ({
|
name: spectrum.name,
|
url: spectrum.url,
|
status: "success",
|
}));
|
} else {
|
this.spectrumList = [];
|
}
|
|
// 重置表单校验状态
|
this.$nextTick(() => {
|
this.$refs.form?.clearValidate();
|
});
|
},
|
formatDateTime(date) {
|
const year = date.getFullYear();
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
const day = String(date.getDate()).padStart(2, '0');
|
const hours = String(date.getHours()).padStart(2, '0');
|
const minutes = String(date.getMinutes()).padStart(2, '0');
|
const seconds = String(date.getSeconds()).padStart(2, '0');
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
},
|
handleClose() {
|
this.dialogVisible = false;
|
this.$refs.form?.resetFields();
|
this.photoList = [];
|
this.spectrumList = [];
|
this.initFormData();
|
},
|
handleSubmit() {
|
console.log('开始提交表单');
|
console.log('表单数据:', this.form);
|
console.log('校验规则:', this.rules);
|
|
this.$refs.form.validate((valid) => {
|
console.log('表单验证结果:', valid);
|
if (valid) {
|
const submitData = {
|
...this.form,
|
photos: this.photoList,
|
spectrums: this.spectrumList,
|
};
|
console.log('提交数据:', submitData);
|
this.$emit("success", submitData);
|
this.handleClose();
|
} else {
|
console.log('表单验证失败');
|
this.$message.error('请填写必填项');
|
}
|
});
|
},
|
handlePhotoChange(file, fileList) {
|
this.photoList = fileList;
|
this.$refs.form.validateField("photos");
|
},
|
handleSpectrumChange(file, fileList) {
|
this.spectrumList = fileList;
|
this.$refs.form.validateField("spectrums");
|
},
|
handleSpectrumRemove(file) {
|
// 处理文件移除逻辑
|
},
|
|
handleIPadSpectrum() {
|
// TODO: 调用 iPad 选择图谱功能
|
console.log("调用 iPad 选择图谱功能");
|
},
|
},
|
mounted() {
|
console.log("初始headerList:", this.headerList);
|
},
|
};
|
</script>
|
|
<style scoped lang="less">
|
::v-deep .el-dialog__body {
|
padding: 0;
|
max-height: calc(100vh - 200px); // 设置最大高度
|
}
|
|
::v-deep .el-dialog {
|
margin-top: 5vh !important; // 调整弹窗位置
|
max-height: 90vh; // 设置弹窗最大高度
|
display: flex;
|
flex-direction: column;
|
|
.el-dialog__body {
|
flex: 1;
|
overflow: hidden; // 防止出现双滚动条
|
}
|
}
|
|
.sample-dialog {
|
height: 100%;
|
|
.sample-content {
|
background: #ffffff;
|
border-radius: 10px;
|
padding: 20px;
|
height: 100%;
|
display: flex;
|
flex-direction: column;
|
|
.form-content {
|
flex: 1;
|
overflow-y: auto;
|
padding: 0 10px;
|
max-height: calc(90vh - 250px); // 设置内容区域最大高度
|
|
&::-webkit-scrollbar {
|
width: 6px;
|
}
|
|
&::-webkit-scrollbar-thumb {
|
background: #c0c4cc;
|
border-radius: 3px;
|
}
|
|
&::-webkit-scrollbar-track {
|
background: #f5f7fa;
|
}
|
}
|
}
|
}
|
|
.dialog-footer {
|
align-items: center;
|
display: flex;
|
justify-content: center;
|
padding: 15px 20px;
|
border-top: 1px solid #e4e7ed;
|
margin-top: auto; // 保持在底部
|
|
button {
|
width: 150px;
|
}
|
}
|
|
.upload-demo {
|
::v-deep {
|
.el-upload--picture-card {
|
width: 120px;
|
height: 120px;
|
line-height: 120px;
|
}
|
|
.el-upload-list--picture-card {
|
display: flex;
|
flex-wrap: wrap;
|
gap: 8px;
|
|
.el-upload-list__item {
|
width: 120px;
|
height: 120px;
|
margin: 0;
|
}
|
}
|
|
// 让上传按钮始终显示在列表最后
|
.el-upload--picture-card {
|
order: 9999;
|
margin: 0;
|
}
|
}
|
|
// 包裹容器也使用flex布局
|
display: flex;
|
flex-wrap: wrap;
|
gap: 8px;
|
}
|
|
.el-row {
|
margin-bottom: 20px;
|
|
&:last-child {
|
margin-bottom: 0; // 最后一行不要margin
|
}
|
}
|
|
::v-deep .el-form-item--small.el-form-item {
|
margin-bottom: 0;
|
}
|
|
::v-deep .el-form-item__label {
|
padding-bottom: 8px;
|
}
|
|
// 优化表单布局
|
::v-deep .el-form {
|
.el-form-item {
|
margin-bottom: 15px; // 减小表单项间距
|
|
&:last-child {
|
margin-bottom: 0;
|
}
|
}
|
}
|
|
// 优化上传区域布局
|
::v-deep .el-upload-list--picture-card {
|
display: flex;
|
flex-wrap: wrap;
|
gap: 8px; // 设置图片间距
|
}
|
|
.upload-file {
|
::v-deep {
|
.el-upload-list {
|
margin-top: 10px;
|
}
|
.el-upload-list__item {
|
transition: all 0.3s;
|
&:hover {
|
background-color: #f5f7fa;
|
}
|
}
|
.el-upload__tip {
|
color: #909399;
|
font-size: 12px;
|
margin-top: 8px;
|
}
|
}
|
}
|
</style>
|