shikeying
2023-05-08 83efa8f1ebd3ad80dfb5078a10caf9fcc4499dc8
src/views/etaa/question_bank/index.vue
@@ -1,253 +1,166 @@
<template>
  <div class="app-container">
  <div class="app-main info-main">
    <el-aside class="sidebar-box" style="padding: 0;">
      <div class="sidebar">
        <el-card class="box-card" shadow="never">
          <div slot="header" class="clearfix">
            <span>
              <svg-icon icon-class="nested" style="margin-top: -2px;" />题库分类
            </span>
            <el-button style="float: right; padding: 3px 0" type="text" @click="expandedAll">收起</el-button>
          </div>
          <el-input v-model="filterText" clearable placeholder="关键字过滤" />
          <el-tree ref="treeRef" :data="treeData" :default-expanded-keys="defaultExpandedKeys" :filter-node-method="filterNode" :props="defaultProps" highlight-current node-key="id" @node-click="handleNodeClick" />
        </el-card>
      </div>
    </el-aside>
    <el-row :gutter="10" class="mb8">
      <el-col :span="6" :xs="24">
        <div class="head-container">
          <el-tree
            :data="catalogListOptions"
            :props="defaultProps"
            :expand-on-click-node="false"
            :filter-node-method="filterNode"
            ref="tree"
            default-expand-all
            highlight-current
            @node-click="handleNodeClick"
          />
    <div class="base-container flex-1">
      <el-card shadow="never" class="box-card">
        <!--搜索条件-->
        <div class="filter-container">
          <el-form :inline="true" :model="filterForm" size="small">
            <el-form-item label="顶级单位">
              <el-select v-model="filterForm.orgId" placeholder="选择顶级单位" @change="search(1)">
                <el-option
                  v-for="org in this.rootOrgList" :key="org.id" :label="org.dept_name" :value="org.id"/>
              </el-select>
            </el-form-item>
            <el-form-item label="试题类型">
              <el-select v-model="filterForm.questionType" placeholder="试题类型">
                <el-option v-for="d in this.questionTypeList" :key="d.key" :label="d.value" :value="d.key"/>
              </el-select>
            </el-form-item>
            <el-form-item label="试题题目">
              <el-input v-model="filterForm.content" placeholder="试题内容" clearable/>
            </el-form-item>
            <el-form-item>
              <my-button-v2 site="filter" name="搜索" @click="search(1)" />
              <my-button-v2 site="filter" name="重置" @click="reset()" />
            </el-form-item>
          </el-form>
        </div>
      </el-col>
      <el-col :span="18" :xs="24">
        <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
          <el-form-item label="顶级单位" prop="orgId">
            <el-select v-model="queryParams.orgId" placeholder="选择顶级单位" @change="getList()">
              <el-option
                v-for="org in this.rootOrgList"
                :key="org.id"
                :label="org.dept_name"
                :value="org.id"
              />
            </el-select>
          </el-form-item>
      </el-card>
          <el-form-item label="试题类型" prop="questionType">
            <el-select v-model="queryParams.questionType" placeholder="试题类型">
              <el-option
                v-for="d in this.questionTypeList"
                :key="d.key"
                :label="d.value"
                :value="d.key"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="试题题目" prop="content">
            <el-input
              v-model="queryParams.content"
              placeholder="试题内容"
              clearable
              @keyup.enter.native="handleQuery"
            />
          </el-form-item>
<!--          <el-form-item label="专业分类" prop="majorCode">-->
<!--            <el-select v-model="queryParams.majorCode" placeholder="请选择专业分类" clearable>-->
<!--              <el-option-->
<!--                v-for="dict in dict.type.sys_job_status"-->
<!--                :key="dict.value"-->
<!--                :label="dict.label"-->
<!--                :value="dict.value"-->
<!--              />-->
<!--            </el-select>-->
<!--          </el-form-item>-->
          <el-form-item>
            <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
            <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
          </el-form-item>
        </el-form>
        <el-row :gutter="10" class="mb8">
          <el-col :span="1.5">
            <el-button
              type="primary"
              plain
              icon="el-icon-plus"
              size="mini"
              @click="handleAdd"
              v-hasPermi="['exam:online:add']"
            >添加</el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button
              type="danger"
              plain
              icon="el-icon-delete"
              size="mini"
              :disabled="multiple"
              @click="handleDelete"
              v-hasPermi="['exam:online:delBatch']"
            >删除</el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button
              type="warning"
              plain
              icon="el-icon-search"
              size="mini"
              @click="handleExport"
              v-hasPermi="['exam:online:exist']"
            >查重</el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button
              type="warning"
              plain
              icon="el-icon-upload2"
              size="mini"
              @click="handleExport"
              v-hasPermi="['exam:online:upload']"
            >导入</el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button
              type="info"
              plain
              icon="el-icon-download"
              size="mini"
              @click=""
              v-hasPermi="['exam:online:download']"
            >模板下载</el-button>
          </el-col>
          <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
        </el-row>
        <el-table v-loading="loading" :data="examList" @selection-change="handleSelectionChange">
          <el-table-column type="selection" width="55" align="left" />
          <el-table-column label="ID" align="left" prop="id" :show-overflow-tooltip="true" />
          <el-table-column label="归属" align="left" prop="parameter.orgName"/>
          <el-table-column label="大类" align="left" prop="parameter.rootCatalogName"/>
          <el-table-column label="子分类" align="left" prop="parameter.majorCatalogName"/>
          <el-table-column label="题目" align="left" prop="content" :show-overflow-tooltip="true" />
          <el-table-column label="试题类型" align="left" prop="parameter.questionTypeName"/>
          <el-table-column label="创建人" align="left" prop="createUserId" :show-overflow-tooltip="true" />
          <el-table-column label="创建时间" align="left" prop="parameter.createTimeName" />
          <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
            <template slot-scope="scope">
              <el-button
                size="mini"
                type="text"
                icon="el-icon-edit"
                @click="handleUpdate(scope.row)"
                v-hasPermi="['exam:online:edit']"
              >修改</el-button>
              <el-button
                size="mini"
                type="text"
                icon="el-icon-delete"
                @click="handleDelete(scope.row)"
                v-hasPermi="['exam:online:del']"
              >删除</el-button>
            </template>
          </el-table-column>
        </el-table>
        <pagination
          v-show="total>0"
          :total="total"
          :page.sync="queryParams.pageNum"
          :limit.sync="queryParams.pageSize"
          @pagination="getList"
        />
      </el-col>
    </el-row>
    <!-- 添加或修改定时任务对话框 -->
    <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
      <el-form ref="form" :model="form" :rules="rules" label-width="120px">
        <el-row>
          <el-col :span="24">
            <el-form-item label="所属分类" prop="majorId">
              <el-select v-model="form.majorId" placeholder="请选择所属分类">
                <el-option
                  v-for="dict in dict.type.sys_job_group"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="题目类型" prop="type">
              <el-select v-model="form.type" placeholder="请选择题目类型">
                <el-option
                  v-for="dict in dict.type.sys_job_group"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="题目" prop="content">
              <el-input v-model="form.content" placeholder="请输入题目"/>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>
    <!-- 试题库详细 -->
    <el-dialog title="试题库详细" :visible.sync="openView" width="700px" append-to-body>
      <el-form ref="form" :model="form" label-width="120px" size="mini">
        <el-row>
          <el-col :span="12">
            <el-form-item label="所属分类:">{{ form.id }}</el-form-item>
            <el-form-item label="题目类型:">{{ form.jobName }}</el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="题目:">{{ "" }}</el-form-item>
            <el-form-item label="答案:">{{ form.createTime }}</el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="openView = false">关 闭</el-button>
      </div>
    </el-dialog>
      <!--列表-->
      <my-table-v3 ref="myTable" :filter="filterForm" :table="table" />
    </div>
    <!--添加/编辑弹窗-->
    <add v-if="editSetting.show" :setting="editSetting" @search="search()" @close="editSetting.show=false"/>
    <!-- 导入窗口-->
    <my-import :import-setting="importSetting" :dialog-show="importSetting.dialogShow" :dialog-title="importSetting.dialogTitle"/>
  </div>
</template>
<script>
  // import { listJob, getJob, delJob, addJob, updateJob, runJob, changeJobStatus } from "@/api/monitor/job";
  import { listOrgRoot, listOrgRootTree } from '@/api/system/dept'
  import { listCatalogTreeList, listQuestion, listQuestionType } from '@/api/etaa/question_bank'
  import { getToken } from '@/utils/auth'
  import {listOrgRoot} from '@/api/system/dept'
  import {clear, listCatalogTreeList, listQuestionType} from '@/api/etaa/question_bank'
  import myTableV3 from '@/views/components/myTableV3';
  import myButtonV2 from '@/views/components/myButtonV2'
  import myImport from '@/views/components/myImport'
  import {isEmptyValue} from "@/utils/StringUtils";
  import add from './add'
  export default {
  // components: { Crontab },
    components: {myTableV3, myButtonV2, add, myImport},
  name: "questionBank",
  dicts: ['sys_job_status'],
  data() {
    return {
      // 日期范围
      dateRange: [],
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 表格数据
      examList: [],
      /** 树配置*/
      defaultExpandedKeys: [1], // 默认展开的key
      filterText: '',
      treeData: [],
      /** 分类树数据结构 */
      defaultProps: {
        children: "children",
        label: "label"
      },
      /** 搜索条件*/
      filterForm: {
        orgId: null,
        questionType: null,
        content: null
      },
      table: {
        // size: "small",
        autoLoad: false,
        showIndex: false, // 是否显示序号
        expand: false, // 是否显示详情数据
        checkBox: false, // 是否显示复选框
        url: globalConf.baseUrl + '/etaa/question_bank/list', // 请求地址
        // 工具条
        tools: {
          columnsCtrl: {// 列控制按钮
            show: true
          },
          generalExport: {// 通用导出按钮
            show: false
          },
          custom: [ // 自定义工具条按钮
            {
              name: '添加试题',
              // checkPermission: 'system:config:remove',
              // myType: 'danger',
              mySize: 'mini',
              click: ()=> {
                this.handleAdd();
              }
            },
            {
              name: '导入',
              click: ()=> {
                this.handleImport();
              }
            },
            {
              name: '清空题库',
              checkPermission: 'etaa:question_bank:clear',
              myType: 'info',
              mySize: 'mini',
              click: ()=> {
                this.handleClear();
              }
            }
          ]
        },
        columns: [
          { title: 'ID', field: 'id', align: 'left', width: 80 },
          { title: '归属', field: 'parameter.orgName', align: 'left', width: 130 },
          { title: '大类', field: 'parameter.rootCatalogName', align: 'left', width: 150 },
          { title: '子分类', field: 'parameter.majorCatalogName', align: 'left', width: 160},
          { title: '题目', field: 'content', align: 'left', width: 230 },
          { title: '题型', field: 'parameter.questionTypeName', align: 'left', width: 80 },
          { title: '创建人', field: 'createUserId', align: 'left', width: 80 },
          { title: '创建时间', field: 'parameter.createTimeName', align: 'left', width: 160 }
        ],
        // 操作信息
        operation: {
          show: true, // 显示操作列
          width: '100', // 列宽
          attr: [
            {
              title: '编辑',
              checkPermission: 'system:config:edit',
              events: row => {
                this.handleUpdate(row)
              }
            }
          ]
        },
        paging: {
          show: true, // 显示分页
          // 分页信息
          page: {
            small: false,
            pageNum: 1,
            pageSize: platformPageSize,
            total: 0
          }
        }
      },
      // 2022-12-30 根机构列表,个人只能列出自己所在根机构
      rootOrgList:[],
@@ -255,48 +168,81 @@
      selectedRootOrgId: undefined,
      // 试题类别列表,2023-03-11
      questionTypeList: [],
      // 2023-03-13 试题类别树数据选项
      catalogListOptions: undefined,
      /** 分类树数据结构 */
      defaultProps: {
        children: "children",
        label: "label"
      // 添加&编辑窗口
      editSetting: {
        id: null,
        title: '',
        show: false
      },
      // 弹出层标题
      title: "",
      // 是否显示弹出层
      open: false,
      // 是否显示详细弹出层
      openView: false,
      // 是否显示Cron表达式弹出层
      openCron: false,
      // 传入的表达式
      expression: "",
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        content: undefined,
        catalogId: undefined,
        orgId: undefined,
        questionType: undefined
      // 导入
      importSetting: {
        dialogTitle: '导入',
        dialogShow: false,
        fileSettings: {
          uploadUrl: globalConf.baseUrl + "/etaa/question_bank/select/import?Authorization=" + getToken(), // 上传地址
          accept: '.xlsx,.csv', // 格式
          type: 'text', // 回显形式
          loading: false // 导入效果
        },
        /* 模板下载 */
        templateSettings: {
          templateName: '题库导入模板.xlsx', // 名称
          templateUrl: globalConf.baseUrl + '/etaa/question_bank/select/downloadTemplate?Authorization=' + getToken() // 下载地址
        },
        onSuccess: null
      },
      // 表单参数
      form: {},
      // 表单校验
      rules: {
        content: [
          { required: true, message: "题目不能为空", trigger: "blur" }
        ]
      }
    };
  },
  created() {
    this.getRootOrgList();
    this.getQuestionTypeList();
  },
  methods: {
    // 树节点过滤
    filterNode(value, data) {
      if (!value) return true;
      console.log("value = " + value + ", data = " + data);
      return data.label.indexOf(value) !== -1;
    },
    // 树节点收起
    expandedAll() {
      const nodes = this.$refs.treeRef.store._getAllNodes()
      for (let i = 0; i < nodes.length; i++) {
        nodes[i].expanded = false
      }
      // 编辑页面
      // this.editSetting.orgId = null
      // this.editSetting.orgName = '无'
      this.reset()
    },
    // 重置
    reset() {
      this.filterForm = {
        orgId: this.selectedRootOrgId,
        questionType: null,
        content: null
      }
      this.search(1)
    },
    // 查询table列表
    search(pageNum) {
      if(isEmptyValue(this.filterForm.orgId)){
        return;
      } else {
        // console.log("-----------" + this.filterForm.orgId);
        if (pageNum != undefined) {
          this.$refs.myTable.search({ pageNum: pageNum })
        } else {
          this.$refs.myTable.search()
        }
      }
    },
    /** 获取试题类别集合 2023-03-11 */
    getQuestionTypeList(){
      listQuestionType().then(response => {
@@ -306,95 +252,33 @@
    },
    /** 获取顶级机构列表选择框 2022-12-30 */
    getRootOrgList(){
      this.loading = true;
      listOrgRoot().then(response => {
        this.rootOrgList = response.data;
        this.selectedRootOrgId = this.rootOrgList[0].id;
        this.queryParams.orgId = this.selectedRootOrgId;
        this.loading = false;
        this.filterForm.orgId = this.selectedRootOrgId;
      }).then(() => {
        this.listCatalogTree();
        this.getList();
        this.search(1);
      }).catch(function() {
        this.loading = false;
      });
    },
    // 试题类别树
    listCatalogTree(){
      listCatalogTreeList("question_root_catalog").then(response => {
        console.log(response.data);
        this.catalogListOptions = response.data;
        // console.log(response.data);
        this.treeData = response.data;
      });
    },
    /** 查询列表 */
    getList() {
      this.loading = true;
      listQuestion(this.queryParams).then(response => {
        this.examList = response.data;
        this.total = response.total;
        this.loading = false;
      });
    },
    // 筛选节点
    filterNode(value, data) {
      if (!value) return true;
      console.log("value = " + value + ", data = " + data);
      return data.label.indexOf(value) !== -1;
    },
    // 节点单击事件
    handleNodeClick(data) {
      this.queryParams.catalogId = data.id;
      this.handleQuery();
      // 保持已展开的菜单刷新后依旧展开
      this.defaultExpandedKeys = [data.id];
      this.filterForm.catalogId = data.id;
      this.search(1);
    },
    // 取消按钮
    cancel() {
      this.open = false;
      this.reset();
    },
    // 表单重置
    reset() {
      this.form = {
        id: undefined,
        content: undefined,
        concurrent: 1,
        status: "0"
      };
      this.dateRange = [];// 时间范围
      this.resetForm("form");
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      this.queryParams.orgId = this.selectedRootOrgId;
      this.queryParams.questionType = undefined;
      this.handleQuery();
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.id);
      this.single = selection.length != 1;
      this.multiple = !selection.length;
    },
    // 状态修改
    handleStatusChange(row) {
      let text = row.status === "0" ? "启用" : "停用";
      this.$modal.confirm('确认要"' + text + '""' + row.name + '"任务吗?').then(function() {
        return changeJobStatus(row.id, row.status);
      }).then(() => {
        this.$modal.msgSuccess(text + "成功");
      }).catch(function() {
        row.status = row.status === "0" ? "1" : "0";
      });
    },
    /** 任务详细信息 */
    handleView(row) {
      // getJob(row.id).then(response => {
@@ -404,10 +288,21 @@
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset();
      this.open = true;
      this.title = "添加试题库";
      if(isEmptyValue(this.selectedRootOrgId)){
        this.$message.warning("请先选择一个顶级机构");
        return;
      }
      if(isEmptyValue(this.filterForm.catalogId)){
        this.$message.warning("请先选择题库分类");
        return;
      }
      this.editSetting.id = null;
      this.editSetting.title = "添加试题";
      this.editSetting.catalogId = this.filterForm.catalogId;
      this.editSetting.orgId = this.selectedRootOrgId;
      this.editSetting.show = true;
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset();
@@ -418,6 +313,65 @@
        this.title = "修改试题库";
      });
    },
    handleClear(){
      this.$modal.confirm('要清空题库吗?通常只有测试阶段需要使用!').then(function() {
        return clear();
      }).then(() => {
        this.search(1);
        this.$modal.msgSuccess("操作成功");
      }).catch(() => {});
    },
    handleImport(){
      this.importSetting.dialogShow = true
      this.importSetting.onSuccess = (response, callBack) => {
        console.log(response);
        if(response.code != 1){
          this.$message.error('导入失败' || response.msg);
          callBack();
          return;
        }
        if(isEmptyValue(response.data)){
          // 没有返回错误记录文件
          this.$message.success("导入成功");
          this.search();
          callBack();
          return;
        }
        this.$confirm("请查看导入错误,文件:" + response.data, '导入完成', {
          confirmButtonText: '确定',
          type: 'warning'
        }).then(() => {
          this.search()
        });
        // user.importUser(response.data[0]).then(response => {
        //   if (response.code === 10000) {
        //     this.importSetting.dialogShow = false
        //     if (response.data.errorInfo.length === 0) {
        //       this.$message.success(response.data.info)
        //       this.search()
        //     } else {
        //       const errorInfoList = response.data.errorInfo
        //       var errorInfo = errorInfoList.join('')
        //       this.$confirm(errorInfo, '提示', {
        //         confirmButtonText: '确定',
        //         type: 'warning'
        //       }).then(() => {
        //         this.search()
        //       })
        //     }
        //   } else {
        //     this.$message.error('导入失败' || response.description)
        //     this.search()
        //   }
        //   callBack()
        // })
      }
    },
    /** 提交按钮 */
    submitForm: function() {
      this.$refs["form"].validate(valid => {
@@ -457,3 +411,14 @@
  }
};
</script>
<style scope lang="scss">
  .info-main{
    display:-webkit-box;
    display: -moz-box;
    display: -0-box;
    min-height: calc( 100vh - 50px);
  }
  .flex-1{
    flex:1;
  }
</style>