zxl
2 天以前 819d40eb1bec7acb2b3adaa4a9a3f8d8eeca1dcc
src/views/workbench.vue
@@ -19,6 +19,15 @@
          <span class="stat-number">{{ totalActiveTasks }}</span>
          <span class="stat-label">今日处理</span>
        </div>
        <div style="display: flex;align-items: center">
          <el-button size="mini" @click="handleAddReport()"
                     class="report-btn"
                     icon="el-icon-upload2">上报</el-button>
          <el-button size="mini" @click="handleViewReport()"
                     class="report-btn"
                     icon="el-icon-view">查看上报</el-button>
        </div>
      </div>
      <div class="user-profile">
<!--        <el-dropdown>-->
@@ -123,6 +132,17 @@
                </template>
              </el-table-column>
            </el-table>
          </div>
          <div class="pagination-container">
            <el-pagination
              @current-change="handleCurrentChange"
              :current-page="waitTaskQuery.currentPage"
              :page-size="waitTaskQuery.pageSize"
              layout="total, sizes, prev, pager, next, jumper"
              :total="waitTaskTotal"
            >
            </el-pagination>
          </div>
        </div>
@@ -233,16 +253,7 @@
              </el-table-column>
            </el-table>
          </div>
          <div class="pagination-container">
            <el-pagination
              @current-change="handleCurrentChange"
              :current-page="waitTaskQuery.currentPage"
              :page-size="waitTaskQuery.pageSize"
              layout="total, sizes, prev, pager, next, jumper"
              :total="waitTaskTotal"
            >
            </el-pagination>
          </div>
        </div>
      </div>
    </div>
@@ -300,6 +311,107 @@
        <el-button type="primary" @click="submitSaveSchedule">确定</el-button>
      </template>
    </el-dialog>
    <el-dialog
      :title="reportTitle"
      :visible.sync="reportDialogVisible"
      width="600px"
      @close="resetReportForm"
    >
      <el-form
        ref="reportFormRef"
        :model="reportForm"
        :rules="reportRules"
        label-width="90px"
      >
        <el-form-item label="选择项目" prop="projectId">
          <el-select
            v-model="reportForm.projectId"
            clearable
            placeholder="选择项目"
            style="width: 100%"
          >
            <el-option
              v-for="project in allProjects"
              :key="project.id"
              :label="project.name"
              :value="project.id"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="上报内容" prop="content">
          <el-input
            v-model="reportForm.content"
            type="textarea"
            placeholder="请输入上报内容"
            rows="4"
          ></el-input>
        </el-form-item>
        <el-form-item label="上传附件">
          <FileUpload v-model="reportForm.fileUrl" :isShowTip="true" />
        </el-form-item>
      </el-form>
      <template v-slot:footer>
        <el-button @click="reportDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitReport">确定</el-button>
      </template>
    </el-dialog>
    <el-dialog
      title="上报记录"
      :visible.sync="reportListDialogVisible"
      width="700px"
    >
      <div class="calendar-section">
        <el-calendar v-model="reportCalendarDate">
          <template
            slot="dateCell"
            slot-scope="{date, data}">
            <div class="calendar-day">
              {{ data.day.split('-').slice(2).join('-') }}
              <div v-if="getReportCount(date) > 0" class="schedule-count">
                {{ getReportCount(date) }}个上报
              </div>
            </div>
          </template>
        </el-calendar>
      </div>
      <div class="schedule-list-section">
        <div class="section-header">
          <h3>上报列表</h3>
          <div>
            <el-button type="text" icon="el-icon-refresh" @click="getReportList" :disabled="reportRefreshing">刷新</el-button>
          </div>
        </div>
        <div class="schedule-list">
          <el-table
            v-loading="reportLoading"
            :data="filteredReport"
            style="width: 100%"
            height="250">
            <el-table-column
              prop="time"
              label="时间"
             >
            </el-table-column>
            <el-table-column
              prop="title"
              label="事项"
             >
            </el-table-column>
            <el-table-column
              label="操作">
              <template slot-scope="scope">
                <el-button size="mini" @click="handleEditReport(scope.row)">查看</el-button>
                <el-button size="mini" @click="handleReturn(scope.row)" :disabled="scope.row.status !== 'PendingReview'">撤回</el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
      <template v-slot:footer>
        <el-button @click="reportListDialogVisible = false">关 闭</el-button>
      </template>
    </el-dialog>
  </div>
</template>
@@ -315,17 +427,27 @@
  del,
  countTodayTask,
} from "@/api/workbench/workbench"
import {getTaskIsAuditing} from "@/api/projectProcess/projectProcess";
import {getProjectSelectList} from "@/api/index";
import {addReport, reportByDate,delReport} from "@/api/report/report";
import { formatDateToFrontend,formatDate,formatCalendarDate,getDayStartAndEnd } from "@/utils/date.js"
export default {
  data() {
    return {
      diaLogTitle:"",
      reportTitle:"",
      allProjects:[],
      scheduleDialogVisible: false,
      reportLoading:false,
      reportCurrentPageNum:1,
      reportPageSize:5,
      reportTotal:5,
      reportDialogVisible: false,
      reportListDialogVisible: false,
      // 新增:新增日程表单数据(对应WorkStationSchedule实体)
      scheduleForm: {
        id:'',
@@ -333,6 +455,12 @@
        completedTime: '',
        projectId:''
      },
      reportForm: {
        id:'',
        projectId: '',
        content: '',
        fileUrl: []
      },
      // 新增:表单校验规则
      scheduleRules: {
@@ -347,6 +475,15 @@
          {required:true,message: '请选择项目', trigger: 'change'}
        ]
      },
      reportRules: {
        projectId: [
          { required: true, message: '请选择项目', trigger: 'change' }
        ],
        content: [
          { required: true, message: '请输入上报内容', trigger: 'blur' },
          { max: 500, message: '上报内容最多500个字符', trigger: 'blur' }
        ]
      },
      queryParams: {
        taskName: '',
        taskType: 'todo',
@@ -359,6 +496,7 @@
        processName: '' // 流程名称
      },
      waitTaskRefreshing:false,
      reportRefreshing:false,
      scheduleRefreshing:false,
      auditHistoryRefreshing:false,
      loading:false,
@@ -381,20 +519,14 @@
        avatar: 'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png',
        department: '项目部'
      },
      currentDate: this.formatDate(new Date()),
      currentDate: formatDate(new Date()),
      todayTasks: 0,
      todaySchedules: 0,
      totalActiveTasks: 0,
      activeProject: 'all',
      projects: [],
      tasks: [],
      logs: [
        { id: 1, time: '09:30', project: '射洪市国家储备林建设项目(一期)', action: '提交', detail: '提交了施工图纸审核申请' },
        { id: 2, time: '10:15', project: '射洪市白羽肉鸡产业建设项目', action: '更新', detail: '更新了材料采购清单' },
        { id: 3, time: '11:00', project: '遂宁市射洪2024—2027年度东北片区高标准农田建设项目', action: '完成', detail: '完成了电力设备测试' },
        { id: 4, time: '14:30', project: '射洪市现代种业示范基地建设项目', action: '创建', detail: '创建了新的安装计划' },
        { id: 5, time: '16:45', project: '射洪市沱牌镇综合水利设施建设项目', action: '审批', detail: '审批通过了安全方案' }
      ],
      logs: [],//日志数据对象
      achievements: {
        completedTasks: 0,
        avgDuration: 0,
@@ -402,13 +534,50 @@
        completedSchedules: 0
      },
      calendarDate: new Date(),
      schedules: []
      lastCalendarDate:new Date(),
      reportCalendarDate: new Date(),
      lastReportCalendarDate: new Date(),
      schedules: [],
      reports:[]
    }
  },
  watch:{
    calendarDate(newDate, oldDate) {
      // 排除「点击日期单元格」导致的变化(仅日期变,月份/年份不变)
      const isOnlyDayChange =
        newDate.getFullYear() === oldDate.getFullYear() &&
        newDate.getMonth() === oldDate.getMonth() &&
        newDate.getDate() !== oldDate.getDate();
      if (!isOnlyDayChange) {
        // 触发按钮点击逻辑(上月/下月/今日)
        this.getScheduleList();
        this.lastCalendarDate = new Date(newDate); // 更新记录的日期
      }
    },
    reportCalendarDate(newDate, oldDate) {
      // 排除「点击日期单元格」导致的变化(仅日期变,月份/年份不变)
      const isOnlyDayChange =
        newDate.getFullYear() === oldDate.getFullYear() &&
        newDate.getMonth() === oldDate.getMonth() &&
        newDate.getDate() !== oldDate.getDate();
      if (!isOnlyDayChange) {
        // 触发按钮点击逻辑(上月/下月/今日)
        this.getReportList();
        this.lastReportCalendarDate = new Date(newDate); // 更新记录的日期
      }
    },
  },
  computed: {
    // 计算获得指定日期数据
    filteredSchedules() {
      const selectedDate = this.formatCalendarDate(this.calendarDate);
      const selectedDate = formatCalendarDate(this.calendarDate);
      return this.schedules.filter(schedule => schedule.date === selectedDate);
    },
    filteredReport(){
      const selectDate = formatCalendarDate(this.reportCalendarDate);
      return this.reports.filter(report => report.date === selectDate);
    }
  },
  mounted() {
@@ -419,6 +588,33 @@
    this.getAuditHistoryPage();
  },
  methods: {
    handleReturn(row){
      delReport(row.id).then(res =>{
        if (res.code === 200){
          this.getReportList()
        }
      })
    },
    handleAddReport(){
      this.reportTitle="提交上报";
      this.resetReportForm();
      this.reportDialogVisible = true;
    },
    handleEditReport(row){
      this.reportTitle="编辑上报";
      this.resetReportForm();
      this.reportDialogVisible = true;
      this.reportForm.id = row.id;
      this.reportForm.projectId = row.projectId + ""; //先转为字符串类型 提交的时候转为数字
      this.reportForm.content = row.title;
      this.reportForm.fileUrl = row.fileUrl;
    },
    handleViewReport(){
      this.getReportList();
      this.reportListDialogVisible = true;
    },
    getAuditTypeText(auditType) {
      // 映射关系:后端值 → 前端汉字
      const typeMap = {
@@ -439,6 +635,7 @@
        }
      })
    },
    // 获得下拉项目数据
    initSelect(){
      getProjectSelectList().then(res =>{
        if (res.code === 200){
@@ -449,12 +646,34 @@
        }
      })
    },
    // 获得上报列表数据
    getReportList(){
      if (this.reportRefreshing){
        return
      }
      const form ={
        startTime: getDayStartAndEnd(this.reportCalendarDate).startTime,
        endTime: getDayStartAndEnd(this.reportCalendarDate).endTime,
        projectId:this.activeProject
      }
      this.reportLoading = true;
      this.reportRefreshing = true;
      // 后端接口获得数据
      reportByDate(form).then(res =>{
        this.reportRefreshing = false;
        this.reportLoading = false;
        if (res.code === 200){
          this.reports = res.data;
        }
      })
    },
    // 获得日程列表数据
    getScheduleList(){
      if (this.scheduleRefreshing){
        return
      }
      const form ={
        completedTime:this.formatDateToFrontend(this.calendarDate),
        completedTime:formatDateToFrontend(this.calendarDate),
        projectId:this.activeProject
      }
      this.scheduleLoading = true
@@ -467,17 +686,7 @@
        }
      })
    },
    formatDateToFrontend(date) {
      if (!date) return '';
      const d = new Date(date);
      const year = d.getFullYear();
      const month = (d.getMonth() + 1).toString().padStart(2, '0');
      const day = d.getDate().toString().padStart(2, '0');
      const hour = d.getHours().toString().padStart(2, '0');
      const minute = d.getMinutes().toString().padStart(2, '0');
      const second = d.getSeconds().toString().padStart(2, '0');
      return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
    },
    async submitSaveSchedule(){
      this.$refs.scheduleFormRef.validate((valid, fields) => {
        if (valid) {
@@ -485,7 +694,7 @@
          if (this.scheduleForm.id === null || this.scheduleForm.id ==='' || this.scheduleForm.id === undefined){
            const submitData = {
              content: this.scheduleForm.content,
              completedTime: this.formatDateToFrontend(this.scheduleForm.completedTime),
              completedTime: formatDateToFrontend(this.scheduleForm.completedTime),
              projectId:this.scheduleForm.projectId
            };
            this.$message.success('表单提交成功!');
@@ -501,7 +710,7 @@
            const submitData = {
              id:this.scheduleForm.id,
              content: this.scheduleForm.content,
              completedTime: this.formatDateToFrontend(this.scheduleForm.completedTime),
              completedTime: formatDateToFrontend(this.scheduleForm.completedTime),
              projectId:this.scheduleForm.projectId
            };
            this.$message.success('表单提交成功!');
@@ -551,6 +760,46 @@
        this.$refs.scheduleFormRef.resetFields();
      }
    },
    resetReportForm() {
      this.reportForm = {
        projectId: '',
        content: '',
        fileUrl: []
      };
      if (this.$refs.reportFormRef) {
        this.$refs.reportFormRef.resetFields();
      }
    },
    submitReport() {
      this.$refs.reportFormRef.validate(valid => {
        if (valid) {
          const matchItem = this.allProjects.find(item => item.id === this.reportForm.projectId);
          let files=[];
          this.reportForm.fileUrl.forEach(item =>{
            if (item.url !== null || itme.url !== '')
            files.push(item.url)
          })
          const submitData = {
            projectId: Number(this.reportForm.projectId),
            content: this.reportForm.content,
            projectName:matchItem.name,
            fileUrl: files
          };
          this.$message.success('上报内容已准备就绪');
          this.reportDialogVisible = false;
          addReport(submitData).then(res =>{
            if (res.code === 200){
              this.getReportList();
            }
          })
        } else {
          this.$message.error('请完善上报信息');
        }
      });
    },
    addProject(){
      this.$router.push({path: '/projectEngineering/project/ProjectDetails'});
    },
@@ -597,8 +846,8 @@
        this.loading = false;
        this.waitTaskRefreshing = false;
        if (res.code === 200){
          this.tasks = res.data.data;
          this.waitTaskTotal = res.data.total;
          this.tasks = res.data;
          this.waitTaskTotal = res.total;
        }
      })
@@ -656,18 +905,6 @@
    isProjectNameTooLong(name) {
      return name.length > 10;
    },
    formatDate(date) {
      const year = date.getFullYear();
      const month = date.getMonth() + 1;
      const day = date.getDate();
      return `${year}年${month}月${day}日`;
    },
    formatCalendarDate(date) {
      const year = date.getFullYear();
      const month = (date.getMonth() + 1).toString().padStart(2, '0');
      const day = date.getDate().toString().padStart(2, '0');
      return `${year}-${month}-${day}`;
    },
    handleProjectSelect(index) {
      this.activeProject = index;
      console.log(this.activeProject)
@@ -684,6 +921,14 @@
    },
    handleTaskEdit(row) {
      console.log(row)
      this.queryParams.projectId = row.checkPointInfo.id +"";
      this.queryParams.processDefId = row.checkPointInfo.processDefinitionId;
      this.queryParams.processInsId = row.checkPointInfo.processInstanceId;
      this.queryParams.deployId = row.checkPointInfo.deployId;
      this.queryParams.processName = row.checkPointInfo.processName;
      console.log(this.queryParams)
      if (row.taskType === '容缺') {
        this.$router.push({
          path: '/flowable/task/myProcess/send/index',
@@ -728,8 +973,15 @@
        })
      }
    },
    // 获得计数
    getReportCount(date){
      const dateStr = formatCalendarDate(date);
      return this.reports.filter(s => s.date === dateStr).length;
    },
    getScheduleCount(date) {
      const dateStr = this.formatCalendarDate(date);
      const dateStr = formatCalendarDate(date);
      return this.schedules.filter(s => s.date === dateStr).length;
    },
    handleDeleteSchedule(schedule) {
@@ -1009,4 +1261,34 @@
  padding: 0 !important;
  border: none !important;
}
.report-btn {
  background: linear-gradient(135deg, #409eff, #1e88e5) !important;
  border: none !important;
  border-radius: 20px !important;
  padding: 6px 16px !important;
  color: white !important;
  font-weight: 500 !important;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3) !important;
  transition: all 0.3s ease !important;
  height: 32px !important;
  margin-left: 10px;
}
.report-btn:hover {
  background: linear-gradient(135deg, #66b1ff, #409eff) !important;
  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.4) !important;
  transform: translateY(-1px);
}
.report-btn:active {
  background: linear-gradient(135deg, #1e88e5, #0d6efd) !important;
  box-shadow: 0 2px 6px rgba(64, 158, 255, 0.2) !important;
  transform: translateY(0);
}
.report-btn:disabled {
  background: #e0e0e0 !important;
  color: #999 !important;
  box-shadow: none !important;
  transform: none !important;
}
</style>