123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552 |
- <template>
- <div
- v-loading="loading"
- class="card-manage content"
- element-loading-text="请稍后..."
- >
- <div class="part-box">
- <h2 class="part-box-title">题卡管理</h2>
- <!-- 搜索 -->
- <el-form class="part-filter-form" inline :model="searchForm">
- <el-form-item label="课程">
- <el-select
- v-model="searchForm.courseId"
- :remote-method="getCourses4Search"
- :loading="courseLoading4Search"
- remote
- filterable
- clearable
- placeholder="请选择"
- @clear="getCourses4Search('')"
- >
- <el-option
- v-for="item in courseList"
- :key="item.id"
- :label="item.name + ' - ' + item.code"
- :value="item.id"
- ></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="命题老师">
- <el-input
- v-model="searchForm.teacherName"
- placeholder="请输入命题老师"
- maxlength="20"
- />
- </el-form-item>
- <el-form-item>
- <el-button type="danger" @click="handleCurrentChange(1)">
- 查询
- </el-button>
- </el-form-item>
- </el-form>
- <div class="part-box-action">
- <div v-if="!onlyAssignTeacher">
- <el-button
- type="primary"
- plain
- icon="icon icon-edit"
- @click="toCardHead"
- >题卡版头管理
- </el-button>
- <el-button
- type="primary"
- plain
- icon="icon icon-edit"
- @click="toExportPaperStruct"
- >导入试卷结构
- </el-button>
- <el-button
- type="danger"
- plain
- icon="icon icon-delete"
- @click="toBatchDelete"
- >批量删除
- </el-button>
- </div>
- <div>
- <el-button
- type="primary"
- icon="icon icon-export-white"
- @click="toBatchDownload"
- >批量下载
- </el-button>
- </div>
- </div>
- </div>
- <div class="part-box">
- <!-- 页面列表 -->
- <el-table
- ref="table"
- :data="tableData"
- resizable
- @selection-change="selectChange"
- >
- <el-table-column
- type="selection"
- width="50"
- align="center"
- ></el-table-column>
- <el-table-column prop="course" label="所属课程"> </el-table-column>
- <el-table-column
- prop="creationTime"
- label="创建时间"
- width="170"
- ></el-table-column>
- <el-table-column prop="creator" label="创建人"></el-table-column>
- <el-table-column
- prop="submitTime"
- width="170"
- label="提交时间"
- ></el-table-column>
- <el-table-column prop="teacher" label="命题老师"></el-table-column>
- <el-table-column width="50" label="状态">
- <template slot-scope="scope">
- <span v-if="scope.row.enable">
- <el-tooltip
- class="item"
- effect="dark"
- content="启用"
- placement="left"
- >
- <i class="icon icon-right"></i>
- </el-tooltip>
- </span>
- <span v-else>
- <el-tooltip
- class="item"
- effect="dark"
- content="禁用"
- placement="left"
- >
- <i class="icon icon-error"></i>
- </el-tooltip>
- </span>
- </template>
- </el-table-column>
- <el-table-column width="170" label="操作">
- <template slot-scope="scope">
- <el-button
- v-if="!onlyAssignTeacher"
- size="mini"
- :type="scope.row.enable ? 'danger' : 'primary'"
- plain
- @click="toEnable(scope.row)"
- >
- {{ scope.row.enable ? "禁用" : "启用" }}
- </el-button>
- <el-dropdown>
- <el-button type="primary" plain size="mini">
- 更多<i class="el-icon-more el-icon--right"></i>
- </el-button>
- <el-dropdown-menu slot="dropdown" class="action-dropdown">
- <el-dropdown-item v-if="!onlyAssignTeacher">
- <el-button
- size="mini"
- type="primary"
- plain
- @click="toChangeTeacher(scope.row)"
- >编辑任务
- </el-button>
- </el-dropdown-item>
- <el-dropdown-item>
- <el-button
- size="mini"
- type="primary"
- plain
- @click="toEdit(scope.row)"
- >编辑题卡
- </el-button>
- </el-dropdown-item>
- <el-dropdown-item>
- <el-button
- size="mini"
- type="primary"
- plain
- @click="toView(scope.row)"
- >查看题卡
- </el-button>
- </el-dropdown-item>
- <el-dropdown-item v-if="!onlyAssignTeacher">
- <el-button
- size="mini"
- type="danger"
- plain
- @click="toDelete(scope.row)"
- >删除
- </el-button>
- </el-dropdown-item>
- <el-dropdown-item>
- <el-button
- size="mini"
- type="danger"
- plain
- @click="toDownload([scope.row.id])"
- >
- 下载题卡
- </el-button>
- </el-dropdown-item>
- </el-dropdown-menu>
- </el-dropdown>
- </template>
- </el-table-column>
- </el-table>
- <div class="part-page">
- <el-pagination
- :current-page="currentPage"
- :page-size="pageSize"
- :page-sizes="[10, 20, 50, 100, 200, 300]"
- layout="total, sizes, prev, pager, next, jumper"
- :total="total"
- @current-change="handleCurrentChange"
- @size-change="handleSizeChange"
- />
- </div>
- </div>
- <!-- ImportFileDialog -->
- <import-file-dialog
- ref="ImportFileDialog"
- dialog-title="导入试卷结构"
- :upload-url="uploadUrl"
- :template-url="templateUrl"
- @uploaded="batchAutoBuildCard"
- ></import-file-dialog>
- <!-- ModifyCard -->
- <modify-card
- ref="ModifyCard"
- :instance="curRow"
- @modified="search"
- ></modify-card>
- <!-- ProgressDialog -->
- <progress-dialog ref="ProgressDialog" :percentage="buildProgress"
- ><p><i class="el-icon-loading"></i>生成题卡中</p></progress-dialog
- >
- <!-- card-view-frame -->
- <div v-if="cardBuildUrl" class="card-build-frame">
- <iframe :src="cardBuildUrl" frameborder="0"></iframe>
- </div>
- </div>
- </template>
- <script>
- import {
- cardListApi,
- courseQueryApi,
- cardDeleteApi,
- cardEnableApi,
- cardConfigInfos,
- cardTemplateDetail,
- cardDownloadApi,
- } from "../api";
- import ImportFileDialog from "@/components/ImportFileDialog.vue";
- import ModifyCard from "../components/ModifyCard.vue";
- import ProgressDialog from "@/components/ProgressDialog.vue";
- import { QUESTION_API } from "@/constants/constants.js";
- import { mapState } from "vuex";
- import { getPaperStructSimpleStructInfo } from "../autoBuild/paperStruct";
- import { downloadByApi } from "@/plugins/download";
- export default {
- name: "CardManage",
- components: { ImportFileDialog, ModifyCard, ProgressDialog },
- data() {
- return {
- courseLoading4Search: false,
- loading: false,
- courseList: [],
- searchForm: {
- courseId: "",
- teacherName: "",
- },
- selectedIds: [],
- tableData: [],
- curRow: {},
- currentPage: 1,
- pageSize: 10,
- total: 10,
- downloading: false,
- // build task
- taskList: [],
- curTask: {},
- finishTaskList: [],
- cardBuildUrl: "",
- buildProgress: 0,
- // upload
- uploadUrl: `${QUESTION_API}/card/structure/import`,
- templateUrl: "",
- };
- },
- computed: {
- ...mapState({
- user: (state) => state.user,
- }),
- onlyAssignTeacher() {
- if (this.isAdmin) {
- return false;
- } else {
- return this.user.roleList.some(
- (role) => role.roleCode == "ASSIGN_TEACHER"
- );
- }
- },
- },
- mounted() {
- const cacheInfo = window.sessionStorage.getItem("card-manage");
- if (cacheInfo) {
- const { currentPage, pageSize, searchForm } = JSON.parse(cacheInfo);
- this.searchForm = { ...searchForm };
- this.currentPage = currentPage;
- this.pageSize = pageSize;
- this.handleCurrentChange(this.currentPage);
- window.sessionStorage.removeItem("card-manage");
- } else {
- this.handleCurrentChange(1);
- }
- this.getCoursesList();
- this.templateUrl = `${QUESTION_API}/card/import/template?$key=${this.user.key}&$token=${this.user.token}`;
- this.registBuildEmit();
- },
- beforeDestroy() {
- delete window.emitResult;
- },
- methods: {
- getCourses4Search(query) {
- this.courseLoading4Search = true;
- this.$httpWithMsg
- .get(QUESTION_API + "/course/query?name=" + query)
- .then((response) => {
- this.courseList = response.data;
- this.courseLoading4Search = false;
- });
- },
- async getCoursesList() {
- const res = await courseQueryApi();
- this.courseList = res.data || [];
- },
- async search() {
- if (this.loading) return;
- this.loading = true;
- const res = await cardListApi({
- ...this.searchForm,
- pageNumber: this.currentPage,
- pageSize: this.pageSize,
- }).catch(() => {});
- this.loading = false;
- if (!res) return;
- this.tableData = res.data.content;
- this.total = res.data.totalElements;
- },
- handleCurrentChange(val) {
- this.selectedIds = [];
- this.currentPage = val;
- this.search();
- },
- handleSizeChange(val) {
- this.selectedIds = [];
- this.currentPage = 1;
- this.pageSize = val;
- this.search();
- },
- selectChange(selections) {
- this.selectedIds = selections.map((item) => item.id);
- },
- toCardHead() {
- this.cacheSearchInfo();
- this.$router.push({ name: "CardHeadManage" });
- },
- toExportPaperStruct() {
- this.$refs.ImportFileDialog.open();
- },
- async batchAutoBuildCard(resData) {
- if (!resData.data || !resData.data.length) return;
- this.finishTaskList = [];
- this.curTask = {};
- this.taskList = [];
- const cardConfig = await this.getCardConfig();
- this.taskList = resData.data.map((item) => {
- return {
- cardId: item.id,
- cardConfig,
- paperSimpleStruct: getPaperStructSimpleStructInfo(item.structure),
- };
- });
- this.$refs.ProgressDialog.open();
- this.startTask();
- },
- startTask() {
- this.curTask = this.taskList.shift();
- window.cardData = this.curTask;
- const { href } = this.$router.resolve({
- name: "CardBuild",
- });
- this.cardBuildUrl = href + `?t=${Date.now()}`;
- // console.log(this.cardBuildUrl);
- },
- async getCardConfig() {
- const res = await cardConfigInfos();
- if (!res.data) {
- this.$message.error("找不到题卡版头!");
- return;
- }
- const tempRes = await cardTemplateDetail(res.data.cardTemplateId);
- if (!tempRes.data) {
- this.$message.error("找不到题卡模板!");
- return;
- }
- const config = {
- ...res.data,
- ...{
- pageSize: "A3",
- columnNumber: 2,
- columnGap: 20,
- showForbidArea: true,
- showScorePan: false,
- templateInfo: JSON.parse(tempRes.data.content),
- },
- };
- return config;
- },
- registBuildEmit() {
- window.emitResult = async (result) => {
- console.log(result);
- this.finishTaskList.push({ id: this.curTask.cardId, result });
- this.buildProgress =
- (
- (100 * this.finishTaskList.length) /
- (this.finishTaskList.length + this.taskList.length)
- ).toFixed(2) * 1;
- if (this.taskList.length) {
- this.cardBuildUrl = null;
- this.$nextTick(() => {
- this.startTask();
- });
- } else {
- this.$nextTick(() => {
- this.$refs.ProgressDialog.cancel();
- this.buildProgress = 0;
- const successCount = this.finishTaskList.filter(
- (item) => item.result
- ).length;
- delete window.cardData;
- const failCount = this.finishTaskList.length - successCount;
- this.$notify({
- message: `题卡生成完毕,成功${successCount}个,失败${failCount}个`,
- type: "success",
- });
- this.search();
- });
- }
- };
- },
- toBatchDownload() {
- if (!this.selectedIds.length) {
- this.$message.error("请选择数据");
- return;
- }
- this.toDownload(this.selectedIds);
- },
- async toBatchDelete() {
- if (!this.selectedIds.length) {
- this.$message.error("请选择数据");
- return;
- }
- const confirm = await this.$confirm(
- `确定要删除选中的这些数据吗?`,
- "提示",
- {
- type: "warning",
- }
- ).catch(() => {});
- if (confirm !== "confirm") return;
- await cardDeleteApi(this.selectedIds);
- this.$message.success("删除成功!");
- this.deletePageLastItem(this.selectedIds.length);
- },
- async toEnable(row) {
- const action = row.enable ? "禁用" : "启用";
- const confirm = await this.$confirm(`确定要${action}该题卡吗?`, "提示", {
- type: "warning",
- }).catch(() => {});
- if (confirm !== "confirm") return;
- const enable = !row.enable;
- await cardEnableApi({
- id: row.id,
- enable,
- });
- row.enable = enable;
- this.$message.success("操作成功!");
- },
- toChangeTeacher(row) {
- this.curRow = { ...row, teacherId: row.assignTeacher };
- this.$refs.ModifyCard.open();
- },
- toEdit(row) {
- this.cacheSearchInfo();
- this.$router.push({
- name: "CardEdit",
- params: {
- idType: "card",
- paperOrCardId: row.id,
- },
- });
- },
- toView(row) {
- const href = this.getRouterPath({
- name: "CardPreview",
- params: {
- viewType: "view",
- cardId: row.id,
- },
- });
- window.open(href);
- },
- async toDelete(row) {
- const confirm = await this.$confirm(`确定要删除题卡吗?`, "提示", {
- type: "warning",
- }).catch(() => {});
- if (confirm !== "confirm") return;
- await cardDeleteApi([row.id]);
- this.$message.success("删除成功!");
- this.deletePageLastItem();
- },
- async toDownload(ids) {
- if (this.downloading) return;
- this.downloading = true;
- const res = await downloadByApi(() => {
- return cardDownloadApi(ids);
- }).catch((e) => {
- this.$message.error(e || "下载失败,请重新尝试!");
- });
- this.downloading = false;
- if (!res) return;
- this.$message.success("下载成功!");
- },
- cacheSearchInfo() {
- window.sessionStorage.setItem(
- "card-mamange",
- JSON.stringify({
- searchForm: this.searchForm,
- currentPage: this.currentPage,
- pageSize: this.pageSize,
- })
- );
- },
- },
- };
- </script>
|