Newer
Older
Nanping_sponge_GCYPG / src / views / preassess / examineManage / mark / index.vue
@liyingjing liyingjing on 25 Oct 2023 22 KB 工程预评估
<template>
  <div
    class="mark"
    v-loading.fullscreen.lock="loading"
    element-loading-text="加载中..."
    element-loading-background="rgba(0, 0, 0, 0.6)"
  >
    <el-page-header class="header" @back="goBack(route, '/preassess/examineManage')">
      <template #content>
        <span class="title">{{ name }}</span>
      </template>
    </el-page-header>
    <div class="body">
      <el-form ref="ruleForm" :model="form">
        <el-row :gutter="20">
          <el-col :span="5">
            <el-form-item label="评价规则:" prop="name">
              <el-input v-model="form.name" placeholder="请输入评价规则"/>
            </el-form-item>
          </el-col>
          <el-col :span="4">
            <el-form-item>
              <el-button type="primary" icon="Search" @click="search">
                查询</el-button>
              <el-button icon="Refresh" @click="resetQuery">重置</el-button>
            </el-form-item>
          </el-col>
          <el-col :span="15">
            <el-button
              type="primary"
              style="float: right;margin-left: 10px;"
              @click="save"
              :disabled="type === 'view'"
            >保存</el-button>
            <el-button
              type="primary"
              style="float: right;margin-left: 10px;"
              @click="enable"
              :disabled="type === 'view'"
            >{{ statusText }}</el-button>
            <el-button
              type="primary"
              icon="Plus"
              style="float: right"
              :disabled="type === 'view'"
              @click="openDialog({}, '0', 'add')"
            >
              新增评价类型</el-button>
            <upload
              class="upload"
              style="float: right"
              action="/prod-api/sponge/assessTargetConfigGradeItem/exportTargetConfigGradeItem"
              :data="{ targetId: markId }"
              :disabled="type === 'view'"
              @success="(data) => { uploadSuccess(data) }"
            >
              <el-button
                type="primary"
                icon="Upload"
                :disabled="type === 'view'"
              >
              导入</el-button>
            </upload>
          </el-col>
        </el-row>
      </el-form>
      <el-table
        ref="tableRef"
        :data="treeData"
        stripe
        :max-height="600"
        row-key="nodeCode"
        v-loading="tableLoading"
      >
        <el-table-column label="评价类型" prop="evaluationType" width="120px">
          <template #default="{ row }">
            <span>{{ row.level === '0' ? row.evaluationType : ''}}</span>
          </template>
        </el-table-column>
        <el-table-column label="评价内容" prop="evaluationContent" width="120px">
          <template #default="{ row }">
            <span>{{ row.level === '1' ? row.evaluationContent : ''}}</span>
          </template>
        </el-table-column>
        <el-table-column label="评价规则" prop="evaluationRule" width="300px">
          <template #default="{ row, $index }">
            <div v-html="formatSearch(row, $index, row.evaluationRule)" v-if="row.level === '2'"></div>
            <span v-else></span>
          </template>
        </el-table-column>
        <el-table-column label="分值" prop="score" show-overflow-tooltip width="80px">
          <template #default="{ row }">
            <span v-if="row.level === '0'">{{ row.evaluationTypeScore }}</span>
            <span v-else-if="row.level === '1'">{{ row.evaluationContentScore }}</span>
            <span v-else-if="row.level === '2'">{{ row.evaluationRuleScore }}</span>
          </template>
        </el-table-column>
        <el-table-column label="评价标准" align="center" prop="calculateStandard" show-overflow-tooltip width="80px">
          <template #default="{ row }">
            <span>{{ calculateStandardText.get(row.calculateStandard) }}</span>
          </template>
        </el-table-column>
        <el-table-column label="是否可操作" align="center" prop="canOperate" width="90px">
          <template #default="{ row }">
            <el-switch
              v-model="row.canOperate"
              :active-value="1"
              :inactive-value="0"
              :disabled="row.canOperateDisabled || type === 'view'"
              @change="(val) => { canOperateChange(row, val) }"
            />
          </template>
        </el-table-column>
        <el-table-column label="启用状态" align="center" prop="status" width="90px">
          <template #default="{ row }">
            <el-switch
              v-model="row.status"
              active-value="1"
              inactive-value="0"
              @change="(val) => { statusChange(row, val) }"
              :disabled="row.statusDisabled || type === 'view'"
            />
          </template>
        </el-table-column>
        <el-table-column label="启用时间" align="center" prop="enableTime" show-overflow-tooltip width="160px" />
        <el-table-column label="停用时间" align="center" prop="stopTime" show-overflow-tooltip width="160px" />
        <el-table-column label="修改人" align="center" prop="updateBy" show-overflow-tooltip />
        <el-table-column label="修改日期" align="center" prop="updateTime" show-overflow-tooltip width="160px" />
        <el-table-column label="排序" align="center" show-overflow-tooltip width="110px" fixed="right">
          <template #default="{ row }">
            <el-button
              type="primary"
              link
              :disabled="getSortIsDisabled(row, 'ascending') || type === 'view'"
              @click="ascHandle(row)"
            >升序</el-button>
            <el-button
              type="primary"
              link
              :disabled="getSortIsDisabled(row, 'descending') || type === 'view'"
              @click="descHandle(row)"
            >降序</el-button>
          </template>
        </el-table-column>
        <el-table-column
          label="操作"
          align="center"
          width="260"
          fixed="right"
        >
          <template #default="{ row }">
            <el-button
              type="primary"
              link v-if="row.level === '0'"
              @click="openDialog(row, row.level * 1 + 1 + '', 'add')"
              :disabled="type === 'view'"
            >新增评价内容</el-button>
            <el-button
              type="primary"
              link
              v-if="row.level === '1'"
              @click="openDialog(row, row.level * 1 + 1 + '', 'add')"
              :disabled="type === 'view'"
            >新增评价规则</el-button>
            <el-button
              type="primary"
              link
              v-if="row.level === '2'"
              @click="copy(row)"
              :disabled="type === 'view'"
            >复制</el-button>
            <el-button
              type="primary"
              link
              @click="openDialog(row, row.level, 'view')"
            >查看</el-button>
            <el-button
              type="primary"
              link
              @click="openDialog(row, row.level, 'edit')"
              :disabled="type === 'view'"
            >修改</el-button>
            <el-button
              type="danger"
              link
              @click="del(row)"
              :disabled="type === 'view'"
            >删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <el-dialog
      v-model="visible"
      :title="`${operateInfo.text}`"
      :close-on-click-modal="false"
      :width="operateInfo.width"
      :before-close="close"
      class="dialog"
    >
      <el-form
        ref="dialogFormRef"
        :model="dialogForm"
        :rules="dialogFormRules"
        v-if="operateInfo.level"
        :disabled="operateInfo.type === 'view' || type === 'view'"
      >
        <el-row v-if="operateInfo.level === '0'">
          <el-col :span="20" :offset="2">
            <el-form-item label="评价类型:" prop="evaluationType">
              <el-input v-model="dialogForm.evaluationType" placeholder="请输入评价类型"/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20" v-if="operateInfo.level === '1'">
          <el-col :span="12">
            <el-form-item label="评价内容:" prop="evaluationContent">
              <el-input v-model="dialogForm.evaluationContent" placeholder="请输入评价内容"/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="评价类型:" prop="evaluationType">
              <el-input v-model="dialogForm.evaluationType" :disabled="true"/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20" v-if="operateInfo.level === '2'">
          <el-col :span="12">
            <el-form-item label="评价规则:" prop="evaluationRule">
              <el-input v-model="dialogForm.evaluationRule" placeholder="请输入评价规则"/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="评价标准:" prop="calculateStandard">
              <el-select
                v-model="dialogForm.calculateStandard"
                placeholder="请选择评价标准"
                style="width: 100%"
              >
                <el-option label="达标" value="reach" />
                <el-option label="评级" value="rate" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="dialogForm.calculateStandard === 'reach'">
            <el-form-item label="分值:" prop="evaluationRuleScore">
              <el-input v-model="dialogForm.evaluationRuleScore" placeholder="请输入分值"/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="评价内容:" prop="evaluationContent">
              <el-input v-model="dialogForm.evaluationContent" :disabled="true" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="评价类型:" prop="evaluationType">
              <el-input v-model="dialogForm.evaluationType" :disabled="true" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <rate
        ref="rateRef"
        :type="operateInfo.type"
        :operateJson="dialogForm.operateJson"
        v-if="operateInfo.level && dialogForm.calculateStandard === 'rate'"
      />
      <template #footer v-if="operateInfo.type !== 'view'">
        <div class="dialog-footer">
          <el-button type="primary" @click="submit">保存</el-button>
          <el-button @click="close">取消</el-button>
        </div>
      </template>
    </el-dialog>

  </div>

</template>

<script setup>
import { ref, nextTick, onMounted, reactive } from 'vue'
import { v4 as uuidv4 } from 'uuid'
import useUserStore from "@/store/modules/user"
import {
  getAssessTargetConfigGradeItem,
  assessTargetConfigGradeItemBatchUpdate,
  assessTargetConfigOpen,
  assessTargetConfigClose
}
from '@/api/preassess/examineManage.js'
import { optTextMap } from '@/utils/map'
import { inheritAttr } from '@/utils/v3'
import { numberValidate } from '../validate'
import useTable from '../mixins'
import rate from './rate.vue'
import upload from '../upload.vue'
const route = useRoute();
const { proxy } = getCurrentInstance();

const { markId } = route.params

let { type, status, name, engineeringType } = route.query
const statusText = ref(status ==='1' ? '停用' : '启用')
const {
  form,
  treeData,
  visible,
  curRow,
  operateInfo,
  getTreeCurRow,
  search,
  resetQuery,
  goBack,
  close,
  statusChange,
  setStatusDisabled,
  canOperateChange,
  setCanOperateDisabled,
  getSortIsDisabled,
  copy,
  del,
  ascHandle,
  descHandle,
  formatSearch,
  computedScore,
  expand,
  checkData
} = useTable(proxy, uuidv4)

const dialogForm = reactive({
  evaluationType: '',
  evaluationContent: '',
  evaluationRule: '',
  evaluationRuleScore: '',
  calculateStandard: '',
  operateJson: ''
})

const loading = ref(false)
const tableLoading = ref(false)

const dialogFormRules = reactive({
  evaluationType: [
    { required: true, trigger: "blur", message: "评价类型不能为空" }
  ],
  evaluationContent: [
    { required: true, trigger: "blur", message: "评价内容不能为空" }
  ],
  evaluationRule: [
    { required: true, trigger: "blur", message: "评价规则不能为空" }
  ],
  calculateStandard: [
    { required: true, trigger: "blur", message: "评价标准不能为空" }
  ],
  evaluationRuleScore: [
    { required: true, trigger: "blur",  validator: numberValidate }
  ],
})

const calculateStandardText = new Map([
  ['acc', '累加'],
  ['reach', '达标'],
  ['rate', '评级']
])

const operateMap = new Map([
  ['0', { width: '24%', text: '评价类型' }],
  ['1', { width: '48%',text: '评价内容' }],
  ['2', { width: '48%',text: '评价规则' }],
])
const openDialog = (row, level, type) => {
  console.log(row)
  curRow.value = row
  operateInfo.level = level
  operateInfo.type = type
  operateInfo.text = optTextMap.get(type) + operateMap.get(level).text
  operateInfo.width = operateMap.get(level).width
  visible.value = true
  nextTick(() => {
    setDialogForm(row, level, type)
  })
}

const setDialogForm = (row, level, type) => {
  inheritAttr(row, dialogForm)
  switch (level) {
    case '1':
      dialogForm.evaluationType = row.evaluationType
      break;
    case '2':
      dialogForm.evaluationType = row.evaluationType
      dialogForm.evaluationContent = row.evaluationContent
    default:
      break;
  }
  if(type === 'add'){
    dialogForm.calculateStandard = ''
    dialogForm.operateJson = ''
  }
}

const submit = () => {
  console.log(operateInfo, dialogForm)
  proxy.$refs.dialogFormRef.validate((valid) => {
    if(valid){
      const treeDataCurRow = getTreeCurRow(treeData.value, curRow.value)
      const row = {
        assessTargetConfigId: markId,
        evaluationType: '',
        evaluationTypeScore: '',
        evaluationContent: '',
        evaluationContentScore: '',
        evaluationRule: '',
        evaluationRuleScore: '',
        calculateStandard: '',
        canOperate: '0',
        enableTime: '',
        stopTime: proxy.moment().format("YYYY-MM-DD HH:mm:ss"),
        updateBy: useUserStore().name,
        updateTime: proxy.moment().format("YYYY-MM-DD HH:mm:ss"),
        status: '0',
        parentNodeCode: '0',
        operateJson: ''
      }
      if(operateInfo.type === 'add'){
        row.nodeCode = uuidv4()
        row.level = operateInfo.level
        switch (operateInfo.level) {
          case '0':
            row.evaluationType = dialogForm.evaluationType
            // row.evaluationTypeScore = dialogForm.evaluationTypeScore
            row.calculateStandard = 'acc'
            row.statusDisabled = false
            treeData.value.unshift(row)
            row.sort = treeData.value.length
            break;
          case '1':
            row.evaluationType = dialogForm.evaluationType
            row.evaluationContent = dialogForm.evaluationContent
            // row.evaluationContentScore = dialogForm.evaluationContentScore
            row.calculateStandard = 'acc'
            row.parentNodeCode = curRow.value.nodeCode
            row.statusDisabled = curRow.value.status === '0'
            if(!treeDataCurRow.children) treeDataCurRow.children = []
            row.sort = treeDataCurRow.children.length + 1
            treeDataCurRow.children.unshift(row)
            break;
          case '2':
            if(dialogForm.calculateStandard === 'rate') {
              const list = proxy.$refs.rateRef.rateTableData
              if(!list?.length) return proxy.$modal.msgError('请至少添加一条评级规则')
              const scorelist = list.map(it => it.value * 1)
              row.evaluationRuleScore = Math.max(...scorelist) + ''
              row.operateJson = JSON.stringify(list)
            } else {
              row.operateJson = ''
              row.evaluationRuleScore = dialogForm.evaluationRuleScore
            }
            row.evaluationType = dialogForm.evaluationType
            row.evaluationContent = dialogForm.evaluationContent
            row.evaluationRule = dialogForm.evaluationRule
            row.calculateStandard = dialogForm.calculateStandard
            row.parentNodeCode = curRow.value.nodeCode
            row.statusDisabled = curRow.value.status === '0'
            if(!treeDataCurRow.children) treeDataCurRow.children = []
            row.sort = treeDataCurRow.children.length + 1
            treeDataCurRow.children.unshift(row)
            //计算分值
            computedScore(treeDataCurRow.nodeCode)
            break;
          default:
            break;
        }
        nextTick(() => {
          proxy.$refs.tableRef.toggleRowExpansion(treeDataCurRow, true)
        })
      } else if(operateInfo.type === 'edit'){
        switch (operateInfo.level) {
          case '0':
            treeDataCurRow.evaluationType = dialogForm.evaluationType
            if(treeDataCurRow?.children?.length){
              for (const item of treeDataCurRow.children) {
                item.evaluationType = treeDataCurRow.evaluationType
                if(item?.children?.length){
                  for (const it of item.children) {
                    it.evaluationType = treeDataCurRow.evaluationType
                  }
                }
              }
            }
            // treeDataCurRow.evaluationTypeScore = dialogForm.evaluationTypeScore
            break;
          case '1':
            treeDataCurRow.evaluationContent = dialogForm.evaluationContent
            if(treeDataCurRow?.children?.length){
              for (const item of treeDataCurRow.children) {
                item.evaluationContent = treeDataCurRow.evaluationContent
              }
            }
            // treeDataCurRow.evaluationContentScore = dialogForm.evaluationContentScore
            break;
          case '2':
            if(dialogForm.calculateStandard === 'rate') {
              const list = proxy.$refs.rateRef.rateTableData
              if(!list?.length) return proxy.$modal.msgError('请至少添加一条评级规则')
              const scorelist = list.map(it => it.value * 1)
              treeDataCurRow.evaluationRuleScore = Math.max(...scorelist) + ''
              treeDataCurRow.operateJson = JSON.stringify(list)
            } else {
              treeDataCurRow.operateJson = ''
              treeDataCurRow.evaluationRuleScore = dialogForm.evaluationRuleScore
            }
            treeDataCurRow.evaluationRule = dialogForm.evaluationRule
            treeDataCurRow.calculateStandard = dialogForm.calculateStandard
            //计算分值
            computedScore(treeDataCurRow.parentNodeCode)
            break;
          default:
            break;
        }
      }
      close()
    }
  })

}

const getTableData = async () => {
  tableLoading.value = true
  const res = await getAssessTargetConfigGradeItem(markId)
  tableLoading.value = false
  if(res?.code !== 200) return
  treeData.value = res?.data || []
  setFields(treeData.value, '0')
  setSort(treeData.value)
  setCanOperateDisabled(treeData.value)
  setStatusDisabled(treeData.value)
  nextTick(() => {
    expand()
  })
  console.log(treeData.value)
}

const setFields = (data, level) => {
  for (const item of data) {
    item.level = level
    switch (level) {
      case '0':
        item.sort = item.evaluationTypeRank
        break;
      case '1':
        item.sort = item.evaluationContentRank
        break;
      case '2':
        item.sort = item.evaluationRuleRank
        break;
      default:
        break;
    }
    if(item.children) {
      setFields(item.children, level * 1 + 1 + '')
    }
  }
}

const setSort = (data) => {
  data.sort((a, b) => {
    return b.sort - a.sort
  })
  for (const item of data) {
    if(item.children) {
      setSort(item.children)
    }
  }
}

const save = async () => {
  loading.value = true
  const params = JSON.parse(JSON.stringify(treeData.value))
  const flag = checkData(params)
  if(flag) return proxy.$modal.msgError('表格数据至少要填写到评价规则')
  setParams(params)
  console.log(params)
  const res = await assessTargetConfigGradeItemBatchUpdate(params)
  loading.value = false
  if(res?.code !== 200) return
  proxy.$modal.msgSuccess('操作成功!')
}

const setParams = (data) => {
  for (const item of data) {
    if(item.level === '0'){
      item.evaluationTypeRank = item.sort
    } else if(item.level === '1') {
      item.evaluationContentRank = item.sort
    } else if(item.level === '2') {
      item.evaluationRuleRank = item.sort
    }
    if(item.children) {
      setParams(item.children)
    }
  }
}

const enable = () => {
  proxy.$modal
  .confirm(`是否确认${statusText.value}?`)
  .then(async () => {
    let method = status === '1' ? assessTargetConfigClose : assessTargetConfigOpen
    const formData = new FormData()
    formData.append('id', markId)
    formData.append('engineeringType', engineeringType)
    formData.append('assessType', 'score')
    const res = await method(formData)
    if(res?.code !== 200) return
    proxy.$modal.msgSuccess('操作成功!')
    if(status === '1'){
      status = '0'
      statusText.value = '启用'
    } else {
      status = '1'
      statusText.value = '停用'
    }
  })
  .catch(() => {});
}

const uploadSuccess = (data) => {
  console.log(data)
  if(data) getTableData()
}

onMounted(() => {
  getTableData()
})
</script>

<style lang="scss" scoped>
.mark {
  padding: 10px;
  height: 92vh;
  overflow-y: hidden;
  .header {
    padding: 10px;
    border-radius: 4px;
    box-shadow: 0px 0px 12px rgba(0, 0, 0, .12);
    border: 1px solid #e4e7ed;
    margin-bottom: 10px;
    .title {
      font-size: 16px;
    }
    ::v-deep(.el-page-header__header) {
      .el-page-header__left {
        .el-page-header__back {
          .el-page-header__icon {
            font-size: 20px;
            font-weight: 700;
          }
          .el-page-header__title {
            font-size: 16px;
          }
        }
      }
    }
  }
  .body {
    height: calc(100% - 74px);
    overflow: auto;
    overflow-x: hidden;
    background-color: #fff;
    border-radius: 4px;
    box-shadow: 0px 0px 12px rgba(0, 0, 0, .12);
    border: 1px solid #e4e7ed;
    padding: 20px;
    ::v-deep(.el-table) {
      .light {
          background-color: rgb(252, 247, 0);
        }
    }
  }
}

::v-deep(.dialog) {
  .el-dialog__body {
    padding-bottom: 20px !important;
    .el-form {
      .el-form-item {
          .el-form-item__label {
            width: 80px;
            word-break: keep-all;
            white-space: nowrap;
          }
        }
      }
    }
  .el-dialog__footer {
    padding-top: 0 !important;
  }
}

</style>