SelectDrag.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. <!-- 选择 -> 拖拽 -->
  2. <template>
  3. <div
  4. class="select-drag"
  5. v-if="curQue && judgeAnswer == 'standardAnswer' ? IsError : true"
  6. >
  7. <!-- 选项 -->
  8. <div class="select-drag-options">
  9. <draggable
  10. v-model="curQue.options"
  11. group="option"
  12. animation="300"
  13. class="draggable-options"
  14. :sort="false"
  15. :disabled="isAnswerMode"
  16. :move="onMove"
  17. >
  18. <span
  19. v-for="(item, i) in curQue.options"
  20. :key="`option-${i}`"
  21. class="drag-option"
  22. :style="{
  23. cursor: `${isAnswerMode ? 'default' : 'pointer'}`,
  24. }"
  25. >
  26. <div>
  27. <span
  28. v-for="({ chs, pinyin }, j) in item.wordsList"
  29. :key="`${isPyTop ? 'pinyin' : 'chs'}-${j}`"
  30. :class="[`${isPyTop ? 'pinyin' : 'chs'}`]"
  31. v-text="`${isPyTop ? pinyin : chs}`"
  32. />
  33. </div>
  34. <div>
  35. <span
  36. v-for="({ chs, pinyin }, j) in item.wordsList"
  37. :key="`${isPyTop ? 'chs' : 'pinyin'}-${j}`"
  38. :class="[`${isPyTop ? 'chs' : 'pinyin'}`]"
  39. v-text="`${isPyTop ? chs : pinyin}`"
  40. />
  41. </div>
  42. </span>
  43. </draggable>
  44. </div>
  45. <!-- 句子 -->
  46. <div class="select-drag-sentences">
  47. <div
  48. v-for="(sentence, i) in judgeAnswer == 'standardAnswer'
  49. ? CorrectData.sentences
  50. : curQue.sentences"
  51. :key="`sentence-${i}`"
  52. :data-serial="judgeAnswer == 'standardAnswer' ? changeNumber(i) : i + 1"
  53. class="drag-sentence"
  54. >
  55. <span
  56. v-for="(item, j) in sentence"
  57. :key="`sentence-item-${j}`"
  58. :class="[
  59. 'drag-sentence-item',
  60. `${item.isSpace && item.dragList.length <= 0 ? 'space' : ''}`,
  61. changeClass(i, item.index, j),
  62. ]"
  63. :style="{
  64. 'grid-template': item.isSpace
  65. ? ''
  66. : `repeat(${item.wordsList.length}, auto) / repeat(${item.wordsList.length}, auto)`,
  67. }"
  68. >
  69. <!-- 空格 -> 拖拽 -->
  70. <template v-if="item.isSpace">
  71. <draggable
  72. v-model="item.dragList"
  73. class="draggable-space"
  74. :data-sentence="i"
  75. :data-subsection="j"
  76. :sort="false"
  77. :disabled="isAnswerMode"
  78. group="option"
  79. animation="300"
  80. :move="onMoveTo"
  81. @change="change({ ...arguments }, i)"
  82. >
  83. <div
  84. :class="[`${item.dragList.length > 0 ? 'drag-list' : ''}`]"
  85. :style="{
  86. 'grid-template':
  87. item.dragList.length > 0
  88. ? `repeat(${item.dragList[0].wordsList.length}, auto) / repeat(${item.dragList[0].wordsList.length}, auto)`
  89. : '',
  90. cursor: `${isAnswerMode ? 'default' : 'pointer'}`,
  91. }"
  92. >
  93. <template v-if="item.dragList.length > 0">
  94. <span
  95. v-for="({ chs, pinyin }, k) in item.dragList[0].wordsList"
  96. :key="`${isPyTop ? 'pinyin' : 'chs'}-${k}`"
  97. :class="[`${isPyTop ? 'pinyin' : 'chs'}`]"
  98. v-text="isPyTop ? pinyin : chs"
  99. />
  100. <span
  101. v-for="({ chs, pinyin }, k) in item.dragList[0].wordsList"
  102. :key="`${isPyTop ? 'chs' : 'pinyin'}-${k}`"
  103. :class="[`${isPyTop ? 'chs' : 'pinyin'}`]"
  104. v-text="isPyTop ? chs : pinyin"
  105. />
  106. </template>
  107. </div>
  108. </draggable>
  109. </template>
  110. <template v-else>
  111. <span
  112. v-for="({ chs, pinyin }, k) in item.wordsList"
  113. :key="`${isPyTop ? 'pinyin' : 'chs'}-${k}`"
  114. :class="[`${isPyTop ? 'pinyin' : 'chs'}`]"
  115. >
  116. {{ isPyTop ? pinyin : chs }}
  117. </span>
  118. <span
  119. v-for="({ chs, pinyin }, k) in item.wordsList"
  120. :key="`${isPyTop ? 'chs' : 'pinyin'}-${k}`"
  121. :class="[`${isPyTop ? 'chs' : 'pinyin'}`]"
  122. >
  123. {{ isPyTop ? chs : pinyin }}
  124. </span>
  125. </template>
  126. </span>
  127. </div>
  128. </div>
  129. </div>
  130. </template>
  131. <script>
  132. import draggable from "vuedraggable";
  133. export default {
  134. components: { draggable },
  135. props: {
  136. curQue: {
  137. type: Object,
  138. required: true,
  139. },
  140. themeColor: {
  141. type: String,
  142. required: true,
  143. },
  144. TaskModel: {
  145. type: String,
  146. required: true,
  147. },
  148. judgeAnswer: {
  149. type: String,
  150. required: true,
  151. },
  152. },
  153. data() {
  154. return {
  155. isAnswerMode: false,
  156. curDrag: {
  157. sentenceIndex: 0,
  158. subsectionIndex: 0,
  159. },
  160. IsError: false,
  161. CorrectData: null,
  162. };
  163. },
  164. computed: {
  165. isPyTop() {
  166. return this.curQue.pyPosition === "top";
  167. },
  168. },
  169. created() {
  170. const Bookanswer = this.curQue.Bookanswer;
  171. if (Bookanswer) {
  172. this.isAnswerMode = true;
  173. if (this.judgeAnswer == "userAnswer") {
  174. } else if (this.judgeAnswer == "standardAnswer") {
  175. let data = JSON.parse(JSON.stringify(this.curQue));
  176. let arr = [];
  177. data.sentences.forEach((item, index) => {
  178. let flag = false;
  179. item.forEach((items, indexs) => {
  180. if (items.isSpace) {
  181. if (
  182. this.curQue.Bookanswer.answerList[index][items.index]
  183. .userAnswerJudge == "[JUDGE##F##JUDGE]"
  184. ) {
  185. if (!flag) {
  186. flag = true;
  187. }
  188. }
  189. }
  190. });
  191. arr.push(flag);
  192. });
  193. arr.forEach((item, index) => {
  194. if (!item) {
  195. data.sentences.splice(index, 1);
  196. }
  197. });
  198. data.sentences.forEach((item, index) => {
  199. item.forEach((items, indexs) => {
  200. if (items.isSpace) {
  201. items.dragList = [];
  202. this.curQue.oldOptions.forEach((op) => {
  203. if (items.answer == op.sentence) {
  204. items.dragList.push(op);
  205. }
  206. });
  207. }
  208. });
  209. });
  210. this.CorrectData = data;
  211. }
  212. this.iSErrorEvent();
  213. } else {
  214. let Bookanswer = {
  215. dragList: [],
  216. answerList: [],
  217. };
  218. this.curQue.oldOptions = JSON.parse(JSON.stringify(this.curQue.options));
  219. this.curQue.sentences.forEach((item) => {
  220. let arr = [];
  221. let index = 0;
  222. item.forEach((items, i) => {
  223. if (items.isSpace) {
  224. let obj = {
  225. userAnswerJudge: "",
  226. answer: items.answer,
  227. index: index,
  228. };
  229. items.index = index;
  230. if (items.answer) {
  231. obj.userAnswerJudge = "[JUDGE##F##JUDGE]";
  232. }
  233. arr.push(obj);
  234. index++;
  235. }
  236. });
  237. Bookanswer.dragList.push([]);
  238. Bookanswer.answerList.push(arr);
  239. });
  240. this.$set(this.curQue, "Bookanswer", Bookanswer);
  241. }
  242. },
  243. methods: {
  244. // 计算序号
  245. changeNumber(i) {
  246. let index = null;
  247. this.curQue.sentences.forEach((item, indexs) => {
  248. let flag = true;
  249. if (this.CorrectData.sentences[i].length == item.length) {
  250. item.forEach((items, indexss) => {
  251. if (items.isSpace) {
  252. if (
  253. this.CorrectData.sentences[i][indexss].answer != items.answer
  254. ) {
  255. flag = false;
  256. }
  257. } else {
  258. if (
  259. this.CorrectData.sentences[i][indexss].sentence !=
  260. items.sentence
  261. ) {
  262. flag = false;
  263. }
  264. }
  265. });
  266. } else {
  267. flag = false;
  268. }
  269. if (flag) {
  270. index = indexs;
  271. }
  272. });
  273. return index + 1;
  274. },
  275. changeClass(index, indexs, indexss) {
  276. let className = "";
  277. if (Object.prototype.toString.call(index).indexOf("Number") != -1) {
  278. if (
  279. this.judgeAnswer == "studentAnswer" ||
  280. this.judgeAnswer == "userAnswer"
  281. ) {
  282. if (this.curQue.Bookanswer.answerList[index][indexs]) {
  283. if (
  284. this.curQue.Bookanswer.answerList[index][indexs].userAnswerJudge
  285. ) {
  286. if (
  287. this.curQue.Bookanswer.answerList[index][indexs]
  288. .userAnswerJudge == "[JUDGE##T##JUDGE]"
  289. ) {
  290. className = "correct";
  291. } else {
  292. className = "error";
  293. }
  294. }
  295. }
  296. } else if (this.judgeAnswer == "standardAnswer") {
  297. if (this.CorrectData.sentences[index][indexss].isSpace) {
  298. if (
  299. this.CorrectData.sentences[index][indexss].dragList.length > 0
  300. ) {
  301. className = "correct";
  302. }
  303. }
  304. }
  305. }
  306. return className;
  307. },
  308. onMove(e) {
  309. if (e.relatedContext.component.realList.length > 0) return false;
  310. let { sentence, subsection } = e.to.dataset;
  311. this.curDrag = {
  312. sentenceIndex: sentence,
  313. subsectionIndex: subsection,
  314. };
  315. return true;
  316. },
  317. onMoveTo(e) {
  318. if (
  319. e.to.classList.contains("draggable-space") &&
  320. e.relatedContext.component.realList.length > 0
  321. ) {
  322. return false;
  323. }
  324. let { sentence, subsection } = e.from.dataset;
  325. this.curDrag = {
  326. sentenceIndex: sentence,
  327. subsectionIndex: subsection,
  328. };
  329. },
  330. change(obj, i) {
  331. if (obj[0].added) {
  332. this.curQue.Bookanswer.dragList[i].push({
  333. ...this.curDrag,
  334. ...obj[0].added.element,
  335. });
  336. }
  337. if (obj[0].removed) {
  338. this.curQue.Bookanswer.dragList[i] = this.curQue.Bookanswer.dragList[
  339. i
  340. ].filter(({ sentenceIndex, subsectionIndex }) => {
  341. let { sentenceIndex: senIndex, subsectionIndex: subIndex } =
  342. this.curDrag;
  343. if (sentenceIndex === senIndex && subsectionIndex === subIndex) {
  344. return false;
  345. }
  346. return true;
  347. });
  348. }
  349. this.changeuserAnswerJudge();
  350. },
  351. // 判断对错
  352. changeuserAnswerJudge() {
  353. this.curQue.sentences.forEach((item, index) => {
  354. item.forEach((items, indexs) => {
  355. if (items.isSpace) {
  356. if (items.answer) {
  357. if (items.dragList) {
  358. if (items.dragList.length > 0) {
  359. if (items.answer == items.dragList[0].sentence) {
  360. this.curQue.Bookanswer.answerList[index][
  361. items.index
  362. ].userAnswerJudge = "[JUDGE##T##JUDGE]";
  363. } else {
  364. this.curQue.Bookanswer.answerList[index][
  365. items.index
  366. ].userAnswerJudge = "[JUDGE##F##JUDGE]";
  367. }
  368. } else {
  369. this.curQue.Bookanswer.answerList[index][
  370. items.index
  371. ].userAnswerJudge = "[JUDGE##F##JUDGE]";
  372. }
  373. }
  374. }
  375. }
  376. });
  377. });
  378. },
  379. // 判断是否有错的
  380. iSErrorEvent() {
  381. let flag = false;
  382. this.curQue.Bookanswer.answerList.forEach((item) => {
  383. item.forEach((items) => {
  384. if (items.userAnswerJudge == "[JUDGE##F##JUDGE]") {
  385. flag = true;
  386. }
  387. });
  388. });
  389. if (flag) {
  390. this.IsError = true;
  391. } else {
  392. this.IsError = false;
  393. }
  394. },
  395. },
  396. };
  397. </script>
  398. <style lang="scss" scoped>
  399. .select-drag {
  400. width: 100%;
  401. color: #000;
  402. margin-bottom: 16px;
  403. .pinyin {
  404. font-family: "GB-PINYINOK-B";
  405. font-size: 14px;
  406. line-height: 1.3;
  407. }
  408. .chs {
  409. font-family: "FZJCGFKTK";
  410. font-size: 16px;
  411. line-height: 1.5;
  412. }
  413. &-options {
  414. width: 100%;
  415. background-color: #f7f7f7;
  416. border: 1px solid #dedede;
  417. border-radius: 8px;
  418. padding: 24px;
  419. .draggable-options {
  420. display: flex;
  421. flex-wrap: wrap;
  422. column-gap: 16px;
  423. row-gap: 24px;
  424. .drag-option {
  425. min-width: 96px;
  426. height: 58px;
  427. text-align: center;
  428. padding: 8px 12px;
  429. background-color: #fff;
  430. border: 1px solid #dedede;
  431. border-radius: 8px;
  432. }
  433. }
  434. }
  435. &-sentences {
  436. .drag-sentence {
  437. margin-top: 24px;
  438. display: flex;
  439. align-items: center;
  440. .correct {
  441. background: rgba(44, 167, 103, 0.1);
  442. /* 正确答案 */
  443. border: 1px solid #2ca767;
  444. }
  445. .error {
  446. background: rgba(237, 52, 45, 0.1);
  447. /* 错误颜色 */
  448. border: 1px solid #ed342d;
  449. }
  450. &::before {
  451. content: attr(data-serial);
  452. display: inline-block;
  453. text-align: center;
  454. color: #fff;
  455. font-size: 16px;
  456. line-height: 1.5;
  457. width: 24px;
  458. height: 24px;
  459. border-radius: 50%;
  460. background-color: #32a5d8;
  461. margin-right: 12px;
  462. }
  463. &-item {
  464. padding: 8px 12px;
  465. height: 58px;
  466. background-color: #fff;
  467. border: 1px solid #dedede;
  468. border-radius: 8px;
  469. margin-left: 4px;
  470. display: grid;
  471. column-gap: 4px;
  472. > :not(:first-child) {
  473. text-align: center;
  474. }
  475. &.space {
  476. min-width: 96px;
  477. background-color: #f1f1f1;
  478. }
  479. .drag-list {
  480. display: grid;
  481. column-gap: 4px;
  482. > :not(:first-child) {
  483. text-align: center;
  484. }
  485. }
  486. }
  487. }
  488. }
  489. }
  490. </style>