123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659 |
- <template>
- <div class="content add-paper-select">
- <div>
- <LinkTitlesCustom
- :current-paths="['题库管理 ', '卷库管理', '抽题模板管理']"
- />
- </div>
- <div class="box-body">
- <div class="top">
- <div class="flex items-center">
- <p>课程名称:{{ $route.query.courseName }}</p>
- <p style="margin-left: 100px">
- 课程代码:{{ $route.query.courseNo }}
- </p>
- </div>
- <div>
- <el-button type="primary" size="small" @click="save">保存</el-button>
- <el-button type="primary" size="small" plain @click="back"
- >返回</el-button
- >
- </div>
- </div>
- <div class="form">
- <el-form
- ref="form"
- :rules="rules"
- :model="form"
- label-position="left"
- label-width="120px"
- >
- <el-form-item label="组卷模板名称:" prop="name">
- <el-input v-model="form.name" style="width: 300px"></el-input>
- </el-form-item>
- <el-form-item label="选择组卷模式:" required>
- <el-radio-group
- v-model="form.paperStructType"
- @change="paperStructTypeChange"
- >
- <el-radio label="EXACT">精确结构</el-radio>
- <el-radio label="BLUEPRINT">蓝图结构</el-radio>
- </el-radio-group>
- </el-form-item>
- <el-form-item label="选择组卷结构:" prop="paperStructId">
- <el-select v-model="form.paperStructId">
- <el-option
- v-for="item in options1"
- :key="item.id"
- :label="item.name"
- :value="item.id"
- ></el-option>
- </el-select>
- <p style="display: inline-block; margin-left: 40px">
- 难度:<span style="color: #409eff; font-weight: bold">{{
- difficultyDegree
- }}</span>
- </p>
- </el-form-item>
- <el-table
- v-loading="tableLoading1"
- :data="tableData1"
- border
- style="margin-top: 10px; margin-bottom: 20px; width: 700px"
- >
- <el-table-column
- v-for="(item, index) in tableColumns1"
- :key="index"
- :label="item.label"
- :prop="item.prop"
- :min-width="item.minWidth"
- >
- <template slot-scope="scope">
- <span
- v-if="
- !['hardInfo', 'mediumInfo', 'easyInfo'].includes(item.prop)
- "
- >{{ scope.row[item.prop] }}</span
- >
- <span v-else>{{ scope.row[item.prop]?.count }}</span>
- </template>
- </el-table-column>
- </el-table>
- <div class="flex" style="margin-top: 30px">
- <div style="width: 40%">
- <el-form-item label="选择题源范围:" style="margin-bottom: 0">
- <el-select
- v-model="form.paperType"
- placeholder="题源选择"
- style="width: 120px"
- @change="changePaperType"
- >
- <el-option label="题库来源" value="IMPORT"></el-option>
- <el-option label="卷库来源" value="GENERATE"></el-option>
- </el-select>
- <span
- v-if="checked && !tempPapers.length"
- class="red"
- style="font-size: 12px; font-weight: bold; margin-left: 10px"
- >请选择数据</span
- >
- </el-form-item>
- <el-table
- ref="table2"
- v-loading="tableLoading2"
- :data="tableData2"
- border
- @selection-change="handleSelectionChange"
- >
- <el-table-column
- type="selection"
- width="55"
- :selectable="canSelect"
- >
- </el-table-column>
- <el-table-column
- v-for="(item, index) in tableColumns2"
- :key="index"
- :label="item.label"
- :prop="item.prop"
- :width="item.width"
- >
- </el-table-column>
- </el-table>
- <div class="page pull-right">
- <el-pagination
- :current-page="curSelect"
- :page-size="pageSize"
- layout="total, prev, pager, next, jumper"
- :total="totalSelect"
- @current-change="selectCurrentChange"
- >
- </el-pagination>
- </div>
- <div style="clear: both; margin-top: 5px"></div>
- <el-form
- :inline="true"
- label-position="right"
- label-width="100px"
- >
- <el-form-item label="选中列表" class="form-item"></el-form-item>
- </el-form>
- <el-table :data="tempPapers" border>
- <el-table-column label="名称" width="200">
- <template slot-scope="scope">
- <div>
- <span>{{ scope.row.name }}</span>
- </div>
- </template>
- </el-table-column>
- <el-table-column label="操作">
- <template slot-scope="scope">
- <div>
- <el-button
- type="danger"
- size="mini"
- @click="removeSelected(scope.row.id)"
- >移除</el-button
- >
- </div>
- </template>
- </el-table-column>
- </el-table>
- </div>
- <div style="width: 60%; padding-left: 20px">
- <div style="color: #606266; font-size: 14px; line-height: 32px">
- <span>选中范围预览:</span>
- <span
- v-if="hasError"
- class="red"
- style="font-size: 12px; font-weight: bold"
- >不满足最低要求</span
- >
- </div>
- <el-table
- v-loading="tableLoading3"
- :data="tableData3"
- border
- style="margin-top: 8px"
- >
- <el-table-column
- v-for="(item, index) in tableColumns3"
- :key="index"
- :label="item.label"
- :prop="item.prop"
- >
- <template slot-scope="scope">
- <div
- v-if="
- ['hardInfo', 'mediumInfo', 'easyInfo'].includes(
- item.prop
- )
- "
- >
- <el-tooltip
- v-if="!scope.row[item.prop].valid"
- effect="dark"
- :content="scope.row[item.prop].invalidMsg"
- placement="top"
- >
- <span class="red">{{
- scope.row[item.prop]?.count
- }}</span>
- </el-tooltip>
- <span v-else>{{ scope.row[item.prop]?.count }}</span>
- </div>
- <div v-else>
- <span
- v-if="
- item.prop === 'totalCount' && hasNumError(scope.row)
- "
- style="color: #f56c6c; font-weight: bold"
- >{{ scope.row[item.prop] }}</span
- >
- <span v-else>{{ scope.row[item.prop] }}</span>
- </div>
- </template>
- </el-table-column>
- </el-table>
- </div>
- </div>
- </el-form>
- </div>
- </div>
- </div>
- </template>
- <script>
- import qs from "qs";
- import { cloneDeep } from "lodash";
- import { mapState } from "vuex";
- import { QUESTION_API } from "@/constants/constants";
- import LinkTitlesCustom from "@/components/LinkTitlesCustom.vue";
- export default {
- name: "AddPaperSelect",
- components: { LinkTitlesCustom },
- data() {
- return {
- tempPapers: [],
- tempPaperIds: [],
- curSelect: 1,
- totalSelect: 10,
- pageSize: 10,
- hasError: false,
- form: {
- paperStructType: "EXACT",
- name: "",
- paperStructId: "",
- paperType: "IMPORT",
- paperIds: "",
- },
- paperIdsArr: [],
- options1: [],
- tableData1: [],
- difficultyDegree: "",
- tableColumns1: [
- { label: "题型", prop: "detailName", minWidth: "100" },
- { label: "总分", prop: "totalScore", minWidth: "80" },
- { label: "数量", prop: "totalCount", minWidth: "80" },
- { label: "难", prop: "hardInfo", minWidth: "80" },
- { label: "中", prop: "mediumInfo", minWidth: "80" },
- { label: "易", prop: "easyInfo", minWidth: "80" },
- ],
- tableData2: [],
- tableColumns2: [
- { label: "名称", prop: "name" },
- { label: "小题数量", prop: "unitCount", width: "100px" },
- ],
- multipleSelection: [],
- tableData3: [],
- tableColumns3: [
- { label: "题型", prop: "detailName", minWidth: "100" },
- { label: "数量", prop: "totalCount", minWidth: "80" },
- { label: "难", prop: "hardInfo", minWidth: "80" },
- { label: "中", prop: "mediumInfo", minWidth: "80" },
- { label: "易", prop: "easyInfo", minWidth: "80" },
- ],
- lastRequestKey: "",
- tableLoading3: false,
- tableLoading1: false,
- tableLoading2: false,
- checked: false,
- initSelectedRows: [],
- isEditInitPage: false,
- };
- },
- computed: {
- ...mapState({ user: (state) => state.user }),
- curStruct() {
- if (this.form.paperStructId) {
- return this.options1.find(
- (item) => item.id === this.form.paperStructId
- );
- } else {
- return {};
- }
- },
- rules() {
- return {
- name: { required: true, message: "请输入模板名称", trigger: "change" },
- paperStructId: {
- required: true,
- message: "请选择组卷结构",
- trigger: "change",
- },
- };
- },
- },
- watch: {
- "form.paperStructId"() {
- this.structChange();
- this.changePaperType(true);
- },
- // "form.paperStructType"() {
- // this.form.paperStructId = "";
- // this.getStruct();
- // this.tableData1 = [];
- // this.$refs.table2.clearSelection();
- // },
- multipleSelection(val) {
- this.form.paperIds = val.map((item) => item.id).join(",");
- },
- },
- async created() {
- let res = await this.getTplData();
- if (res) {
- this.getStruct();
- // this.getTable2(true);
- }
- },
- methods: {
- selectCurrentChange(val) {
- this.curSelect = val;
- this.getTable2();
- },
- paperStructTypeChange() {
- this.form.paperStructId = "";
- this.getStruct();
- this.tableData1 = [];
- this.difficultyDegree = "";
- this.$refs.table2.clearSelection();
- },
- async getTplData() {
- const { id } = this.$route.params;
- if (id) {
- try {
- const data = await this.$http.post(
- "/api/ecs_ques/randompaper/info",
- null,
- {
- params: {
- id,
- },
- }
- );
- const tplData = data.data;
- this.tempPaperIds = tplData.paperIds || [];
- this.tempPapers = tplData.papers || [];
- this.isEditInitPage = true;
- Object.assign(this.form, tplData || {}, {
- paperIds: (tplData.paperIds || []).join(","),
- });
- this.getTable2();
- this.getTable3();
- return true;
- } catch (e) {
- return false;
- }
- } else {
- return true;
- }
- },
- back() {
- // if (this.$route.params?.id) {
- this.$router.push("/questions/extract_paper_template");
- // } else {
- // this.$router.push("/questions/gen_paper/0");
- // }
- },
- save() {
- this.checked = true;
- let paperIds = this.tempPaperIds.join(",");
- this.$refs.form.validate((valid) => {
- if (valid) {
- if (this.tempPaperIds.length && !this.hasError) {
- let params = {
- courseId: this.$route.query.courseId,
- ...this.form,
- rootOrgId: this.user.rootOrgId,
- paperIds,
- };
- if (this.$route.params.id) {
- params.id = this.$route.params.id;
- }
- this.$http
- .post("/api/ecs_ques/randompaper/save", qs.stringify(params))
- .then(() => {
- this.$message.success("保存成功");
- // this.$router.back();
- this.$router.push("/questions/extract_paper_template");
- })
- .catch((err) => {
- if (
- err.response &&
- err.response.data &&
- err.response.data.desc
- ) {
- this.$message.error(err.response.data.desc);
- }
- });
- }
- } else {
- console.log("error submit!!");
- return false;
- }
- });
- },
- canSelect() {
- return !!this.form.paperStructId;
- },
- structChange() {
- if (!this.form.paperStructId) {
- return;
- }
- this.tableLoading1 = true;
- this.$http
- .post("/api/ecs_ques/randompaper/struct/question/info", null, {
- params: { structId: this.form.paperStructId },
- headers: { "content-type": "application/x-www-form-urlencoded" },
- })
- .then((res) => {
- this.tableData1 = res.data.structQuestionInfo || [];
- this.difficultyDegree = res.data.difficultyDegree;
- this.tableLoading1 = false;
- });
- },
- getStruct() {
- var courseNo = this.$route.query.courseNo;
- var url =
- QUESTION_API +
- "/paperStruct?courseNo=" +
- courseNo +
- "&type=" +
- this.form.paperStructType;
- this.loading = true;
- this.$http.get(url).then((response) => {
- this.options1 = response.data;
- this.loading = false;
- });
- },
- getTable2() {
- this.tableLoading2 = true;
- let apiUrl =
- this.form.paperType === "IMPORT"
- ? "/api/ecs_ques/importPaper/huoge"
- : "/api/ecs_ques/genPaper/huoge";
- this.$http
- .get(
- apiUrl +
- `/${this.curSelect}/${this.pageSize}?courseNo=${this.$route.query.courseNo}&ids=${this.tempPaperIds}`,
- {
- // params: {
- // courseNo: this.$route.query.courseNo,
- // ids: this.tempPaperIds,
- // },
- }
- )
- .then((res) => {
- this.tableData2 = res.data.content || [];
- this.totalSelect = res.data.totalElements;
- // this.curSelect = res.data.number + 1;
- // if (bool) {
- // this.tableData2.forEach((item) => {
- // if (this.paperIdsArr.includes(item.id)) {
- // this.initSelectedRows.push(item);
- // }
- // });
- // setTimeout(() => {
- // this.initSelectedRows.forEach((item) => {
- // this.$refs.table2.toggleRowSelection(item, true);
- // });
- // }, 0);
- // }
- this.tableLoading2 = false;
- });
- },
- removeSelected(id) {
- for (let [index, paper] of this.tempPapers.entries()) {
- if (id == paper.id) {
- this.tempPapers.splice(index, 1);
- this.tableData2.push(paper);
- break;
- }
- }
- for (var i = 0; i < this.tempPaperIds.length; i++) {
- if (this.tempPaperIds[i] == id) {
- this.tempPaperIds.splice(i, 1);
- break;
- }
- }
- this.getTable2();
- this.getTable3();
- },
- changePaperType() {
- console.log("changePaperType");
- if (!this.isEditInitPage) {
- this.tempPapers = [];
- this.tempPaperIds = [];
- this.tableData2 = [];
- this.tableData3 = [];
- this.multipleSelection = [];
- this.curSelect = 1;
- this.getTable2();
- } else {
- this.isEditInitPage = false;
- }
- // if (bool === true) {
- // // this.handleSelectionChange([]);
- // this.tempPapers = [];
- // this.tempPaperIds = [];
- // // this.$refs.table2.clearSelection();
- // this.getTable3();
- // } else {
- // this.tableData2 = [];
- // this.tempPapers = [];
- // this.tempPaperIds = [];
- // this.multipleSelection = [];
- // this.curSelect = 1;
- // this.getTable2();
- // }
- },
- getTable3() {
- // let paperIds = this.multipleSelection.map((item) => item.id);
- // if (!paperIds.length) {
- if (!this.tempPaperIds.length) {
- this.tableData3 = [];
- this.tableLoading3 = false;
- return false;
- }
- this.tableLoading3 = true;
- let str = new Date().getTime() + "";
- this.lastRequestKey = str;
- this.$http
- .post(
- "/api/ecs_ques/randompaper/struct/question/view/info",
- qs.stringify({
- paperIds: this.tempPaperIds.join(","),
- structId: this.form.paperStructId,
- }),
- {
- headers: { "content-type": "application/x-www-form-urlencoded" },
- }
- )
- .then((res) => {
- if (this.lastRequestKey === str) {
- this.tableData3 = res.data.structQuestionInfo || [];
- this.tableLoading3 = false;
- this.hasError = !res.data.valid;
- }
- });
- },
- handleSelectionChange(val) {
- // this.multipleSelection = val;
- if (val.length) {
- val.forEach((element) => {
- this.tempPapers.push(cloneDeep(element));
- this.tempPaperIds.push(element.id);
- });
- this.getTable2();
- this.getTable3();
- }
- },
- hasNumError(row) {
- return (
- row.easyInfo?.valid == false ||
- row.hardInfo?.valid == false ||
- row.mediumInfo?.valid == false
- );
- // if (prop === "detailName") {
- // return false;
- // } else {
- // let targetName = row.detailName;
- // let find = this.tableData1.find(
- // (item) => item.detailName === targetName
- // );
- // if (!find) {
- // return false;
- // } else {
- // if (prop === "totalCount") {
- // return row[prop] < find[prop];
- // } else {
- // return row[prop].count < find[prop].count;
- // }
- // }
- // }
- },
- // hasError() {
- // return (
- // this.tableData1.length &&
- // this.tableData3.length &&
- // this.tableData3.every((item) => {
- // return (
- // this.hasNumError(item, "totalCount") ||
- // this.hasNumError(item, "hardInfo") ||
- // this.hasNumError(item, "mediumInfo") ||
- // this.hasNumError(item, "easyInfo")
- // );
- // })
- // );
- // },
- },
- };
- </script>
- <style lang="scss" scoped>
- .add-paper-select {
- * {
- box-sizing: border-box;
- }
- .el-form .el-form-item {
- margin-bottom: 18px;
- }
- ::v-deep .red {
- color: #f56c6c;
- font-weight: bold;
- text-decoration: underline;
- cursor: pointer;
- }
- p {
- margin: 0;
- }
- .top {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding-bottom: 15px;
- border-bottom: 1px solid #eee;
- p {
- font-size: 14px;
- }
- }
- .box-body {
- background-color: #fff;
- border-radius: 6px;
- padding: 15px 10px;
- .form {
- margin-top: 15px;
- }
- }
- }
- </style>
|