<template> 
 | 
  <vol-box :footer="false" v-model="model" :height="height" :width="width" :padding="0" :lazy="true" title="审核"> 
 | 
  
 | 
    <div class="audit-model-content" :style="{ height: height - 100 + 'px' }"> 
 | 
      <el-descriptions class="desc-top" :column="3" size="default" :border="true"> 
 | 
        <el-descriptions-item v-for="(item, index) in formData" :key="index"> 
 | 
          <template #label> 
 | 
            <div class="cell-item"> 
 | 
              {{ item.name }} 
 | 
            </div> 
 | 
          </template> 
 | 
          {{ item.value }} 
 | 
        </el-descriptions-item> 
 | 
      </el-descriptions> 
 | 
      <el-radio-group v-show="hasFlow" style="padding-left: 15px;" v-model="activeName" class="ml-4"> 
 | 
        <el-radio label="audit" size="large">审核</el-radio> 
 | 
        <el-radio label="log" size="large">审核记录</el-radio> 
 | 
      </el-radio-group> 
 | 
      <div v-show="activeName == 'audit' || !hasFlow" class="audit-content"> 
 | 
        <div class="fx-left" v-if="hasFlow"> 
 | 
          <div class="v-steps"> 
 | 
            <div v-for="(item, index) in workFlowSteps" :key="index"> 
 | 
              <div class="step-item" :class="{'step-item-ad':item.auditId||item.stepAttrType=='start'}" v-if="item.stepAttrType == 'start'"> 
 | 
                <div class="left-item"> 
 | 
                  <div>流程开始</div> 
 | 
                  <div class="left-date">{{ item.createDate }}</div> 
 | 
                </div> 
 | 
                <div class="right-item"> 
 | 
                  <div class="step-line"></div> 
 | 
                  <i class="step-circle"></i> 
 | 
                  <div class="step-title"> 
 | 
                    {{ item.stepName }} 
 | 
                  </div> 
 | 
                  <div class="step-text">发起人:{{ item.creator }}</div> 
 | 
                </div> 
 | 
              </div> 
 | 
              <div class="step-item" v-else-if="item.stepAttrType == 'end'"> 
 | 
                <div class="left-item"> 
 | 
                  <div>流程结束</div> 
 | 
                </div> 
 | 
                <div class="right-item"> 
 | 
                  <div class="step-line"></div> 
 | 
                  <i class="step-circle"></i> 
 | 
                  <div class="step-title"> 
 | 
                    {{ item.stepName }} 
 | 
                  </div> 
 | 
                </div> 
 | 
              </div> 
 | 
              <div v-else :class="{ 'step-current': item.isCurrent }" class="step-item"> 
 | 
                <div class="left-item"> 
 | 
                  <div>审批时间</div> 
 | 
                  <div class="left-date">{{ item.auditDate || '待审批' }}</div> 
 | 
                </div> 
 | 
                <div class="right-item"> 
 | 
                  <div class="step-line"></div> 
 | 
                  <i class="step-circle"></i> 
 | 
                  <div class="step-title"> 
 | 
                    {{ item.stepName }} 
 | 
                  </div> 
 | 
                  <div class="step-text">审批人:{{ item.auditor }}</div> 
 | 
                  <div class="step-text"> 
 | 
                    状 态: {{ getAuditStatus(item.auditStatus) }} 
 | 
                  </div> 
 | 
                  <div class="step-text">备 注: {{ item.remark || '-' }}</div> 
 | 
                </div> 
 | 
              </div> 
 | 
            </div> 
 | 
          </div> 
 | 
        </div> 
 | 
        <div class="fx-right" :style="{ width: !hasFlow ? '100%' : '400px' }" v-if="isCurrentUser || !hasFlow"> 
 | 
  
 | 
          <div v-if="!hasFlow"> 
 | 
            <el-alert :title="'当前选中【' + rowLen + '】条记录待审核..'" type="success" :closable="false" /> 
 | 
          </div> 
 | 
          <div class="rd"> 
 | 
            <span>审批:</span> 
 | 
            <el-radio-group style="margin-left:15px" v-model="auditParam.value"> 
 | 
              <el-radio v-for="item in auditParam.data" :key="item.value" :label="item.value"> 
 | 
                <span>{{ item.text }}</span> 
 | 
              </el-radio> 
 | 
            </el-radio-group> 
 | 
          </div> 
 | 
          <el-input style="padding-top: 10px;" v-model="auditParam.reason" type="textarea" 
 | 
            :autosize="{ minRows: 4, maxRows: 10 }" placeholder="请输入备注..."></el-input> 
 | 
          <div class="btn"> 
 | 
            <el-button type="primary" @click="auditClick" icon="Check">审批</el-button> 
 | 
          </div> 
 | 
        </div> 
 | 
      </div> 
 | 
      <div v-show="activeName == 'log'"> 
 | 
        <vol-table :tableData="tableData" :columns="columns" :height="height - 250" :pagination-hide="true" 
 | 
          :load-key="false" :text-inline="false" :ck="false"></vol-table> 
 | 
      </div> 
 | 
    </div> 
 | 
  </vol-box> 
 | 
</template> 
 | 
<script> 
 | 
import VolTable from '@/components/basic/VolTable.vue'; 
 | 
import VolBox from '@/components/basic/VolBox.vue'; 
 | 
import http from '@/../src/api/http.js'; 
 | 
import { defineComponent, ref, reactive, getCurrentInstance } from 'vue'; 
 | 
export default defineComponent({ 
 | 
  components: { 
 | 
    VolTable, 
 | 
    VolBox 
 | 
  }, 
 | 
  props: { 
 | 
    option: { //生成vue文件的table参数 
 | 
      type: Object, 
 | 
      default: { 
 | 
        key: '', 
 | 
        cnName: '', 
 | 
        name: '', 
 | 
        url: "" 
 | 
      } 
 | 
    } 
 | 
  }, 
 | 
  setup(props, { emit }) { 
 | 
    const height = ref(500); 
 | 
    const width = ref(820); 
 | 
    const model = ref(false) 
 | 
    const workFlowSteps = reactive([]); 
 | 
  
 | 
    const hasFlow = ref(false) 
 | 
    const formData = reactive([]); 
 | 
  
 | 
    const auditParam = reactive({ 
 | 
      //审核对象 
 | 
      rows: 0, //当前选中审核的行数 
 | 
      model: false, //审核弹出框 
 | 
      value: -1, //审核结果 
 | 
      reason: '', //审核原因 
 | 
      //审核选项(main.js里面可以添加其他选项) 
 | 
      data: [] 
 | 
    }) 
 | 
    const { proxy } = getCurrentInstance(); 
 | 
    auditParam.data = proxy.$global.audit.data; 
 | 
    const tableData = reactive([]); 
 | 
    const columns = reactive([ 
 | 
      { title: '节点', field: 'stepName', width: 100 }, 
 | 
      { title: '审批人', field: 'auditor', width: 80 }, 
 | 
      { title: '审批结果', field: 'auditStatus', width: 70, bind: { data: [] } }, 
 | 
      { title: '审批时间', field: 'auditDate', width: 145 }, 
 | 
      { title: '备注', field: 'remark', width: 120 } 
 | 
    ]); 
 | 
  
 | 
    const isCurrentUser = ref(null); 
 | 
    const activeName = ref('audit') 
 | 
  
 | 
    const auditDic = reactive([]); 
 | 
    const getAuditStatus = (key) => { 
 | 
      return (auditDic.find(x => { return x.key === key + '' }) || { value: key }).value; 
 | 
    } 
 | 
    const rowLen = ref(0) 
 | 
    let currentRows = [] 
 | 
    const getAuditInfo = (option) => { 
 | 
      const table = option.table; //props.option.url.replaceAll('/', ''); 
 | 
      const url = `api/Sys_WorkFlow/getSteps?tableName=${table}` 
 | 
      //  let ids = currentRows.map(x => { return x[props.option.key] }); 
 | 
      let ids = currentRows.map(x => { return x[option.key] }); 
 | 
      // ['498043c1-fbd0-4a35-a870-523823912a9b'] 
 | 
      http.post(url, ids, true).then(result => { 
 | 
        if (!result.status) { 
 | 
          proxy.$message.error(result.message); 
 | 
          return; 
 | 
        } 
 | 
  
 | 
        hasFlow.value = !!(result.list || []).length; 
 | 
        if (!hasFlow.value) { 
 | 
  
 | 
          let auditStatus = Object.keys(currentRows[0]).find(x => { return x.toLowerCase() === 'auditstatus' }); 
 | 
  
 | 
          let checkStatus = currentRows.every((x) => { 
 | 
            return proxy.$global.audit.status.some(c => { return c === x[auditStatus] || !x[auditStatus] }) 
 | 
          }); 
 | 
          if (!checkStatus) { 
 | 
            proxy.$message.error('只能选择待审批或审核中的数据'); 
 | 
            return; 
 | 
          } 
 | 
          rowLen.value = currentRows.length; 
 | 
          model.value = true; 
 | 
          width.value = 430; 
 | 
          height.value = 330; 
 | 
          isCurrentUser.value = true; 
 | 
          //没有审批流程的数据只显示 
 | 
          return; 
 | 
        } 
 | 
        model.value = true; 
 | 
        height.value = document.body.clientHeight * 0.95; 
 | 
        width.value = 820; 
 | 
        if (!auditDic.length) { 
 | 
          auditDic.push(...(result.auditDic || [])) 
 | 
          columns.forEach(item => { 
 | 
            if (item.field == 'auditStatus') { 
 | 
              item.bind.data = auditDic; 
 | 
            } 
 | 
          }) 
 | 
        } 
 | 
        isCurrentUser.value = result.list.some(x => { return x.isCurrentUser }) 
 | 
        workFlowSteps.length = 0; 
 | 
        workFlowSteps.push(...result.list); 
 | 
        tableData.length = 0; 
 | 
        tableData.push(...result.log) 
 | 
        formData.length = 0; 
 | 
        formData.push(...(result.form || [])) 
 | 
      }) 
 | 
    } 
 | 
    // 
 | 
  
 | 
    const auditClick = () => { 
 | 
      if (auditParam.value == -1) { 
 | 
        proxy.$message.error('请选择审批项'); 
 | 
        return; 
 | 
      } 
 | 
  
 | 
      if (!isFlow.value) { 
 | 
        emit("auditClick", auditParam, currentRows, (result) => { 
 | 
          if (result.status) { 
 | 
            model.value = false; 
 | 
            tableData.length = 0; 
 | 
          } 
 | 
        }); 
 | 
        return; 
 | 
      } 
 | 
      //我的流程中点击审批 
 | 
      //保存审核 
 | 
      let keys = currentRows.map(x => { return x[currentOption.key] }); 
 | 
      let url = `api/${currentOption.table}/audit?auditReason=${auditParam.reason}&auditStatus=${auditParam.value}` 
 | 
      http.post(url, keys, '审核中....').then((x) => { 
 | 
        if (!x.status) { 
 | 
          proxy.$message.error(x.message); 
 | 
          return; 
 | 
        } 
 | 
        model.value = false; 
 | 
        proxy.$parent.search() 
 | 
        proxy.$message.success(x.message) 
 | 
      }); 
 | 
    } 
 | 
    const isFlow = ref(false); 
 | 
    let currentOption = {}; 
 | 
    const open = (rows, flow) => { 
 | 
      isFlow.value = !!flow; 
 | 
      currentRows = rows; 
 | 
      activeName.value = 'audit' 
 | 
      auditParam.reason = ''; 
 | 
      auditParam.value = -1; 
 | 
  
 | 
      if (flow) { 
 | 
        currentOption = { 
 | 
          table: rows[0].WorkTable, 
 | 
          key: "WorkTableKey"// rows[0].WorkTableKey 
 | 
        } 
 | 
      } else { 
 | 
        currentOption = { 
 | 
          table: props.option.url.replaceAll('/', ''), 
 | 
          key: props.option.key 
 | 
        } 
 | 
      } 
 | 
      getAuditInfo(currentOption); 
 | 
  
 | 
    } 
 | 
  
 | 
    return { 
 | 
      columns, 
 | 
      height, 
 | 
      width, 
 | 
      model, 
 | 
      workFlowSteps, 
 | 
      getAuditInfo, 
 | 
      getAuditStatus, 
 | 
      activeName, 
 | 
      reactive, 
 | 
      tableData, 
 | 
      auditParam, 
 | 
      auditClick, 
 | 
      open, 
 | 
      isCurrentUser, 
 | 
      hasFlow, 
 | 
      rowLen, 
 | 
      formData, 
 | 
      isFlow 
 | 
    } 
 | 
  } 
 | 
}); 
 | 
</script> 
 | 
   
 | 
<style lang="less" scoped> 
 | 
.audit-model-content { 
 | 
  padding: 10px; 
 | 
} 
 | 
  
 | 
.step-item { 
 | 
  background: #fff; 
 | 
  display: flex; 
 | 
} 
 | 
  
 | 
.left-item { 
 | 
  min-width: 180px; 
 | 
  text-align: right; 
 | 
  padding-right: 25px; 
 | 
  padding-top: 8px; 
 | 
  
 | 
  .left-date { 
 | 
    font-size: 13px; 
 | 
    padding-top: 7px; 
 | 
    color: #6c6c6c; 
 | 
  } 
 | 
} 
 | 
  
 | 
.right-item { 
 | 
  cursor: pointer; 
 | 
  position: relative; 
 | 
  border-bottom: 1px solid #f3f3f3; 
 | 
  padding: 5px 0 5px 5px; 
 | 
} 
 | 
  
 | 
.left-item, 
 | 
.right-item { 
 | 
  padding-bottom: 10px; 
 | 
} 
 | 
  
 | 
.right-item:last-child { 
 | 
  border-bottom: 0; 
 | 
} 
 | 
  
 | 
.step-line { 
 | 
  top: 16px; 
 | 
  left: -10px; 
 | 
  width: 1px; 
 | 
  height: 100%; 
 | 
  position: absolute; 
 | 
  background-color: #ebedf0; 
 | 
} 
 | 
  
 | 
.step-circle { 
 | 
  position: absolute; 
 | 
  top: 17px; 
 | 
  left: -9px; 
 | 
  z-index: 2; 
 | 
  font-size: 12px; 
 | 
  line-height: 1; 
 | 
  transform: translate(-50%, -50%); 
 | 
  width: 7px; 
 | 
  height: 7px; 
 | 
  background-color: #a1a1a1; 
 | 
  border-radius: 50%; 
 | 
} 
 | 
  
 | 
.right-item::before { 
 | 
  content: ''; 
 | 
} 
 | 
  
 | 
.step-content { 
 | 
  padding-top: 2px; 
 | 
  font-size: 14px; 
 | 
  color: #828282; 
 | 
  line-height: 1.5; 
 | 
} 
 | 
  
 | 
.step-title { 
 | 
  font-weight: bold; 
 | 
  padding-top: 3px; 
 | 
} 
 | 
  
 | 
.step-text { 
 | 
  font-size: 13px; 
 | 
  color: #999999; 
 | 
  padding-top: 6px; 
 | 
} 
 | 
  
 | 
.step-current { 
 | 
  * { 
 | 
    color: #2f95ff !important; 
 | 
  } 
 | 
  
 | 
  .step-circle { 
 | 
    background: #2f95ff !important; 
 | 
  } 
 | 
  
 | 
  // border-radius: 5px; 
 | 
  // border: 1px solid #d6eaff; 
 | 
  font-size: 13px; 
 | 
  padding-top: 6px; 
 | 
  // background-color: #eff7ffd9; 
 | 
  color: black; 
 | 
} 
 | 
  
 | 
.audit-content { 
 | 
  // background: #f9f9f9; 
 | 
  padding: 10px; 
 | 
  border-radius: 4px; 
 | 
  display: flex; 
 | 
  
 | 
  .fx-left { 
 | 
    flex: 1; 
 | 
    width: 0; 
 | 
  
 | 
    .rd { 
 | 
      display: flex; 
 | 
      align-items: baseline; 
 | 
    } 
 | 
  } 
 | 
  
 | 
  .fx-right { 
 | 
    // width: 400px; 
 | 
  
 | 
    .btn { 
 | 
      margin-top: 10px; 
 | 
      text-align: center; 
 | 
    } 
 | 
  } 
 | 
  
 | 
} 
 | 
  
 | 
.cell-item { 
 | 
  font-weight: 500; 
 | 
} 
 | 
  
 | 
.desc-top { 
 | 
  padding: 5px 10px 0 10px; 
 | 
} 
 | 
.step-item-ad{ 
 | 
  *{ 
 | 
    color: #9f9898 !important; 
 | 
  } 
 | 
} 
 | 
</style> 
 |