suhp 1 месяц назад
Родитель
Сommit
18dc60a032

+ 5 - 5
public/config.js

@@ -2,9 +2,9 @@
 // 当前后端不在同一个服务器时,需要指定host地址
 // var host = 'http://10.7.13.26' // 以前
 // var host = 'http://116.204.117.33' //基本用这个
-var host = 'http://116.204.117.33' // 测试
+//var host = 'http://116.204.117.33' // 测试
 // var host = 'http://b463f4b7.natappfree.cc' // 后端服务海鹏
-//var host = 'http://5jrgep.ipx.wanziwk.cn' // 后端服务译文
+var host = 'http://5jrgep.ipx.wanziwk.cn' // 后端服务译文
 // var host = 'http://192.168.1.2' // 后端服务译文
 // var host = 'http://5jrgep.ipx.wanziwk.cn'
 // combine为true时五合一部署, 为false时分五个服务部署
@@ -23,13 +23,13 @@ var defaultModulePortMap = {
 window.getModuleRootUrl = function (module) {
   // 默认是全部服务合一的端口
   //var modulePort = '8089' // 以前
-  var modulePort = '9506' // 基本用这个
+  //var modulePort = '9506' // 基本用这个
   // var modulePort = '8088' //测试
-  // var modulePort = ''
+  var modulePort = ''
   if (!combine) {
     modulePort = defaultModulePortMap[module]
   }
-  return host + ':' + modulePort
+  return "http://5jrgep.ipx.wanziwk.cn";
   // return host + modulePort
 }
 window.context = {

+ 41 - 0
src/api/audit/collective.js

@@ -0,0 +1,41 @@
+import request from '@/utils/request'
+
+const url = window.context.form
+
+// 集体审议 - 获取记录列表
+export function getCollectiveDeliberateList(data) {
+  return request({
+    url: url + '/api/costProjectDeliberate/v1/pageList',
+    method: 'post',
+    data: data,
+  })
+}
+
+// 集体审议 - 新增
+// POST /api/costProjectDeliberate/v1/
+export function addCollectiveDeliberate(data) {
+  return request({
+    url: url + '/api/costProjectDeliberate/v1/',
+    method: 'post',
+    data: data,
+  })
+}
+
+// 集体审议 - 更新
+// PUT /api/costProjectDeliberate/v1/
+export function updateCollectiveDeliberate(data) {
+  return request({
+    url: url + '/api/costProjectDeliberate/v1/',
+    method: 'put',
+    data: data,
+  })
+}
+
+// 集体审议 - 删除
+// DELETE /api/costProjectDeliberate/v1/id
+export function deleteCollectiveDeliberate(id) {
+  return request({
+    url: url + '/api/costProjectDeliberate/v1/' + id,
+    method: 'delete',
+  })
+}

+ 981 - 17
src/views/costAudit/auditInfo/auditManage/collectiveMain.vue

@@ -4,12 +4,280 @@
       <div class="collective-header-left">
         <span>集体审议</span>
       </div>
+      <div class="collective-header-right">
+        <el-button type="primary" @click="handleAddRecord">新增记录</el-button>
+      </div>
+    </div>
+
+    <!-- 集体审议记录列表 -->
+    <div class="collective-list">
+      <el-table :data="recordList" style="width: 100%" border>
+        <el-table-column
+          type="index"
+          label="序号"
+          width="80"
+          header-align="center"
+          align="center"
+        />
+        <el-table-column
+          prop="reviewForm"
+          label="审议形式"
+          header-align="center"
+          align="center"
+        />
+        <el-table-column
+          prop="location"
+          label="地点"
+          header-align="center"
+          align="center"
+        />
+        <el-table-column
+          prop="hostName"
+          label="主持人"
+          header-align="center"
+          align="center"
+        />
+        <el-table-column
+          prop="reviewTime"
+          label="审议时间"
+          header-align="center"
+          align="center"
+        />
+        <el-table-column
+          prop="attachments"
+          label="附件"
+          width="80"
+          header-align="center"
+          align="center"
+        >
+          <template slot-scope="scope">
+            <el-tooltip
+              v-if="scope.row.attachments && scope.row.attachments.length > 0"
+              content="查看附件"
+              placement="top"
+            >
+              <el-button type="text" @click="handleViewAttachment(scope.row)">
+                <i class="el-icon-document"></i>
+              </el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="操作"
+          width="120"
+          header-align="center"
+          align="center"
+        >
+          <template slot-scope="scope">
+            <el-button type="text" @click="handleEditRecord(scope.row)">
+              修改
+            </el-button>
+            <el-button
+              type="text"
+              style="color: #f56c6c"
+              @click="handleDeleteRecord(scope.row)"
+            >
+              删除
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
     </div>
+
+    <!-- 新增/修改集体审议记录弹窗 -->
+    <el-dialog
+      :title="dialogTitle"
+      :visible.sync="showRecordDialog"
+      width="800px"
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+      :modal="false"
+      append-to-body
+    >
+      <div class="record-form">
+        <!-- 表单行:审议形式 -->
+        <div class="form-row">
+          <div class="form-item">
+            <label class="form-label required">审议形式</label>
+            <el-input
+              v-model="formData.reviewForm"
+              placeholder="请输入审议形式"
+              class="form-input"
+            ></el-input>
+          </div>
+        </div>
+
+        <!-- 表单行:时间 -->
+        <div class="form-row">
+          <div class="form-item">
+            <label class="form-label required">时间</label>
+            <div class="time-picker">
+              <el-date-picker
+                v-model="formData.startDate"
+                type="datetime"
+                placeholder="开始时间"
+                value-format="yyyy-MM-dd HH:mm"
+                :picker-options="startDateOptions"
+                class="date-picker"
+              ></el-date-picker>
+              <span class="date-range-separator">至</span>
+              <el-date-picker
+                v-model="formData.endDate"
+                type="datetime"
+                placeholder="结束时间"
+                value-format="yyyy-MM-dd HH:mm"
+                :picker-options="endDateOptions"
+                class="date-picker"
+              ></el-date-picker>
+            </div>
+          </div>
+        </div>
+
+        <!-- 表单行:地点 -->
+        <div class="form-row">
+          <div class="form-item">
+            <label class="form-label required">地点</label>
+            <el-input
+              v-model="formData.location"
+              placeholder="请输入地点"
+              class="form-input"
+            ></el-input>
+          </div>
+        </div>
+
+        <!-- 表单行:主持人和记录人 -->
+        <div class="form-row">
+          <div class="form-item form-item-compact">
+            <label class="form-label required">主持人</label>
+            <el-input
+              v-model="formData.hostId"
+              placeholder="请输入参加人员"
+              class="form-input"
+            ></el-input>
+            <label class="required">记录人</label>
+            <el-input
+              v-model="formData.recorderId"
+              placeholder="请输入参加人员"
+              class="form-input"
+            ></el-input>
+          </div>
+        </div>
+        <!-- 表单行:参加人员 -->
+        <div class="form-row">
+          <div class="form-item">
+            <label class="form-label required">参加人员</label>
+            <el-input
+              v-model="formData.participants"
+              placeholder="请输入参加人员"
+              class="form-input"
+            ></el-input>
+          </div>
+        </div>
+
+        <!-- 表单行:审议项目 -->
+        <div class="form-row">
+          <div class="form-item">
+            <label class="form-label">审议项目</label>
+            <el-input
+              v-model="formData.reviewProject"
+              placeholder="自动获取项目名称"
+              readonly
+              class="form-input readonly-input"
+            ></el-input>
+          </div>
+        </div>
+
+        <!-- 表单行:被审单位 -->
+        <div class="form-row">
+          <div class="form-item">
+            <label class="form-label">被审单位</label>
+            <el-input
+              v-model="formData.auditedUnit"
+              placeholder="自动获取被审单位名称"
+              readonly
+              class="form-input readonly-input"
+            ></el-input>
+          </div>
+        </div>
+
+        <!-- 表单行:审议情况 -->
+        <div class="form-row">
+          <div class="form-item">
+            <label class="form-label required">审议情况</label>
+            <el-input
+              v-model="formData.reviewSituation"
+              type="textarea"
+              :rows="5"
+              placeholder="填写"
+              class="form-textarea"
+            ></el-input>
+          </div>
+        </div>
+
+        <!-- 表单行:审议结论意见 -->
+        <div class="form-row">
+          <div class="form-item">
+            <label class="form-label required">审议结论意见</label>
+            <el-input
+              v-model="formData.reviewConclusion"
+              type="textarea"
+              :rows="5"
+              placeholder="填写"
+              class="form-textarea"
+            ></el-input>
+          </div>
+        </div>
+
+        <!-- 表单行:审议记录扫描件 -->
+        <div class="form-row">
+          <div class="form-item">
+            <label class="form-label required">审议记录扫描件</label>
+            <div class="upload-file">
+              <el-upload
+                class="upload-demo"
+                :auto-upload="false"
+                :on-change="handleFileChange"
+                :file-list="fileList"
+                accept=".doc,.docx,.pdf"
+              >
+                <el-button size="small" type="primary">选择文件</el-button>
+                <div slot="tip" class="el-upload__tip">
+                  只能上传doc、docx、pdf格式文件
+                </div>
+              </el-upload>
+              <div v-if="fileList.length > 0" class="file-name">
+                <a
+                  :href="fileList[0].url || '#'"
+                  target="_blank"
+                  class="file-link"
+                >
+                  {{ fileList[0].name }}
+                </a>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- 弹窗底部按钮 -->
+      <div slot="footer" class="dialog-footer">
+        <el-button class="cancel-btn" @click="handleCancel">取消</el-button>
+        <el-button type="primary" class="save-btn" @click="handleSave">
+          保存
+        </el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 <script>
+  import {
+    addCollectiveDeliberate,
+    updateCollectiveDeliberate,
+    deleteCollectiveDeliberate,
+    getCollectiveDeliberateList,
+  } from '@/api/audit/collective'
   export default {
-    name: 'Collective',
+    name: 'CollectiveMain',
     components: {},
     props: {
       visible: {
@@ -31,29 +299,725 @@
     },
     data() {
       return {
-        buttonData: [], //集体审议按钮数据
-        activeTab: 'submitData', // 默认选中集体审议标签页
+        // 记录列表数据
+        recordList: [],
         // 弹窗显示状态
-        showSupplementDialog: false,
-        showAbortDialog: false,
-        showRejectDialog: false,
-        // 弹窗数据
-        additionalParams: {},
-        // 当前操作按钮信息
-        currentButton: null,
+        showRecordDialog: false,
+        // 表单数据
+        formData: {
+          id: '',
+          reviewForm: '',
+          startDate: '',
+          endDate: '',
+          location: '',
+          hostId: '',
+          recorderId: '',
+          participants: '',
+          reviewProject: '',
+          auditedUnit: '',
+          reviewSituation: '',
+          reviewConclusion: '',
+          attachments: [],
+        },
+        // 文件列表
+        fileList: [],
+        // 当前操作类型:add/edit
+        operationType: 'add',
+        // 模拟用户列表数据
+        userList: [
+          { id: 1, name: '张三' },
+          { id: 2, name: '李四' },
+          { id: 3, name: '王五' },
+        ],
+        // 开始时间选择器选项
+        startDateOptions: {
+          disabledDate: (time) => {
+            if (this.formData.endDate) {
+              return time.getTime() > new Date(this.formData.endDate).getTime()
+            }
+            return false
+          },
+          disabledTime: (date) => {
+            if (this.formData.endDate) {
+              const endDate = new Date(this.formData.endDate)
+              if (
+                date.getFullYear() === endDate.getFullYear() &&
+                date.getMonth() === endDate.getMonth() &&
+                date.getDate() === endDate.getDate()
+              ) {
+                return {
+                  disabledHours: () => {
+                    const hours = []
+                    const endHour = endDate.getHours()
+                    for (let i = endHour + 1; i < 24; i++) {
+                      hours.push(i)
+                    }
+                    return hours
+                  },
+                  disabledMinutes: (selectedHour) => {
+                    if (selectedHour === endHour) {
+                      const minutes = []
+                      const endMinute = endDate.getMinutes()
+                      for (let i = endMinute + 1; i < 60; i++) {
+                        minutes.push(i)
+                      }
+                      return minutes
+                    }
+                    return []
+                  },
+                }
+              }
+            }
+            return {}
+          },
+        },
+        // 结束时间选择器选项
+        endDateOptions: {
+          disabledDate: (time) => {
+            if (this.formData.startDate) {
+              return (
+                time.getTime() < new Date(this.formData.startDate).getTime()
+              )
+            }
+            return time.getTime() < Date.now() - 8.64e7 // 禁止选择过去的日期
+          },
+          disabledTime: (date) => {
+            if (this.formData.startDate) {
+              const startDate = new Date(this.formData.startDate)
+              if (
+                date.getFullYear() === startDate.getFullYear() &&
+                date.getMonth() === startDate.getMonth() &&
+                date.getDate() === startDate.getDate()
+              ) {
+                return {
+                  disabledHours: () => {
+                    const hours = []
+                    const startHour = startDate.getHours()
+                    for (let i = 0; i < startHour; i++) {
+                      hours.push(i)
+                    }
+                    return hours
+                  },
+                  disabledMinutes: (selectedHour) => {
+                    if (selectedHour === startHour) {
+                      const minutes = []
+                      const startMinute = startDate.getMinutes()
+                      for (let i = 0; i < startMinute; i++) {
+                        minutes.push(i)
+                      }
+                      return minutes
+                    }
+                    return []
+                  },
+                }
+              }
+            }
+            return {}
+          },
+        },
       }
     },
     computed: {
       dialogTitle() {
-        // 根据节点类型设置标题
-        if (
-          this.currentNode === 'sdshenhe' &&
-          this.currentStatus === '审核中'
-        ) {
-          return '集体审议详情'
+        return this.operationType === 'add'
+          ? '新增集体审议记录'
+          : '修改集体审议记录'
+      },
+    },
+    mounted() {
+      this.loadRecordList()
+      this.getProjectInfo()
+    },
+    methods: {
+      // 加载记录列表
+      loadRecordList() {
+        // 调用API获取集体审议记录列表
+        const queryParams = {
+          projectId: this.id, // 使用props传入的id作为项目ID
+        }
+
+        getCollectiveDeliberateList(queryParams)
+          .then((res) => {
+            if (res && res.success) {
+              // 处理返回的数据,转换为前端表格需要的格式
+              this.recordList = res.data.map((item) => ({
+                id: item.id,
+                reviewForm: item.deliberationForm,
+                location: item.location,
+                hostName: item.hostPerson,
+                reviewTime: item.beginTime,
+                attachments: item.attachmentIds
+                  ? item.attachmentIds.split(',').map((attachmentId) => ({
+                      name: `附件_${attachmentId}`,
+                      url: '#', // 实际应该根据附件ID获取完整URL
+                    }))
+                  : [],
+              }))
+            } else {
+              this.$message.error(res.message || '获取记录列表失败')
+              // 如果API调用失败,使用模拟数据
+              this.recordList = []
+            }
+          })
+          .catch((error) => {
+            this.$message.error('获取记录列表失败:' + error.message)
+            // 错误时使用模拟数据
+            this.recordList = [
+              {
+                id: 1,
+                reviewForm: '现场会议',
+                location: '*****会议室',
+                hostName: '张****',
+                reviewTime: '2025-5-21 15:30',
+                attachments: [{ name: '审议记录.doc', url: '#' }],
+              },
+            ]
+          })
+      },
+
+      // 获取项目信息
+      getProjectInfo() {
+        // 模拟获取项目信息,实际应该调用API
+        this.formData.reviewProject = 'XX项目成本监审'
+        this.formData.auditedUnit = 'XX有限公司'
+      },
+
+      // 新增记录
+      handleAddRecord() {
+        this.operationType = 'add'
+        this.resetForm()
+        this.showRecordDialog = true
+      },
+
+      // 编辑记录
+      handleEditRecord(row) {
+        this.operationType = 'edit'
+        // 复制数据到表单
+        this.formData = {
+          id: row.id,
+          reviewForm: row.reviewForm,
+          location: row.location,
+          // 解析时间,实际应该根据API返回格式处理
+          startDate: row.reviewTime,
+          endDate: row.reviewTime,
+          hostId: this.userList.find((u) => u.name === row.hostName)?.id || '',
+          recorderId: '',
+          participants: '',
+          reviewProject: this.formData.reviewProject,
+          auditedUnit: this.formData.auditedUnit,
+          reviewSituation: '',
+          reviewConclusion: '',
+          attachments: row.attachments || [],
+        }
+        // 设置文件列表
+        this.fileList = row.attachments
+          ? row.attachments.map((file) => ({
+              name: file.name,
+              url: file.url,
+              uid: file.name,
+            }))
+          : []
+        this.showRecordDialog = true
+      },
+
+      // 删除记录
+      handleDeleteRecord(row) {
+        this.$confirm('确定要删除这条记录吗?', '删除确认', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning',
+        })
+          .then(() => {
+            // 调用API进行删除操作
+            deleteCollectiveDeliberate(row.id)
+              .then((res) => {
+                if (res && res.success) {
+                  this.$message.success('删除成功')
+                  this.loadRecordList() // 重新加载记录列表
+                } else {
+                  this.$message.error(res.message || '删除失败')
+                }
+              })
+              .catch((error) => {
+                this.$message.error('删除失败:' + error.message)
+              })
+          })
+          .catch(() => {
+            this.$message.info('已取消删除')
+          })
+      },
+
+      // 查看附件
+      handleViewAttachment(row) {
+        if (row.attachments && row.attachments.length > 0) {
+          // 打开附件链接
+          window.open(row.attachments[0].url, '_blank')
         }
-        return '集体审议详情'
+      },
+
+      // 文件改变处理
+      handleFileChange(file, fileList) {
+        this.fileList = fileList.slice(-1) // 只保留最新选择的文件
+      },
+
+      // 保存记录
+      handleSave() {
+        // 表单验证
+        if (!this.formData.reviewForm) {
+          this.$message.error('请输入审议形式')
+          return
+        }
+        if (!this.formData.location) {
+          this.$message.error('请输入地点')
+          return
+        }
+        if (!this.formData.startDate || !this.formData.endDate) {
+          this.$message.error('请选择时间')
+          return
+        }
+        if (!this.formData.hostId) {
+          this.$message.error('请选择主持人')
+          return
+        }
+        if (!this.formData.recorderId) {
+          this.$message.error('请选择记录人')
+          return
+        }
+
+        // 构建保存数据,按照接口要求的参数格式
+        const saveData = {
+          deliberationForm: this.formData.reviewForm,
+          beginTime: this.formData.startDate,
+          endTime: this.formData.endDate,
+          location: this.formData.location,
+          hostPerson:
+            this.userList.find((u) => u.id === this.formData.hostId)?.name ||
+            this.formData.hostId,
+          recordPerson:
+            this.userList.find((u) => u.id === this.formData.recorderId)
+              ?.name || this.formData.recorderId,
+          participants: this.formData.participants,
+          enterpriseId: '', // 需要从项目信息中获取监审单位id
+          deliberationContent: this.formData.reviewSituation,
+          conclusionOpinion: this.formData.reviewConclusion,
+          attachmentIds: this.fileList
+            .map((file) => file.uid || file.name)
+            .join(','), // 附件ID集合,多个用逗号分隔
+          remark: '', // 备注
+        }
+
+        // 调用API进行保存操作
+        if (this.operationType === 'add') {
+          // 添加新记录
+          addCollectiveDeliberate(saveData)
+            .then((res) => {
+              if (res && res.success) {
+                this.$message.success('新增成功')
+                this.loadRecordList() // 重新加载记录列表
+                this.showRecordDialog = false
+                this.resetForm()
+              } else {
+                this.$message.error(res.message || '新增失败')
+              }
+            })
+            .catch((error) => {
+              this.$message.error('新增失败:' + error.message)
+            })
+        } else {
+          // 更新现有记录
+          updateCollectiveDeliberate(saveData)
+            .then((res) => {
+              if (res && res.success) {
+                this.$message.success('修改成功')
+                this.loadRecordList() // 重新加载记录列表
+                this.showRecordDialog = false
+                this.resetForm()
+              } else {
+                this.$message.error(res.message || '修改失败')
+              }
+            })
+            .catch((error) => {
+              this.$message.error('修改失败:' + error.message)
+            })
+        }
+      },
+
+      // 取消操作
+      handleCancel() {
+        this.showRecordDialog = false
+        this.resetForm()
+      },
+
+      // 重置表单
+      resetForm() {
+        this.formData = {
+          id: '',
+          reviewForm: '',
+          startDate: '',
+          endDate: '',
+          location: '',
+          hostId: '',
+          recorderId: '',
+          participants: '',
+          reviewProject: this.formData.reviewProject, // 保持项目信息不变
+          auditedUnit: this.formData.auditedUnit, // 保持单位信息不变
+          reviewSituation: '',
+          reviewConclusion: '',
+          attachments: [],
+        }
+        this.fileList = []
       },
     },
   }
 </script>
+
+<style scoped>
+  /* 主容器样式 */
+  .collective {
+    padding: 10px;
+    font-family: 'Microsoft YaHei', sans-serif;
+  }
+
+  /* 页面头部样式 */
+  .collective-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 20px;
+    padding: 5px 0;
+  }
+
+  .collective-header-left span {
+    font-size: 18px;
+    font-weight: bold;
+    color: #333;
+  }
+
+  /* 列表容器样式 */
+  .collective-list {
+    margin-top: 15px;
+    border: 1px solid #ebeef5;
+    border-radius: 4px;
+    overflow: hidden;
+  }
+
+  /* 表单容器样式 */
+  .record-form {
+    padding: 20px 0 0;
+    background: #fff;
+  }
+
+  /* 表单行样式 */
+  .form-row {
+    display: flex;
+    margin-bottom: 20px;
+    align-items: flex-start;
+    min-height: 40px;
+  }
+
+  /* 表单项样式 */
+  .form-item {
+    flex: 1;
+    margin-right: 20px;
+    position: relative;
+    display: flex;
+    align-items: center;
+  }
+
+  /* 紧凑表单项目,减小间距 */
+  .form-item-compact {
+    margin-right: 20px; /* 减小右侧间距 */
+    width: calc(50% - 10px); /* 调整宽度以适应紧凑布局 */
+  }
+
+  .form-item:last-child {
+    margin-right: 0;
+  }
+
+  /* 表单标签样式 */
+  .form-label {
+    display: inline-block;
+    width: 120px;
+    text-align: right;
+    margin-right: 10px;
+    font-weight: 500;
+    color: #303133;
+    font-size: 14px;
+    line-height: 32px;
+    vertical-align: middle;
+    flex-shrink: 0;
+  }
+
+  /* 必填项标记 */
+  .form-label.required::before {
+    content: '*';
+    color: #f56c6c;
+    margin-right: 4px;
+  }
+
+  /* 表单输入框样式 */
+  .form-input {
+    flex: 1;
+    max-width: 600px;
+  }
+
+  /* 只读输入框样式 */
+  .readonly-input {
+    background-color: #f5f7fa;
+    color: #909399;
+    cursor: not-allowed;
+  }
+
+  /* 表单选择器样式 */
+  .form-select {
+    width: 200px;
+  }
+
+  /* 表单文本域样式 */
+  .form-textarea {
+    flex: 1;
+    max-width: 600px;
+  }
+
+  /* 时间选择器容器样式 */
+  .time-picker {
+    display: flex;
+    align-items: center;
+    flex-wrap: wrap;
+    flex: 1;
+    max-width: 400px;
+  }
+
+  /* 日期选择器样式 */
+  .date-picker {
+    width: 180px;
+  }
+
+  /* 日期范围分隔符 */
+  .date-range-separator {
+    margin: 0 10px;
+    color: #606266;
+    font-size: 14px;
+  }
+
+  /* 文件上传样式 */
+  .upload-file {
+    display: flex;
+    flex-direction: column;
+    flex: 1;
+    max-width: 400px;
+  }
+
+  /* 文件名称样式 */
+  .file-name {
+    margin-top: 10px;
+    padding: 5px 0;
+    word-break: break-all;
+  }
+
+  /* 文件链接样式 */
+  .file-link {
+    color: #409eff;
+    text-decoration: none;
+    font-size: 14px;
+  }
+
+  .file-link:hover {
+    text-decoration: underline;
+    color: #66b1ff;
+  }
+
+  /* 对话框样式优化 */
+  ::v-deep .el-dialog__header {
+    padding: 20px 25px 15px;
+    border-bottom: 1px solid #ebeef5;
+    background-color: #fafafa;
+  }
+
+  ::v-deep .el-dialog__title {
+    font-size: 16px;
+    font-weight: 500;
+    color: #303133;
+  }
+
+  ::v-deep .el-dialog__body {
+    padding: 25px;
+    max-height: 60vh;
+    overflow-y: auto;
+  }
+
+  ::v-deep .el-dialog__footer {
+    padding: 15px 25px 20px;
+    border-top: 1px solid #ebeef5;
+    margin-top: 10px;
+    background-color: #fafafa;
+  }
+
+  /* 按钮样式优化 */
+  .cancel-btn {
+    margin-right: 15px;
+  }
+
+  .save-btn {
+    min-width: 80px;
+  }
+
+  /* 表格样式优化 */
+  ::v-deep .el-table th {
+    background-color: #f5f7fa;
+    font-weight: 500;
+    color: #606266;
+    border-right: 1px solid #ebeef5;
+  }
+
+  ::v-deep .el-table td {
+    color: #606266;
+    border-right: 1px solid #ebeef5;
+  }
+
+  /* 输入框样式优化 */
+  ::v-deep .el-input__inner,
+  ::v-deep .el-select .el-input__inner,
+  ::v-deep .el-date-editor .el-input__inner {
+    border-radius: 4px;
+    transition: all 0.3s;
+    height: 32px;
+    line-height: 32px;
+  }
+
+  ::v-deep .el-input__inner:hover,
+  ::v-deep .el-select .el-input__inner:hover,
+  ::v-deep .el-date-editor .el-input__inner:hover {
+    border-color: #c0c4cc;
+  }
+
+  ::v-deep .el-input__inner:focus,
+  ::v-deep .el-select .el-input__inner:focus,
+  ::v-deep .el-date-editor .el-input__inner:focus {
+    border-color: #409eff;
+    outline: none;
+  }
+
+  /* 多行文本域样式 */
+  ::v-deep .el-textarea__inner {
+    resize: vertical;
+    border-radius: 4px;
+    min-height: 100px;
+    padding: 8px 12px;
+  }
+
+  /* 响应式设计 */
+  @media (max-width: 768px) {
+    .collective {
+      padding: 5px;
+    }
+
+    .collective-header {
+      flex-direction: column;
+      align-items: flex-start;
+      gap: 10px;
+    }
+
+    .form-row {
+      flex-direction: column;
+      margin-bottom: 15px;
+    }
+
+    .form-item {
+      margin-right: 0;
+      margin-bottom: 15px;
+      flex-direction: column;
+      align-items: flex-start;
+    }
+
+    .form-item:last-child {
+      margin-bottom: 0;
+    }
+
+    .form-label {
+      width: 100%;
+      text-align: left;
+      margin-bottom: 5px;
+      line-height: 1.5;
+    }
+
+    .form-input,
+    .form-select,
+    .form-textarea,
+    .time-picker,
+    .upload-file {
+      width: 100%;
+      max-width: none;
+    }
+
+    .date-picker {
+      width: 100%;
+    }
+
+    ::v-deep .el-dialog {
+      width: 95% !important;
+      margin: 5% auto;
+      max-width: 600px;
+    }
+
+    ::v-deep .el-dialog__header,
+    ::v-deep .el-dialog__body,
+    ::v-deep .el-dialog__footer {
+      padding: 15px;
+    }
+
+    ::v-deep .el-dialog__body {
+      max-height: 70vh;
+    }
+
+    .time-picker {
+      flex-direction: column;
+      align-items: stretch;
+      gap: 10px;
+    }
+
+    .date-range-separator {
+      display: none;
+    }
+
+    .dialog-footer {
+      text-align: center;
+    }
+
+    .cancel-btn,
+    .save-btn {
+      margin: 0 5px;
+    }
+  }
+
+  /* 打印样式 */
+  @media print {
+    .collective {
+      padding: 0;
+    }
+
+    .collective-header-right {
+      display: none;
+    }
+
+    ::v-deep .el-button {
+      display: none;
+    }
+
+    ::v-deep .el-dialog {
+      box-shadow: none !important;
+      margin: 0 !important;
+      width: 100% !important;
+    }
+
+    ::v-deep .el-dialog__header,
+    ::v-deep .el-dialog__footer {
+      display: none;
+    }
+
+    ::v-deep .el-dialog__body {
+      padding: 0;
+      overflow: visible;
+    }
+  }
+</style>

+ 263 - 16
src/views/costAudit/auditInfo/auditManage/conclusionMain.vue

@@ -1,15 +1,98 @@
 <template>
-  <div class="collective">
-    <div class="collective-header">
-      <div class="collective-header-left">
+  <div class="conclusion-container">
+    <div class="conclusion-header">
+      <div class="conclusion-header-left">
         <span>出具结论</span>
       </div>
     </div>
+
+    <div class="conclusion-content">
+      <!-- 保存按钮 -->
+      <div class="conclusion-actions">
+        <el-button type="primary" class="save-btn" @click="handleSave">
+          保存
+        </el-button>
+      </div>
+
+      <!-- 结论表单 -->
+      <div class="conclusion-form">
+        <!-- 定价成本构成 -->
+        <div class="form-row">
+          <div class="form-label">定价成本构成</div>
+          <div class="form-control-wrapper">
+            <el-input
+              v-model="formData.costComposition"
+              type="textarea"
+              placeholder="填写(非必填)"
+              class="form-textarea"
+              rows="4"
+            ></el-input>
+          </div>
+        </div>
+
+        <!-- 审核的内容和方法 -->
+        <div class="form-row">
+          <div class="form-label">审核的内容和方法</div>
+          <div class="form-control-wrapper">
+            <el-input
+              v-model="formData.auditContent"
+              type="textarea"
+              placeholder="填写(非必填)"
+              class="form-textarea"
+              rows="4"
+            ></el-input>
+          </div>
+        </div>
+
+        <!-- 成本费用项目核增(减)情况及理由 -->
+        <div class="form-row">
+          <div class="form-label">成本费用项目核增(减)情况及理由</div>
+          <div class="form-control-wrapper">
+            <el-input
+              v-model="formData.costAdjustment"
+              type="textarea"
+              placeholder="填写(非必填)"
+              class="form-textarea"
+              rows="4"
+            ></el-input>
+          </div>
+        </div>
+
+        <!-- 成本监审结论(带黄色边框) -->
+        <div class="form-row">
+          <div class="form-label">成本监审结论</div>
+          <div class="form-control-wrapper">
+            <el-input
+              v-model="formData.auditConclusion"
+              type="textarea"
+              placeholder="填写(非必填)"
+              class="form-textarea highlight-textarea"
+              rows="4"
+            ></el-input>
+          </div>
+        </div>
+
+        <!-- 其他需要说明的事项 -->
+        <div class="form-row">
+          <div class="form-label">其他需要说明的事项</div>
+          <div class="form-control-wrapper">
+            <el-input
+              v-model="formData.otherNotes"
+              type="textarea"
+              placeholder="填写(非必填)"
+              class="form-textarea"
+              rows="4"
+            ></el-input>
+          </div>
+        </div>
+      </div>
+    </div>
   </div>
 </template>
+
 <script>
   export default {
-    name: 'Collective',
+    name: 'ConclusionMain',
     components: {},
     props: {
       visible: {
@@ -31,16 +114,18 @@
     },
     data() {
       return {
-        buttonData: [], //集体审议按钮数据
-        activeTab: 'submitData', // 默认选中集体审议标签页
-        // 弹窗显示状态
-        showSupplementDialog: false,
-        showAbortDialog: false,
-        showRejectDialog: false,
-        // 弹窗数据
-        additionalParams: {},
-        // 当前操作按钮信息
-        currentButton: null,
+        // 表单数据
+        formData: {
+          costComposition: '', // 定价成本构成
+          auditContent: '', // 审核的内容和方法
+          costAdjustment: '', // 成本费用项目核增(减)情况及理由
+          auditConclusion: '', // 成本监审结论
+          otherNotes: '', // 其他需要说明的事项
+        },
+        // 表单验证规则
+        formRules: {
+          // 虽然设计图显示为非必填,但可以根据实际业务需求添加验证规则
+        },
       }
     },
     computed: {
@@ -50,10 +135,172 @@
           this.currentNode === 'sdshenhe' &&
           this.currentStatus === '审核中'
         ) {
-          return '集体审议详情'
+          return '出具结论详情'
+        }
+        return '出具结论'
+      },
+    },
+    mounted() {
+      // 组件挂载时,如果有id则加载数据
+      if (this.id) {
+        this.loadConclusionData()
+      }
+    },
+    methods: {
+      // 加载结论数据
+      async loadConclusionData() {
+        try {
+          // 这里应该调用实际的API获取数据
+          // const { data } = await getConclusionData(this.id)
+          // this.formData = data
+
+          // 模拟数据加载
+          console.log('加载结论数据,ID:', this.id)
+        } catch (error) {
+          this.$message.error('加载结论数据失败')
+          console.error('加载结论数据失败:', error)
+        }
+      },
+
+      // 保存结论
+      async handleSave() {
+        try {
+          // 这里应该调用实际的API保存数据
+          // const params = { ...this.formData }
+          // if (this.id) {
+          //   params.id = this.id
+          //   await updateConclusion(params)
+          // } else {
+          //   await createConclusion(params)
+          // }
+
+          this.$message.success('保存成功')
+          console.log('保存结论数据:', this.formData)
+
+          // 如果需要,保存成功后可以触发父组件的事件
+          this.$emit('saved', this.formData)
+        } catch (error) {
+          this.$message.error('保存失败')
+          console.error('保存结论数据失败:', error)
         }
-        return '集体审议详情'
       },
     },
   }
 </script>
+
+<style scoped>
+  .conclusion-container {
+    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
+      'Helvetica Neue', Arial, sans-serif;
+    padding: 20px;
+    background: #fff;
+  }
+
+  .conclusion-header {
+    margin-bottom: 20px;
+  }
+
+  .conclusion-header-left {
+    font-size: 16px;
+    font-weight: 500;
+    color: #303133;
+  }
+
+  .conclusion-actions {
+    margin-bottom: 20px;
+  }
+
+  .save-btn {
+    background-color: #1890ff;
+    border-color: #1890ff;
+  }
+
+  .save-btn:hover {
+    background-color: #40a9ff;
+    border-color: #40a9ff;
+  }
+
+  .conclusion-form {
+    border: 1px solid #e6e6e6;
+  }
+
+  .form-row {
+    display: flex;
+    border-bottom: 1px solid #e6e6e6;
+  }
+
+  .form-row:last-child {
+    border-bottom: none;
+  }
+
+  .form-label {
+    width: 200px;
+    padding: 12px 16px;
+    background-color: #fafafa;
+    border-right: 1px solid #e6e6e6;
+    font-size: 14px;
+    color: #303133;
+    display: flex;
+    align-items: center;
+  }
+
+  .form-control-wrapper {
+    flex: 1;
+    padding: 8px 16px;
+    background-color: #fff;
+  }
+
+  .form-textarea {
+    width: 100%;
+    min-height: 100px;
+    resize: vertical;
+    border: 1px solid #dcdfe6;
+    border-radius: 4px;
+    padding: 8px 12px;
+    font-size: 14px;
+    color: #303133;
+    transition: border-color 0.2s;
+  }
+
+  .form-textarea:focus {
+    outline: none;
+    border-color: #40a9ff;
+  }
+
+  .form-textarea::placeholder {
+    color: #c0c4cc;
+  }
+
+  /* 高亮文本区域(成本监审结论) */
+  .highlight-textarea {
+    border-color: #faad14;
+    background-color: #fff9e6;
+  }
+
+  .highlight-textarea:focus {
+    border-color: #faad14;
+    box-shadow: 0 0 0 2px rgba(250, 173, 20, 0.2);
+  }
+
+  /* 响应式设计 */
+  @media (max-width: 768px) {
+    .conclusion-container {
+      padding: 10px;
+    }
+
+    .form-row {
+      flex-direction: column;
+    }
+
+    .form-label {
+      width: 100%;
+      border-right: none;
+      border-bottom: 1px solid #e6e6e6;
+      background-color: #fafafa;
+    }
+
+    .form-control-wrapper {
+      width: 100%;
+    }
+  }
+</style>

+ 3 - 3
src/views/costAudit/auditInfo/auditManage/mainDetails.vue

@@ -51,9 +51,9 @@
   </div>
 </template>
 <script>
-  import auditDocumentsMain from './auditDocumentsMain.vue'
-  import collectiveMain from './collectiveMain.vue'
-  import conclusionMain from './conclusionMain.vue'
+  import auditDocumentsMain from './auditDocumentsMain'
+  import collectiveMain from './collectiveMain'
+  import conclusionMain from './conclusionMain'
   import {
     getDataPreliminaryReviewButton,
     doProcessBtn,