Newer
Older
KaiFengPC / src / views / preassess / examineManage / mark / index.vue
@zhangdeliang zhangdeliang on 23 May 21 KB 初始化项目
<template>
  <div class="mark" v-loading.fullscreen.lock="loading" element-loading-text="加载中..." element-loading-background="rgba(0, 0, 0, 0.6)">
    <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" :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="评价标准" prop="calculateStandard" show-overflow-tooltip width="80px">
          <template #default="{ row }">
            <span>{{ calculateStandardText.get(row.calculateStandard) }}</span>
          </template>
        </el-table-column>
        <el-table-column label="是否可操作" 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="启用状态" 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="启用时间" prop="enableTime" show-overflow-tooltip width="160px" />
        <el-table-column label="停用时间" prop="stopTime" show-overflow-tooltip width="160px" />
        <el-table-column label="修改人" prop="updateBy" show-overflow-tooltip />
        <el-table-column label="修改日期" prop="updateTime" show-overflow-tooltip width="160px" />
        <el-table-column label="排序" show-overflow-tooltip width="110px">
          <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="操作" width="260">
          <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 { proxy } = getCurrentInstance();

const props = defineProps({
  editObj: {
    type: Object,
    default: {},
  },
});
let { type, status, engineeringType, markId } = props.editObj;
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, 0.12);
    border: 1px solid #e4e7ed;
    margin-bottom: 10px;
    .title {
      font-size: 16px;
    }
    :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, 0.12);
    border: 1px solid #e4e7ed;
    padding: 20px;
    :deep(.el-table) {
      .light {
        background-color: rgb(252, 247, 0);
      }
    }
  }
}

: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>