无人机管理后台前端(已迁走)
rain
2025-04-16 b858f5748f928027b621a27bb5d80538ccf6eb6f
工单权限设计
1 files modified
94 ■■■■■ changed files
src/views/tickets/ticket.vue 94 ●●●●● patch | view | raw | blame | history
src/views/tickets/ticket.vue
@@ -32,11 +32,12 @@
            @size-change="sizeChange" @current-change="handleCurrentChange" :table-loading="loading"
            @selection-change="handleSelectionChange" :permission="permissionList">
            <template #menu-left>
              <el-button v-if="(activeTab === 'all' || activeTab === 'myTickets') && permissionList.addBtn" type="primary" icon="el-icon-plus"
                @click="handleAdd">新建工单</el-button>
              <el-button v-if="(activeTab === 'all' || activeTab === 'myTickets') && permissionList.addBtn"
                type="primary" icon="el-icon-plus" @click="handleAdd">新建工单</el-button>
              <el-button v-if="activeTab === 'pending' && permissionList.reviewBtn" type="success" icon="el-icon-check"
                @click="openReviewDialog">批量审核</el-button>
              <el-button v-if="permissionList.exportBtn" type="success" plain icon="el-icon-download" @click="exportData">导出</el-button>
              <el-button v-if="permissionList.exportBtn" type="success" plain icon="el-icon-download"
                @click="exportData">导出</el-button>
            </template>
            <template #menu="{ row }">
              <template v-if="row.status === -1">
@@ -100,7 +101,7 @@
          <el-row :gutter="16">
            <el-col :span="12">
              <el-form-item label="关联算法" prop="algorithm">
                <el-select v-model="form.algorithm" placeholder="请选择关联算法" class="full-width">
                <el-select v-model="form.algorithm" multiple placeholder="请选择关联算法" class="full-width">
                  <el-option v-for="item in algorithms" :key="item.value" :label="item.label" :value="item.value" />
                </el-select>
              </el-form-item>
@@ -131,7 +132,8 @@
                <el-upload ref="upload" :action="'#'" :auto-upload="false" list-type="picture-card"
                  :on-change="handleFileChange" :on-remove="handleUploadRemove" :before-upload="beforeUpload"
                  :file-list="form.photos" :limit="1" accept="image/*" class="uploader">
                  <span style="font-size: 32px; display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;">+</span>
                  <span
                    style="font-size: 32px; display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;">+</span>
                </el-upload>
                <div class="upload-tip">支持jpg/png格式图片,单张不超过5MB</div>
              </el-form-item>
@@ -205,7 +207,7 @@
          <el-table-column>
            <template #default="{ row }">
              <!-- 修复工单名称可编辑 -->
              <template v-if="currentDetail.status === 0 && row.label1 === '工单名称'">
              <template v-if="currentDetail.status === 0 && row.label1 === '工单名称'&&hasProcessingBtnPermission()">
                <el-input v-model="currentDetail.orderName" placeholder="请输入工单名称" />
              </template>
              <!-- 修复任务接收单位为下拉框 -->
@@ -221,11 +223,11 @@
          <el-table-column>
            <template #default="{ row }">
              <!-- 修复工单内容可编辑 -->
              <template v-if="currentDetail.status === 0 && row.label2 === '工单内容'">
              <template v-if="currentDetail.status === 0 && row.label2 === '工单内容'&&hasProcessingBtnPermission()">
                <el-input type="textarea" v-model="currentDetail.content" placeholder="请输入工单内容" />
              </template>
              <!-- 修复工单类型为下拉框 -->
              <template v-else-if="currentDetail.status === 0 && row.label2 === '工单类型'">
              <template v-else-if="currentDetail.status === 0 && row.label2 === '工单类型'&&hasProcessingBtnPermission()">
                <el-select v-model="currentDetail.type" placeholder="请选择工单类型">
                  <el-option v-for="item in types" :key="item.value" :label="item.label" :value="item.value" />
                </el-select>
@@ -246,7 +248,7 @@
        <div v-if="[3, 4, 5].includes(currentDetail.status)" class="form-section">
          <div class="section-title">事件处理详情</div>
          <!-- 处理中状态显示输入框 -->
          <template v-if="currentDetail.status === 3">
          <template v-if="currentDetail.status === 3 && hasProcessedAndOverBtnPermission()">
            <el-input type="textarea" v-model="currentDetail.processingDetail" placeholder="请输入事件处理详情" :rows="4"
              style="width: 100%; margin-bottom: 10px;" />
          </template>
@@ -258,15 +260,16 @@
          </template>
        </div>
          <!-- 上传图片 -->
          <div v-if="[3, 4].includes(currentDetail.status)" class="form-section" style="margin-bottom: 32px;">
          <div class="section-title">上传图片</div>
          <el-upload ref="upload" :action="'#'" :auto-upload="false" list-type="picture-card"
        <!-- 上传图片 -->
        <div v-if="[3, 4].includes(currentDetail.status)" class="form-section" style="margin-bottom: 32px;">
          <div class="section-title"  v-if="hasProcessedAndOverBtnPermission()">上传图片</div>
          <el-upload v-if="hasProcessedAndOverBtnPermission()" ref="upload" :action="'#'" :auto-upload="false" list-type="picture-card"
            :on-change="handleFileChange" :on-remove="handleUploadRemove" :before-upload="beforeUpload" :file-list="[]"
            :limit="1" accept="image/*">
            <span style="font-size: 32px; display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;">+</span>
            <span
              style="font-size: 32px; display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;">+</span>
          </el-upload>
          <div class="el-upload__tip" style="margin-top: 12px;">
          <div class="el-upload__tip" style="margin-top: 12px;"  v-if="hasProcessedAndOverBtnPermission()">
            支持 jpg/png 格式图片,单张不超过 5MB
          </div>
        </div>
@@ -338,24 +341,23 @@
        <div class="dialog-footer">
          <template v-if="currentDetail.status === 2">
            <!-- 待审核 -->
            <el-button type="primary" @click="approveTicket">通过</el-button>
            <el-button type="danger" @click="rejectTicket">不通过</el-button>
            <el-button v-if="hasReviewBtnPermission()" type="primary" @click="approveTicket">通过</el-button>
            <el-button v-if="hasReviewBtnPermission()" type="danger" @click="rejectTicket">不通过</el-button>
            <el-button @click="detailVisible = false">取消</el-button>
          </template>
          <template v-else-if="currentDetail.status === 0">
            <el-button type="primary" @click="approveAndDispatch">通过并派发</el-button>
            <el-button type="danger" @click="rejectTicket">不通过</el-button>
            <el-button v-if="hasProcessingBtnPermission()" type="primary" @click="approveAndDispatch">通过并派发</el-button>
            <el-button v-if="hasProcessingBtnPermission()" type="danger" @click="rejectTicket">不通过</el-button>
            <el-button @click="detailVisible = false">取消</el-button>
          </template>
          <template v-else-if="currentDetail.status === 3">
          <template v-if="currentDetail.status === 3">
            <!-- 处理中 -->
            <el-button type="primary" @click="completeTicket">完成工单</el-button>
            <el-button v-if="hasProcessedAndOverBtnPermission()" type="primary" @click="completeTicket">完成工单</el-button>
            <el-button @click="detailVisible = false">取消</el-button>
          </template>
          <template v-else-if="currentDetail.status === 4">
            <!-- 已完成 -->
            <el-button type="primary" @click="finalizeTicket">完结工单</el-button>
            <el-button v-if="hasProcessedAndOverBtnPermission()" type="primary" @click="finalizeTicket">完结工单</el-button>
            <el-button @click="detailVisible = false">取消</el-button>
          </template>
          <template v-else-if="currentDetail.status === 5">
@@ -424,8 +426,8 @@
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="handleBatchApprove">通过</el-button>
          <el-button type="danger" @click="handleBatchReject">不通过</el-button>
          <el-button  type="primary" @click="handleBatchApprove">通过</el-button>
          <el-button  type="danger" @click="handleBatchReject">不通过</el-button>
          <el-button @click="cancleBatchReject">取消</el-button>
        </div>
      </template>
@@ -527,7 +529,7 @@
        type: '',
        department: '',
        handler: '',
        algorithm: '',
        algorithm: [], // 关联算法改为数组
        location: [],  // 将存储为[经度, 纬度, 地址]格式
        address: '',
        content: '',
@@ -596,8 +598,9 @@
    this.loadAMapScripts();
    this.fetchDropdownData();
    this.fetchTabCounts(); // 新增:初始化时获取 tab 数据
    console.log('permission', this.permission.tickets_tab_status);
    console.log('permission.tickets_processing_btn', this.permission.tickets_processing_btn);
    console.log('permission', this.permission.tickets_tab_pending);
    console.log('权限检查:', this.permission);
  },
  mounted() {
    this.fetchTableData();
@@ -740,10 +743,10 @@
    permissionList() {
      // 可根据实际后端权限key调整
      return {
        addBtn: this.validData(this.permission.tickets_add , false),
        delBtn: this.validData(this.permission.tickets_delete , false),
        exportBtn: this.validData(this.permission.tickets_export , false,),
        reviewBtn: this.validData(this.permission.tickets_review , false),
        addBtn: this.validData(this.permission.tickets_add, false),
        delBtn: this.validData(this.permission.tickets_delete, false),
        exportBtn: this.validData(this.permission.tickets_export, false,),
        reviewBtn: this.validData(this.permission.tickets_review, false),
      };
    },
  },
@@ -986,7 +989,7 @@
          latitude: String(this.form.location[1]),
          address: this.form.address,
          eventDictKey: this.form.type,
          aiType: this.form.algorithm,
          aiType: Array.isArray(this.form.algorithm) ? this.form.algorithm : [this.form.algorithm], // 传数组
          updateUser: this.form.handler,
          createDept: this.form.department,
          isDraft: 0
@@ -1031,7 +1034,7 @@
          latitude: this.form.location?.[1] ? String(this.form.location[1]) : undefined,
          address: this.form.address || undefined,
          eventDictKey: this.form.type || undefined,
          aiType: this.form.algorithm || undefined,
          aiType: Array.isArray(this.form.algorithm) ? this.form.algorithm : [this.form.algorithm], // 传数组
          updateUser: this.form.handler || undefined,
          createDept: this.form.department || undefined,
          isDraft: 1
@@ -1180,7 +1183,7 @@
        type: '',
        department: '',
        handler: '',
        algorithm: '',
        algorithm: [], // 关联算法改为数组
        location: [],  // 将存储为[经度, 纬度, 地址]格式
        address: '',
        content: '',
@@ -1555,6 +1558,21 @@
    async approveAndDispatch() {
      this.dispatchDialogVisible = true; // 打开派发对话框
    },
    hasProcessingBtnPermission() {
    // undefined 或 false 都返回 false,只有 true 返回 true
    console.log('权限检查:', this.permission);
    return this.permission && this.permission.tickets_processing_btn === true;
  },
    hasProcessedAndOverBtnPermission() {
      // undefined 或 false 都返回 false,只有 true 返回 true
      console.log('权限检查:', this.permission);
      return this.permission && this.permission.tickets_view_processedAndOver === true;
    },
    hasReviewBtnPermission() {
      // undefined 或 false 都返回 false,只有 true 返回 true
      console.log('权限检查:', this.permission);
      return this.permission && this.permission.tickets_review_btn === true;
    },
    async submitDispatch() {
      this.$refs.dispatchForm.validate(async (valid) => {
        if (valid) {
@@ -1654,13 +1672,19 @@
        映射后类型值: typeValue
      });
      let algorithmArr = [];
      if (Array.isArray(row.aiType)) {
        algorithmArr = row.aiType;
      } else if (typeof row.aiType === 'string' && row.aiType) {
        algorithmArr = row.aiType.split(',').map(i => i.trim());
      }
      this.form = {
        id: row.id,
        name: row.orderName,
        type: typeValue,
        department: deptId,
        handler: handlerId, // 使用映射后的处理人ID
        algorithm: row.aiType,
        algorithm: algorithmArr, // 回显为数组
        location: row.location,
        address: row.address,
        content: row.content,