MarkPaperMarker.vue 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. <template>
  2. <div class="mark-paper-marker">
  3. <div class="marker-header">
  4. <p
  5. class="marker-desc color-danger"
  6. v-if="subjectiveQuestionCount > groupQuestionCount"
  7. >
  8. 本试卷共<span class="mlr-1">{{ questionCount }}</span
  9. >道小题,客观题<span class="mlr-1">{{ objectiveQuestionCount }}</span
  10. >道,主观题<span class="mlr-1">{{ subjectiveQuestionCount }}</span
  11. >道,已经设置<span class="mlr-1">{{ groupQuestionCount }}</span
  12. >道主观题,还有<span class="mlr-1">{{
  13. subjectiveQuestionCount - groupQuestionCount
  14. }}</span
  15. >道主观题未设置评卷员,请继续设置,确保全部主观题均已分配评卷员!
  16. </p>
  17. <p class="marker-desc color-success" v-else>
  18. 本试卷共<span class="mlr-1">{{ questionCount }}</span
  19. >道小题,客观题<span class="mlr-1">{{ objectiveQuestionCount }}</span
  20. >道,主观题<span class="mlr-1">{{ subjectiveQuestionCount }}</span
  21. >道,主观题已全部设置评卷员!
  22. </p>
  23. <el-button v-if="!onlyMarker" type="primary" @click="toAdd"
  24. >新增</el-button
  25. >
  26. </div>
  27. <el-table :data="groupInfo" border>
  28. <el-table-column type="index" width="50"> </el-table-column>
  29. <el-table-column label="评卷员">
  30. <template slot-scope="scope">
  31. <el-tag
  32. v-for="user in scope.row.markerList"
  33. :key="user.id"
  34. class="tag-spin"
  35. size="medium"
  36. >
  37. {{ user.name }}({{ user.orgName }})
  38. </el-tag>
  39. </template>
  40. </el-table-column>
  41. <el-table-column v-if="!onlyMarker" label="评卷方式">
  42. <template slot-scope="scope">
  43. <el-radio-group v-model="scope.row.doubleRate">
  44. <el-radio
  45. v-for="(val, key) in MARK_TYPE"
  46. :key="key"
  47. :label="key * 1"
  48. >{{ val }}</el-radio
  49. >
  50. </el-radio-group>
  51. <span v-if="scope.row.doubleRate === 1">
  52. 仲裁阀值:<el-input-number
  53. v-model="scope.row.arbitrateThreshold"
  54. class="width-80"
  55. size="small"
  56. :min="0"
  57. :max="999999"
  58. :step="0.01"
  59. step-strictly
  60. :controls="false"
  61. >
  62. </el-input-number>
  63. </span>
  64. </template>
  65. </el-table-column>
  66. <el-table-column label="评阅题目">
  67. <template slot-scope="scope">
  68. {{ scope.row.questions | questionsFilter }}
  69. </template>
  70. </el-table-column>
  71. <el-table-column
  72. v-if="!onlyMarker"
  73. label="评卷区"
  74. width="80"
  75. align="center"
  76. >
  77. <template slot-scope="scope">
  78. <i
  79. v-if="scope.row.pictureConfigList.length"
  80. class="el-icon-success color-success"
  81. ></i>
  82. </template>
  83. </el-table-column>
  84. <el-table-column class-name="action-column" label="操作" width="160px">
  85. <template slot-scope="scope">
  86. <el-button class="btn-primary" type="text" @click="toEdit(scope.row)"
  87. >编辑</el-button
  88. >
  89. <el-button
  90. v-if="!onlyMarker"
  91. class="btn-primary"
  92. type="text"
  93. :disabled="!paperList.length"
  94. @click="toSetArea(scope.row)"
  95. >评卷区</el-button
  96. >
  97. <el-button
  98. v-if="!onlyMarker"
  99. class="btn-danger"
  100. type="text"
  101. @click="toDelete(scope.row)"
  102. >删除</el-button
  103. >
  104. </template>
  105. </el-table-column>
  106. </el-table>
  107. <!-- ModifyMarkerQuestion -->
  108. <modify-marker-question
  109. ref="ModifyMarkerQuestion"
  110. :course-code="datas.basicPaperInfo.courseCode"
  111. :instance="curGroupInfo"
  112. :disabled-question-ids="disabledQuestionIds"
  113. :paper-structure="subjectiveQuestionList"
  114. @modified="groupModified"
  115. ></modify-marker-question>
  116. <!-- ModifyMarkArea -->
  117. <modify-mark-area
  118. v-if="!onlyMarker"
  119. ref="ModifyMarkArea"
  120. :base-info="datas.basicPaperInfo"
  121. :group="curGroupInfo"
  122. :paper-list="paperList"
  123. @modified="areaModified"
  124. ></modify-mark-area>
  125. </div>
  126. </template>
  127. <script>
  128. import ModifyMarkerQuestion from "./ModifyMarkerQuestion";
  129. import ModifyMarkArea from "./ModifyMarkArea.vue";
  130. import { examStructureFindJpg, examBindMarker } from "../../api";
  131. export default {
  132. name: "mark-paper-marker",
  133. components: { ModifyMarkerQuestion, ModifyMarkArea },
  134. props: {
  135. datas: {
  136. type: Object,
  137. default() {
  138. return {
  139. basicPaperInfo: {},
  140. paperStructureInfo: [],
  141. groupInfo: []
  142. };
  143. }
  144. },
  145. onlyMarker: {
  146. type: Boolean,
  147. default: false
  148. }
  149. },
  150. data() {
  151. return {
  152. questionCount: 0,
  153. groupQuestionCount: 0,
  154. groupInfo: [],
  155. disabledQuestionIds: [],
  156. curGroupInfo: {},
  157. subjectiveQuestionList: [],
  158. subjectiveQuestionCount: 0,
  159. objectiveQuestionCount: 0,
  160. MARK_TYPE: {
  161. 0: "单评",
  162. 1: "双评"
  163. },
  164. paperList: []
  165. };
  166. },
  167. filters: {
  168. questionsFilter(val) {
  169. return val.map(item => `${item.mainNumber}-${item.subNumber}`).join(",");
  170. }
  171. },
  172. mounted() {
  173. this.initData();
  174. if (!this.onlyMarker) this.getPaperList();
  175. },
  176. methods: {
  177. async getPaperList() {
  178. this.paperList = [];
  179. const data = await examStructureFindJpg({
  180. examId: this.datas.basicPaperInfo.examId,
  181. courseCode: this.datas.basicPaperInfo.courseCode,
  182. paperNumber: this.datas.basicPaperInfo.paperNumber,
  183. paperType: this.datas.basicPaperInfo.paperType
  184. });
  185. const papers = data || [];
  186. papers.sort((a, b) => a.index - b.index);
  187. this.paperList = papers.map(paper => {
  188. return {
  189. imgUrl: paper.path,
  190. areas: []
  191. };
  192. });
  193. },
  194. initData() {
  195. this.groupInfo = this.datas.groupInfo.map((item, index) => {
  196. return { ...item, groupNumber: index + 1 };
  197. });
  198. this.questionCount = this.datas.paperStructureInfo.length;
  199. this.updateDisableQuestionIds();
  200. this.subjectiveQuestionList = this.datas.paperStructureInfo.filter(
  201. item => item.qType === "subjective"
  202. );
  203. this.subjectiveQuestionCount = this.subjectiveQuestionList.length;
  204. this.objectiveQuestionCount =
  205. this.questionCount - this.subjectiveQuestionCount;
  206. this.$emit("on-ready");
  207. },
  208. updateDisableQuestionIds(filterId) {
  209. let groupInfo = this.groupInfo;
  210. if (filterId)
  211. groupInfo = this.groupInfo.filter(item => item.id !== filterId);
  212. let disabledQuestionIds = [];
  213. groupInfo.forEach(item => {
  214. disabledQuestionIds = [
  215. ...disabledQuestionIds,
  216. ...item.questions.map(item => item.id)
  217. ];
  218. });
  219. this.disabledQuestionIds = disabledQuestionIds;
  220. if (!filterId) this.groupQuestionCount = disabledQuestionIds.length;
  221. },
  222. updateGroupNumber() {
  223. this.groupInfo.forEach((group, index) => {
  224. group.groupNumber = index + 1;
  225. });
  226. },
  227. toAdd() {
  228. this.updateDisableQuestionIds();
  229. if (this.groupQuestionCount === this.subjectiveQuestionCount) {
  230. this.$message.error("当前已经没有主观题目可供设置!");
  231. return;
  232. }
  233. this.curGroupInfo = {
  234. id: this.$randomCode(),
  235. groupNumber: null,
  236. markerList: [],
  237. doubleRate: 0,
  238. arbitrateThreshold: 1,
  239. questions: [],
  240. pictureConfigList: []
  241. };
  242. this.$refs.ModifyMarkerQuestion.open();
  243. },
  244. toEdit(row) {
  245. this.curGroupInfo = row;
  246. this.updateDisableQuestionIds(row.id);
  247. this.$refs.ModifyMarkerQuestion.open();
  248. },
  249. toSetArea(row) {
  250. this.curGroupInfo = row;
  251. this.$refs.ModifyMarkArea.open();
  252. },
  253. toDelete(row) {
  254. const pos = this.groupInfo.findIndex(item => item.id === row.id);
  255. this.groupInfo.splice(pos, 1);
  256. this.updateDisableQuestionIds();
  257. this.updateGroupNumber();
  258. },
  259. groupModified(row) {
  260. const pos = this.groupInfo.findIndex(item => item.id === row.id);
  261. if (pos === -1) {
  262. this.groupInfo.push(row);
  263. } else {
  264. this.groupInfo.splice(pos, 1, row);
  265. }
  266. this.updateDisableQuestionIds();
  267. this.updateGroupNumber();
  268. if (this.onlyMarker) {
  269. this.updateGroupMarker(row);
  270. }
  271. },
  272. async updateGroupMarker(group) {
  273. console.log(group);
  274. await examBindMarker({
  275. paperStructureId: this.datas.basicPaperInfo.id,
  276. groupInfo: group
  277. });
  278. },
  279. areaModified(row) {
  280. const pos = this.groupInfo.findIndex(item => item.id === row.id);
  281. if (pos === -1) return;
  282. this.groupInfo.splice(pos, 1, row);
  283. },
  284. checkData() {
  285. let errorMessages = [];
  286. if (this.subjectiveQuestionCount > this.groupQuestionCount) {
  287. errorMessages.push("当前还有题目未设置评卷员");
  288. }
  289. this.groupInfo.forEach((item, index) => {
  290. if (item.doubleRate === 1 && !item.arbitrateThreshold) {
  291. errorMessages.push(`序号${index + 1}设置中,仲裁阀值不能为空`);
  292. }
  293. });
  294. if (errorMessages.length) {
  295. this.$message.error(errorMessages.join("。"));
  296. return;
  297. }
  298. this.updateData();
  299. this.$emit("next-step");
  300. },
  301. getData() {
  302. return this.groupInfo.map(item => {
  303. return { ...item };
  304. });
  305. },
  306. updateData() {
  307. this.$emit("data-change", { groupInfo: this.getData() });
  308. }
  309. }
  310. };
  311. </script>