index.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. <style lang="less" scoped>
  2. .add_assess {
  3. h5 {
  4. padding: 30px 35px 0 35px;
  5. margin-bottom: 20px;
  6. font-size: 14px;
  7. span {
  8. color: #ff545b;
  9. margin-right: 3px;
  10. }
  11. }
  12. .table_map {
  13. border-bottom: 30px solid #dee2ea;
  14. .table_top_box {
  15. display: flex;
  16. align-items: center;
  17. justify-content: space-between;
  18. padding: 0 37px;
  19. .table_top_box_left {
  20. display: flex;
  21. /deep/.el-input--mini .el-input__inner {
  22. width: 200px;
  23. }
  24. .num_box {
  25. margin-left: 50px;
  26. display: flex;
  27. /deep/ .el-input__inner {
  28. width: 40px;
  29. text-align: center;
  30. }
  31. }
  32. }
  33. }
  34. .move_btn {
  35. font-size: 14px;
  36. margin-left: 10px;
  37. display: flex;
  38. div {
  39. width: 12px;
  40. height: 16px;
  41. margin-right: 8px;
  42. img {
  43. width: 100%;
  44. height: 100%;
  45. cursor: pointer;
  46. }
  47. }
  48. }
  49. }
  50. /deep/ .el-form-item--mini.el-form-item,
  51. .el-form-item--small.el-form-item {
  52. margin-bottom: 0;
  53. }
  54. .hint_msg {
  55. font-size: 12px;
  56. color: red;
  57. margin-top: 5px;
  58. }
  59. .change_table_btns {
  60. width: 100%;
  61. margin-top: 20px;
  62. display: flex;
  63. justify-content: center;
  64. padding: 10px;
  65. box-sizing: border-box;
  66. border-top: 10px solid #dee2ea;
  67. div {
  68. width: 80px;
  69. height: 30px;
  70. line-height: 30px;
  71. border-radius: 2px;
  72. border: 1px solid #21cbc7;
  73. color: #21cbc7;
  74. font-size: 14px;
  75. padding: 0 5px;
  76. margin: 0 30px;
  77. cursor: pointer;
  78. &:nth-child(1) {
  79. &:hover {
  80. background: rgba(97, 218, 215, 0.1);
  81. }
  82. }
  83. &:nth-child(2) {
  84. border-color: #ff5b5b;
  85. color: #ff5b5b;
  86. &:hover {
  87. background: rgba(255, 91, 91, 0.1);
  88. }
  89. }
  90. }
  91. }
  92. .rich_text {
  93. padding: 0 10px;
  94. }
  95. }
  96. .rich_text {
  97. }
  98. .quill-editor.ql-editor {
  99. padding-left: 0 !important;
  100. }
  101. /**富文本编辑器样式修改***/
  102. .ql-snow .ql-picker.ql-size .ql-picker-label::before,
  103. .ql-snow .ql-picker.ql-size .ql-picker-item::before,
  104. .ql-snow .ql-picker.ql-header .ql-picker-label::before,
  105. it .ql-editor,
  106. .quill-editor {
  107. padding-top: 0px !important;
  108. margin-top: -8px;
  109. min-height: 48px;
  110. p {
  111. padding-top: 8px;
  112. }
  113. }
  114. .ql-editor.ql-blank::before {
  115. padding-top: 0px;
  116. }
  117. .btns {
  118. margin-top: 20px;
  119. }
  120. </style>
  121. <template>
  122. <div class="add_assess">
  123. <el-form
  124. size="mini"
  125. :model="scaleData"
  126. label-position="left"
  127. ref="scaleFormRef"
  128. >
  129. <div
  130. class="table_map"
  131. v-for="(table, tableIndex) in scaleData.klScaleParent"
  132. :key="tableIndex"
  133. >
  134. <h5><span>*</span>量表内容:</h5>
  135. <div class="table_top_box">
  136. <div class="table_top_box_left">
  137. <el-form-item label="标题:" label-width="70px">
  138. <el-input maxlength="20" v-model.trim="table.content" />
  139. </el-form-item>
  140. <div style="margin: 0 20px">
  141. <el-form-item label="内容类型:" label-width="100px">
  142. <el-select
  143. v-model="table.textType"
  144. placeholder="请选择"
  145. @change="initializationTableData($event, tableIndex)"
  146. >
  147. <el-option label="问题选项" :value="11"> </el-option>
  148. <el-option label="概述文本" :value="12"> </el-option>
  149. </el-select>
  150. </el-form-item>
  151. <div class="hint_msg">
  152. 注:内容类型修改后已填的所在标题下的内容将会清空
  153. </div>
  154. </div>
  155. <div v-if="table.textType === 11">
  156. <el-form-item label="结果类型:" label-width="100px">
  157. <el-radio-group
  158. v-model="table.resultType"
  159. @change="initializationTableData($event, tableIndex)"
  160. >
  161. <el-radio :label="1">直接结果</el-radio>
  162. <el-radio :label="2">记分结果</el-radio>
  163. </el-radio-group>
  164. </el-form-item>
  165. <div class="hint_msg">
  166. 注:结果类型修改后已填的所在标题下的内容将会清空
  167. </div>
  168. </div>
  169. <div
  170. class="num_box"
  171. v-if="table.resultType === 2 && table.textType === 11"
  172. >
  173. <el-form-item label="系数:" label-width="60px">
  174. <el-input v-model.trim="table.factor" />
  175. </el-form-item>
  176. <el-form-item
  177. label="常数:"
  178. label-width="60px"
  179. style="margin-left: 10px"
  180. >
  181. <el-input v-model.trim="table.constant" />
  182. </el-form-item>
  183. </div>
  184. </div>
  185. <div class="move_btn" v-if="scaleData.klScaleParent.length > 1">
  186. <div
  187. @click="CHANGE_TABLE({ tableIndex, type: 'up' })"
  188. @mouseover="moveTopHover = true"
  189. @mouseout="moveTopHover = false"
  190. v-if="tableIndex"
  191. title="上移"
  192. >
  193. <img
  194. :src="
  195. moveTopHover
  196. ? require('@/images/icon_hover_top.png')
  197. : require('@/images/icon_default_top.png')
  198. "
  199. alt=""
  200. />
  201. </div>
  202. <div
  203. v-if="tableIndex !== scaleData.klScaleParent.length - 1"
  204. @click="CHANGE_TABLE({ tableIndex, type: 'down' })"
  205. @mouseover="moveBottomHover = true"
  206. @mouseout="moveBottomHover = false"
  207. title="下移"
  208. >
  209. <img
  210. :src="
  211. moveBottomHover
  212. ? require('@/images/icon_hover_down.png')
  213. : require('@/images/icon_default_down.png')
  214. "
  215. alt=""
  216. />
  217. </div>
  218. </div>
  219. </div>
  220. <ScaleTable
  221. v-if="table.textType === 11"
  222. :tableData="table.klScaleSaveGroup"
  223. :tableIndex="tableIndex"
  224. :tableResultType="table.resultType"
  225. @CHANGE_FORM_DATA="CHANGE_FORM_DATA"
  226. @CHANGE_TABLE_ROW="CHANGE_TABLE_ROW"
  227. />
  228. <div class="rich_text" v-if="table.textType === 12">
  229. <el-form-item
  230. label="概述:"
  231. prop="content"
  232. label-width="100px"
  233. ref="editor"
  234. >
  235. <quillEditor
  236. v-model="table.klScaleSaveGroup[0].content"
  237. :options="editorOption"
  238. class="ql-editor"
  239. ref="quillEditor"
  240. ></quillEditor>
  241. </el-form-item>
  242. </div>
  243. <div class="change_table_btns">
  244. <div @click="CHANGE_TABLE({ tableIndex, type: 1 })">
  245. <i class="el-icon-plus"></i>
  246. 新增标题
  247. </div>
  248. <div
  249. v-if="scaleData.klScaleParent.length > 1"
  250. @click="CHANGE_TABLE({ tableIndex, type: -1 })"
  251. >
  252. <i class="el-icon-minus"></i>
  253. 删除标题
  254. </div>
  255. </div>
  256. </div>
  257. <ScoreResultsTable
  258. :list="scoreresultsdatas"
  259. @CHANEG_SCORE_RESULT="CHANEG_SCORE_RESULT"
  260. />
  261. </el-form>
  262. </div>
  263. </template>
  264. <script>
  265. import ScaleTable from "./scale-table.vue";
  266. import "quill/dist/quill.core.css";
  267. import "quill/dist/quill.snow.css";
  268. import "quill/dist/quill.bubble.css";
  269. import { quillEditor, Quill } from "vue-quill-editor";
  270. import config from "@api/config";
  271. import { container, ImageExtend, QuillWatch } from "quill-image-extend-module";
  272. Quill.register("modules/ImageExtend", ImageExtend);
  273. import ScoreResultsTable from "./ScoreResultsTable.vue";
  274. import rules from "./rules";
  275. const defaultDate = {
  276. groupId: "",
  277. issueId: "",
  278. two_constant: "",
  279. two_content: "",
  280. two_factor: "",
  281. two_orderNo: 0,
  282. two_remark: "",
  283. two_resultType: 0,
  284. two_ruleCode: "",
  285. two_score: 0,
  286. two_selectType: 1,
  287. two_status: 0,
  288. two_textType: 0,
  289. content: "",
  290. orderNo: 0,
  291. pushInfo: "",
  292. remark: "",
  293. result: "",
  294. ruleCode: "",
  295. score: 0,
  296. status: 0,
  297. textType: 11
  298. };
  299. const defaultTable = {
  300. constant: 0,
  301. content: "",
  302. factor: 0,
  303. klScaleSaveGroup: [
  304. {
  305. ...defaultDate
  306. }
  307. ],
  308. orderNo: 0,
  309. remark: "string",
  310. resultType: 1,
  311. ruleCode: "string",
  312. score: 0,
  313. status: 0,
  314. textType: 11
  315. };
  316. export default {
  317. components: { ScaleTable, quillEditor, ScoreResultsTable },
  318. data() {
  319. return {
  320. rules: rules,
  321. moveTopHover: false,
  322. moveBottomHover: false,
  323. scaleData: {
  324. conceptId: 0,
  325. klScaleParent: [
  326. // 表格层
  327. {
  328. constant: 0,
  329. content: "",
  330. factor: 0,
  331. klScaleSaveGroup: [
  332. // 问题层+结果层(包括分组)
  333. {
  334. groupId: 0,
  335. issueId: 0,
  336. two_constant: "",
  337. two_content: "",
  338. two_factor: "",
  339. two_orderNo: 0,
  340. two_remark: "",
  341. two_resultType: 0,
  342. two_ruleCode: "",
  343. two_score: 0,
  344. two_selectType: 1,
  345. two_status: 0,
  346. two_textType: 0,
  347. content: "",
  348. orderNo: 0,
  349. pushInfo: "",
  350. remark: "",
  351. result: "",
  352. ruleCode: "",
  353. score: 0,
  354. status: 0,
  355. textType: 0
  356. }
  357. ],
  358. orderNo: 0,
  359. remark: "string",
  360. resultType: 1,
  361. ruleCode: "string",
  362. score: 0,
  363. status: 0,
  364. textType: 11
  365. }
  366. ],
  367. modifier: "string"
  368. },
  369. toolbars: [
  370. [
  371. ["bold", "underline", "strike"],
  372. [{ list: "ordered" }, { list: "bullet" }],
  373. [{ script: "sub" }, { script: "super" }],
  374. [{ color: [] }, { background: [] }],
  375. [{ align: [] }],
  376. ["image"]
  377. ]
  378. ],
  379. editorOption: {
  380. modules: {
  381. ImageExtend: {
  382. loading: true,
  383. name: "upfile",
  384. size: 1,
  385. sizeError: () => {
  386. this.$message({
  387. showClose: true,
  388. message: "请上传 1M 以内的图片!",
  389. type: "warning"
  390. });
  391. },
  392. action: config.urls.promptServer,
  393. response: (res) => {
  394. if (res.code == "0") {
  395. return config.imgHost + res.data.url;
  396. } else {
  397. this.$message({
  398. showClose: true,
  399. message: res.msg,
  400. type: "warning"
  401. });
  402. }
  403. }
  404. },
  405. toolbar: {
  406. container: container,
  407. handlers: {
  408. image: function () {
  409. QuillWatch.emit(this.quill.id);
  410. }
  411. }
  412. }
  413. }
  414. },
  415. toolbarMode: 0,
  416. ScoreResultsData: {
  417. //得分结果提交格式
  418. constant: null,
  419. content: "得分结果",
  420. factor: "",
  421. klScaleSaveGroup: {
  422. groupNum: 0,
  423. klScaleSub: [
  424. {
  425. constant: 0,
  426. content: "得分范围",
  427. factor: 0,
  428. klScaleDetail: [
  429. {
  430. content: "string",
  431. orderNo: 0,
  432. pushInfo: "string",
  433. remark: "string",
  434. result: "string",
  435. ruleCode: "string",
  436. score: 0,
  437. status: 0,
  438. textType: 0
  439. }
  440. ],
  441. orderNo: 0,
  442. remark: "string",
  443. resultType: 0,
  444. ruleCode: "string",
  445. score: 0,
  446. selectType: 0,
  447. status: 0,
  448. textType: 0
  449. }
  450. ]
  451. }
  452. },
  453. scoreresultsdatas: [
  454. // todo me: 最后处理数据记得将orderNo设不唯一的值
  455. {
  456. content: {
  457. max: null,
  458. min: null
  459. },
  460. orderNo: null,
  461. pushInfo: "",
  462. remark: null,
  463. result: "",
  464. ruleCode: null,
  465. score: null,
  466. status: null,
  467. textType: null
  468. }
  469. ]
  470. };
  471. },
  472. methods: {
  473. /**
  474. * 增/删/得分结果表格
  475. * @param type : 1:add 0:remove
  476. * @param index :当前行索引
  477. */
  478. CHANEG_SCORE_RESULT(type, index) {
  479. console.log(type, index);
  480. if (type === 1) {
  481. this.scoreresultsdatas.splice(index + 1, 0, {
  482. content: {
  483. max: null,
  484. min: null
  485. },
  486. orderNo: null,
  487. pushInfo: "",
  488. remark: null,
  489. result: "",
  490. ruleCode: null,
  491. score: null,
  492. status: null,
  493. textType: null
  494. });
  495. } else {
  496. this.$delete(this.scoreresultsdatas, index);
  497. }
  498. },
  499. /**
  500. * 增/删/移动表格
  501. * @param tableIndex :当前表格
  502. * @param type :类型 1:新增;-1:删除;up:上移;down:下移
  503. */
  504. CHANGE_TABLE(val) {
  505. // 节流: 阻止用户频繁点击
  506. if (this.timer) return;
  507. this.timer = setTimeout(() => {
  508. clearTimeout(this.timer);
  509. this.timer = null;
  510. }, 500);
  511. const { tableIndex, type } = val;
  512. switch (type) {
  513. case 1:
  514. this.scaleData.klScaleParent.splice(
  515. tableIndex + 1,
  516. 0,
  517. JSON.parse(JSON.stringify(defaultTable))
  518. );
  519. break;
  520. case -1:
  521. this.$delete(this.scaleData.klScaleParent, tableIndex);
  522. break;
  523. case "up":
  524. const thisTable = this.scaleData.klScaleParent[tableIndex];
  525. const beforeTable = this.scaleData.klScaleParent[tableIndex - 1];
  526. this.$set(this.scaleData.klScaleParent, tableIndex - 1, thisTable);
  527. this.$set(this.scaleData.klScaleParent, tableIndex, beforeTable);
  528. break;
  529. case "down":
  530. const thisTable1 = this.scaleData.klScaleParent[tableIndex];
  531. const afterTable = this.scaleData.klScaleParent[tableIndex + 1];
  532. this.$set(this.scaleData.klScaleParent, tableIndex + 1, thisTable1);
  533. this.$set(this.scaleData.klScaleParent, tableIndex, afterTable);
  534. break;
  535. }
  536. },
  537. /**
  538. * 修改表格数据(添加、删除 :组、问题、选项)
  539. * @param type 类型:1/-1:新增/删除组; 2/-2:新增/删除问题; 3/-3:新增/删除选项
  540. * @param tableIndex 单个量表的index
  541. * @param rowIndex 表格 当前行的index
  542. * @param groupId 当前组id
  543. * @param issueId 当前问题id
  544. */
  545. CHANGE_TABLE_ROW(val) {
  546. // 节流: 阻止用户频繁点击
  547. if (this.timer) return;
  548. this.timer = setTimeout(() => {
  549. clearTimeout(this.timer);
  550. this.timer = null;
  551. }, 500);
  552. const { type, tableIndex, rowIndex, groupId, issueId } = val;
  553. const child = { ...defaultDate };
  554. switch (type) {
  555. case 1: //type 1: 添加组
  556. // 设置新的 groupId、issueId
  557. child.groupId = new Date().valueOf().toString();
  558. child.issueId = child.groupId + "-" + new Date().valueOf();
  559. // 使用当前的组id(groupId) 找到最后一个groupId为当前groupId的索引;
  560. let groupIndex;
  561. this.scaleData.klScaleParent[tableIndex].klScaleSaveGroup.forEach(
  562. (item, i) => {
  563. if (item.groupId === groupId) {
  564. groupIndex = i;
  565. }
  566. }
  567. );
  568. // 将新的组插入到当前组后边
  569. this.scaleData.klScaleParent[tableIndex].klScaleSaveGroup.splice(
  570. groupIndex + 1,
  571. 0,
  572. child
  573. );
  574. break;
  575. case 2: //type 2: 添加问题
  576. // 设置新的 groupId(相同的组id)、issueId
  577. child.groupId = groupId;
  578. child.issueId = child.groupId + "-" + new Date().valueOf();
  579. let issueIndex;
  580. // 使用当前的组id(issueId) 找到最后一个issueId为当前issueId的索引;
  581. this.scaleData.klScaleParent[tableIndex].klScaleSaveGroup.forEach(
  582. (item, i) => {
  583. if (item.issueId === issueId) {
  584. issueIndex = i;
  585. }
  586. }
  587. );
  588. // 将新的组插入到当前组后边
  589. this.scaleData.klScaleParent[tableIndex].klScaleSaveGroup.splice(
  590. issueIndex + 1,
  591. 0,
  592. child
  593. );
  594. break;
  595. case 3: //type 3: 添加选项
  596. // 设置新的 groupId(相同的组id)、issueId(相同的组问题id)
  597. child.groupId = groupId;
  598. child.issueId = issueId;
  599. // 将新的组插入到当前组后边
  600. this.scaleData.klScaleParent[tableIndex].klScaleSaveGroup.splice(
  601. rowIndex + 1,
  602. 0,
  603. child
  604. );
  605. break;
  606. case -1: //type -1: 删除组 => 删除所有组id为当前组id的数据
  607. const newTableBygroupId = this.scaleData.klScaleParent[
  608. tableIndex
  609. ].klScaleSaveGroup.filter((item) => item.groupId !== groupId);
  610. this.$set(
  611. this.scaleData.klScaleParent[tableIndex],
  612. "klScaleSaveGroup",
  613. newTableBygroupId
  614. );
  615. break;
  616. case -2: //type -2: 删除问题 => 删除所有问题id为当前问题id的数据
  617. const newTableByissueId = this.scaleData.klScaleParent[
  618. tableIndex
  619. ].klScaleSaveGroup.filter((item) => item.issueId !== issueId);
  620. this.$set(
  621. this.scaleData.klScaleParent[tableIndex],
  622. "klScaleSaveGroup",
  623. newTableByissueId
  624. );
  625. break;
  626. case -3: //type -3: 删除选项
  627. this.$delete(
  628. this.scaleData.klScaleParent[tableIndex].klScaleSaveGroup,
  629. rowIndex
  630. );
  631. break;
  632. }
  633. },
  634. CHANGE_FORM_DATA(tableIndex, rowIndex, name, val) {
  635. this.$set(
  636. this.scaleData.klScaleParent[tableIndex].klScaleSaveGroup[rowIndex],
  637. name,
  638. val
  639. );
  640. },
  641. // 清空选项
  642. initializationTableData(e, tableIndex) {
  643. console.log(this.scaleData.klScaleParent[tableIndex].klScaleSaveGroup);
  644. this.$set(this.scaleData.klScaleParent[tableIndex], "klScaleSaveGroup", [
  645. { ...defaultDate }
  646. ]);
  647. }
  648. },
  649. watch: {
  650. scaleData: {
  651. handler() {
  652. console.log("监听");
  653. },
  654. deep: true
  655. }
  656. },
  657. created() {
  658. this.editorOption.modules.toolbar.container =
  659. this.toolbars[this.toolbarMode];
  660. }
  661. };
  662. </script>