|
|
@@ -0,0 +1,456 @@
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <el-table
|
|
|
+ :data="tableData"
|
|
|
+ style="width: 100%"
|
|
|
+ size="mini"
|
|
|
+ border>
|
|
|
+ <el-table-column
|
|
|
+ prop="eventTime"
|
|
|
+ align="center"
|
|
|
+ label="事件发生时间">
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="eventHospital"
|
|
|
+ align="center"
|
|
|
+ label="事件发生的医院及科室">
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="eventDesc"
|
|
|
+ align="center"
|
|
|
+ label="事件详细描述">
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="eventImage"
|
|
|
+ align="center"
|
|
|
+ label="图片上传">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <div>
|
|
|
+ <div v-for="img in scope.row.eventImage" style="color: #1890ff; cursor: pointer;" :key="img" @click="handleItem(img)">
|
|
|
+ {{ img.name }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="eventOpinion"
|
|
|
+ align="center"
|
|
|
+ label="其他意见">
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ label="操作"
|
|
|
+ align="center"
|
|
|
+ width="100"
|
|
|
+ v-if="!view">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <!-- <el-button @click="editRow(scope.row, scope.$index)" type="text" size="mini">编辑</el-button> -->
|
|
|
+ <el-button @click="deleteRow(scope.$index)" type="text" size="mini">删除</el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ <div v-if="!view" @click="addRow" style="text-align: center;">
|
|
|
+ <el-button type="text" icon="el-icon-plus">添加</el-button>
|
|
|
+ </div>
|
|
|
+ <ele-modal
|
|
|
+ title="明细"
|
|
|
+ custom-class="ele-dialog-form long-dialog-form"
|
|
|
+ :visible.sync="visible"
|
|
|
+ :before-close="handleClose"
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ top="5vh"
|
|
|
+ :close-on-press-escape="false"
|
|
|
+ append-to-body
|
|
|
+ width="70%"
|
|
|
+ :maxable="true"
|
|
|
+ >
|
|
|
+ <el-card shadow="never">
|
|
|
+ <el-form ref="form" :model="form">
|
|
|
+ <el-form-item
|
|
|
+ label="事件发生时间"
|
|
|
+ label-width="110px"
|
|
|
+ prop="eventTime"
|
|
|
+ :rules="{
|
|
|
+ required: true,
|
|
|
+ message: '选择事件发生时间',
|
|
|
+ trigger: 'change'
|
|
|
+ }"
|
|
|
+ >
|
|
|
+ <el-date-picker
|
|
|
+ style="width: 100%"
|
|
|
+ v-model="form.eventTime"
|
|
|
+ value-format="yyyy-MM-dd HH:mm:ss"
|
|
|
+ type="datetime"
|
|
|
+ placeholder="选择日期"
|
|
|
+ >
|
|
|
+ </el-date-picker>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item
|
|
|
+ label="事件发生的医院及科室"
|
|
|
+ label-width="110px"
|
|
|
+ prop="eventHospital"
|
|
|
+ :rules="{
|
|
|
+ required: true,
|
|
|
+ message: '输入事件发生的医院及科室',
|
|
|
+ trigger: 'change'
|
|
|
+ }"
|
|
|
+ >
|
|
|
+ <el-input
|
|
|
+ v-model="form.eventHospital"
|
|
|
+ type="textarea"
|
|
|
+ placeholder="请输入"
|
|
|
+ :autosize="{ minRows: 2, maxRows: 4}"
|
|
|
+ ></el-input>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item
|
|
|
+ label="事件详细描述"
|
|
|
+ label-width="110px"
|
|
|
+ prop="eventDesc"
|
|
|
+ >
|
|
|
+ <el-input
|
|
|
+ v-model="form.eventDesc"
|
|
|
+ type="textarea"
|
|
|
+ placeholder="请输入"
|
|
|
+ :autosize="{ minRows: 2, maxRows: 4}"
|
|
|
+ ></el-input>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item
|
|
|
+ label="图片上传"
|
|
|
+ label-width="110px"
|
|
|
+ prop="eventImage"
|
|
|
+ :rules="{
|
|
|
+ required: true,
|
|
|
+ message: '上传图片',
|
|
|
+ trigger: 'change'
|
|
|
+ }"
|
|
|
+ >
|
|
|
+ <el-upload
|
|
|
+ class="upload-demo"
|
|
|
+ action="#"
|
|
|
+ list-type="picture-card"
|
|
|
+ :http-request="handlRequest"
|
|
|
+ :before-remove="beforeRemove"
|
|
|
+ :on-remove="handleRemove"
|
|
|
+ :on-preview="handleItem"
|
|
|
+ multiple
|
|
|
+ :before-upload="beforeUpload"
|
|
|
+ :file-list="form.eventImage"
|
|
|
+ :show-file-list="true"
|
|
|
+ accept=".jpg, .jpeg, .png, .gif"
|
|
|
+ >
|
|
|
+ <i class="el-icon-plus"></i>
|
|
|
+ </el-upload>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item
|
|
|
+ label="其他意见"
|
|
|
+ label-width="110px"
|
|
|
+ prop="eventOpinion"
|
|
|
+ >
|
|
|
+ <el-input
|
|
|
+ v-model="form.eventOpinion"
|
|
|
+ type="textarea"
|
|
|
+ placeholder="请输入"
|
|
|
+ :autosize="{ minRows: 2, maxRows: 4}"
|
|
|
+ ></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <div slot="footer">
|
|
|
+ <el-button type="primary" size="small" @click="save">保存</el-button>
|
|
|
+ <el-button size="small" @click="handleClose">关闭</el-button>
|
|
|
+ </div>
|
|
|
+ </ele-modal>
|
|
|
+ <ele-modal
|
|
|
+ title="预览"
|
|
|
+ custom-class="ele-dialog-form long-dialog-form"
|
|
|
+ :visible.sync="previewVisible"
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ top="5vh"
|
|
|
+ :close-on-press-escape="false"
|
|
|
+ append-to-body
|
|
|
+ width="60%"
|
|
|
+ :maxable="true"
|
|
|
+ >
|
|
|
+ <el-card shadow="never" style="text-align: center;">
|
|
|
+ <img :src="currentImg.url" alt="" style="height: 300px;">
|
|
|
+ </el-card>
|
|
|
+ </ele-modal>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+<script>
|
|
|
+import upload from '@/components/uploadImg';
|
|
|
+import { uploadFile } from '@/api/system/file/index.js';
|
|
|
+import {
|
|
|
+ removeFile,
|
|
|
+ getFile
|
|
|
+ } from '@/api/system/file/index.js';
|
|
|
+export default {
|
|
|
+ components: {
|
|
|
+ upload
|
|
|
+ },
|
|
|
+ props: {
|
|
|
+ info: {
|
|
|
+ type: Object,
|
|
|
+ default: () => {}
|
|
|
+ },
|
|
|
+ generateForm: {
|
|
|
+ type: Object,
|
|
|
+ default: () => {}
|
|
|
+ },
|
|
|
+ id: {
|
|
|
+ type: String,
|
|
|
+ default: ''
|
|
|
+ },
|
|
|
+ view: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ info: {
|
|
|
+ handler(newVal, oldVal) {
|
|
|
+ console.log('info', newVal);
|
|
|
+ this.tableData = newVal[this.id] || [];
|
|
|
+ },
|
|
|
+ deep: true,
|
|
|
+ immediate: true
|
|
|
+ },
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ const formItem = {
|
|
|
+ eventType: '',
|
|
|
+ eventHospital: '',
|
|
|
+ eventDesc: '',
|
|
|
+ eventImage: [],
|
|
|
+ eventOpinion: '',
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ form: {
|
|
|
+ eventImage: []
|
|
|
+ },
|
|
|
+ formItem,
|
|
|
+ tableData: [],
|
|
|
+ visible: false,
|
|
|
+ currentItem: {},
|
|
|
+ currentIndex: null,
|
|
|
+ type: 'add',
|
|
|
+ limit: 9,
|
|
|
+ size: 20,
|
|
|
+ module: 'processSubmit',
|
|
|
+ currentImg: {},
|
|
|
+ previewVisible: false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ // console.log('info~~~', this.info);
|
|
|
+ // this.initForm();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ // 自定义上传方法,处理文件上传逻辑
|
|
|
+ handlRequest ({ file }) {
|
|
|
+ return this.beforeUpload(file);
|
|
|
+ },
|
|
|
+ // 上传前校验并处理上传
|
|
|
+ beforeUpload (file) {
|
|
|
+ // 1. 文件大小校验
|
|
|
+ if (file.size / 1024 / 1024 > this.size) {
|
|
|
+ this.$message.error(`大小不能超过 ${this.size}MB`);
|
|
|
+ return Promise.reject(new Error('文件大小超出限制'));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 文件数量校验
|
|
|
+ if (this.limit > 0 && this.form.eventImage.length >= this.limit) {
|
|
|
+ this.$message.error(`最多上传 ${this.limit}个文件`);
|
|
|
+ return Promise.reject(new Error('文件数量超出限制'));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 文件类型校验(虽然accept属性已限制,但这里再做一层校验确保安全性)
|
|
|
+ const isImage = /\.(jpg|jpeg|png|gif)$/i.test(file.name);
|
|
|
+ if (!isImage) {
|
|
|
+ this.$message.error('请上传图片格式的文件');
|
|
|
+ return Promise.reject(new Error('文件类型不是图片'));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 执行文件上传
|
|
|
+ return uploadFile({
|
|
|
+ module: this.module,
|
|
|
+ multiPartFile: file
|
|
|
+ }).then((res) => {
|
|
|
+ if (res.data) {
|
|
|
+ // 将上传成功的文件添加到表单中
|
|
|
+ const uploadedFile = {
|
|
|
+ ...file,
|
|
|
+ url: res.data.storePath,
|
|
|
+ ...res.data,
|
|
|
+ status: 'success' // 标记为成功状态
|
|
|
+ };
|
|
|
+
|
|
|
+ // 检查文件是否已存在,避免重复添加
|
|
|
+ const existingIndex = this.form.eventImage.findIndex(item => item.uid === file.uid);
|
|
|
+ if (existingIndex === -1) {
|
|
|
+ this.form.eventImage.push(uploadedFile);
|
|
|
+ } else {
|
|
|
+ this.form.eventImage.splice(existingIndex, 1, uploadedFile);
|
|
|
+ }
|
|
|
+
|
|
|
+ return res.data;
|
|
|
+ }
|
|
|
+ return Promise.reject(new Error('上传失败,未返回数据'));
|
|
|
+ }).catch(error => {
|
|
|
+ this.$message.error('文件上传失败');
|
|
|
+ return Promise.reject(error);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ beforeRemove (file) {
|
|
|
+ if (file.id) {
|
|
|
+ return removeFile({
|
|
|
+ fileId: file.id
|
|
|
+ }).then(() => {
|
|
|
+ return true;
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ handleRemove (file, fileList) {
|
|
|
+ this.form.eventImage = fileList;
|
|
|
+ },
|
|
|
+ handleItem(file){
|
|
|
+ console.log(file,'5555')
|
|
|
+ // getFile({ objectName: file.storePath }, file.name);
|
|
|
+ this.currentImg = file;
|
|
|
+ this.previewVisible = true;
|
|
|
+
|
|
|
+ },
|
|
|
+ async updateRowInfo() {
|
|
|
+ let data = await this.generateForm.getData(false);
|
|
|
+ this.generateForm.setData({
|
|
|
+ [this.id]: this.tableData
|
|
|
+ });
|
|
|
+ console.log('updateRowInfo', this.tableData, data);
|
|
|
+ },
|
|
|
+ validateForm() {
|
|
|
+ //开始表单校验
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ this.$refs.form.validate((valid) => {
|
|
|
+ if (!valid) {
|
|
|
+ reject(false);
|
|
|
+ } else {
|
|
|
+ resolve(true);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ addRow() {
|
|
|
+ this.type = 'add';
|
|
|
+ this.form = JSON.parse(JSON.stringify(this.formItem));
|
|
|
+ this.visible = true;
|
|
|
+
|
|
|
+ },
|
|
|
+ handleClose() {
|
|
|
+ this.visible = false;
|
|
|
+ },
|
|
|
+ editRow(row, index) {
|
|
|
+ this.type = 'edit';
|
|
|
+ console.log('编辑行', row, index);
|
|
|
+ this.currentItem = row;
|
|
|
+ this.currentIndex = index;
|
|
|
+ this.visible = true;
|
|
|
+ this.form = JSON.parse(JSON.stringify(row));
|
|
|
+ },
|
|
|
+ deleteRow(index) {
|
|
|
+ this.tableData.splice(index, 1);
|
|
|
+ this.updateRowInfo();
|
|
|
+ },
|
|
|
+ async save() {
|
|
|
+ try {
|
|
|
+ // 1. 先进行表单基本验证
|
|
|
+ await this.validateForm();
|
|
|
+
|
|
|
+ // 2. 额外验证图片上传是否有效
|
|
|
+ // if (!this.form.eventImage || this.form.eventImage.length === 0) {
|
|
|
+ // this.$message.error('请上传图片');
|
|
|
+ // return;
|
|
|
+ // }
|
|
|
+
|
|
|
+ // // 3. 检查是否有上传中的图片或上传失败的图片
|
|
|
+ // const hasInvalidFile = this.form.eventImage.some(file =>
|
|
|
+ // file.status === 'uploading' || file.status === 'fail'
|
|
|
+ // );
|
|
|
+
|
|
|
+ // if (hasInvalidFile) {
|
|
|
+ // this.$message.error('存在图片正在上传中或上传失败,请等待上传完成或重新上传');
|
|
|
+ // return;
|
|
|
+ // }
|
|
|
+
|
|
|
+ // console.log('表单验证通过,图片上传有效');
|
|
|
+
|
|
|
+ // 4. 深拷贝form对象,避免引用问题
|
|
|
+ const newForm = JSON.parse(JSON.stringify(this.form));
|
|
|
+
|
|
|
+ // 5. 过滤出有效的图片数据(只保留成功上传的图片)
|
|
|
+ newForm.eventImage = newForm.eventImage.filter(file =>
|
|
|
+ file.status === 'success' && file.url
|
|
|
+ );
|
|
|
+
|
|
|
+ console.log('newForm', newForm);
|
|
|
+
|
|
|
+ // 6. 更新表格数据
|
|
|
+ if(this.type === 'add') {
|
|
|
+ this.tableData.push(newForm);
|
|
|
+ } else {
|
|
|
+ this.tableData[this.currentIndex] = newForm;
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log('this.tableData', this.tableData);
|
|
|
+
|
|
|
+ // 7. 更新父组件数据
|
|
|
+ this.updateRowInfo();
|
|
|
+
|
|
|
+ // 8. 保存成功后关闭弹窗并重置表单
|
|
|
+ this.handleClose();
|
|
|
+
|
|
|
+ // 重置form
|
|
|
+ // this.form = {
|
|
|
+ // eventType: '',
|
|
|
+ // eventHospital: '',
|
|
|
+ // eventDesc: '',
|
|
|
+ // eventImage: [],
|
|
|
+ // eventOpinion: ''
|
|
|
+ // };
|
|
|
+ } catch (error) {
|
|
|
+ console.log('表单验证失败', error);
|
|
|
+ // this.$message.error('表单验证失败,请检查输入内容');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+<style scoped>
|
|
|
+.header {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+.blank_business_component {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 10px;
|
|
|
+}
|
|
|
+.label {
|
|
|
+ width: 80px;
|
|
|
+}
|
|
|
+.value {
|
|
|
+ flex: 1;
|
|
|
+ width: calc(100% - 80px);
|
|
|
+}
|
|
|
+:deep(.el-form-box .el-table .el-table__row .el-table__cell .cell) {
|
|
|
+ padding-left: 10px;
|
|
|
+ padding-right: 10px;
|
|
|
+}
|
|
|
+</style>
|