DevInfo.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. <template>
  2. <el-form
  3. :rules="rules"
  4. :model="data"
  5. ref="form"
  6. class="sub-form"
  7. size="mini"
  8. :validate-on-rule-change="false"
  9. >
  10. <!--<el-input v-model="form.orderNo" :value="index" type="hidden"></el-input>-->
  11. <!-- <el-form-item label="是否属于诊断依据:" prop="isReason" label-width="160px">
  12. <el-select v-model="data.isReason" placeholder="请选择">
  13. <el-option label="否" :value="0"></el-option>
  14. <el-option label="是" :value="1"></el-option>
  15. </el-select>
  16. </el-form-item>-->
  17. <el-form-item
  18. label="段落标题:"
  19. prop="title"
  20. label-width="160px"
  21. class="is-required"
  22. >
  23. <el-input v-model="data.title"></el-input>
  24. </el-form-item>
  25. <el-form-item label="内容类型:" prop="position" label-width="160px">
  26. <el-checkbox-group v-model="data.position">
  27. <el-checkbox v-for="it in positions" :key="it.key" :label="it.key">{{
  28. it.name
  29. }}</el-checkbox>
  30. </el-checkbox-group>
  31. </el-form-item>
  32. <el-form-item label="内容" prop="content" label-width="160px" ref="editor">
  33. <quillEditor
  34. v-model="data.content"
  35. :options="editorOption"
  36. class="ql-editor"
  37. ref="quillEditor"
  38. ></quillEditor>
  39. </el-form-item>
  40. <!-- <div class="order-btn">
  41. <a
  42. v-if="index !== 0"
  43. :class="index === total - 1 ? 'order-spc' : 'order-up'"
  44. @click="reOrder(1)"
  45. >上升</a
  46. >
  47. <a
  48. v-if="index !== total - 1"
  49. :class="index === 0 ? 'order-spc' : 'order-down'"
  50. @click="reOrder(0)"
  51. >下降</a
  52. >
  53. </div> -->
  54. <div class="move_btn">
  55. <div
  56. v-if="index !== 0"
  57. @mouseover="moveTopHover = true"
  58. @mouseout="moveTopHover = false"
  59. title="上升"
  60. @click="reOrder(1)"
  61. >
  62. <img
  63. :src="
  64. moveTopHover
  65. ? require('@/images/icon_hover_top.png')
  66. : require('@/images/icon_default_top.png')
  67. "
  68. alt=""
  69. />
  70. </div>
  71. <div
  72. v-if="index !== total - 1"
  73. @mouseover="moveBottomHover = true"
  74. @mouseout="moveBottomHover = false"
  75. title="下降"
  76. @click="reOrder(0)"
  77. >
  78. <img
  79. :src="
  80. moveBottomHover
  81. ? require('@/images/icon_hover_down.png')
  82. : require('@/images/icon_default_down.png')
  83. "
  84. alt=""
  85. />
  86. </div>
  87. </div>
  88. <el-form-item label-width="160px" class="btns">
  89. <!-- <el-button size="small" @click="addEmit">添加段落</el-button>
  90. <el-button size="small" @click="delEmit" type="info"
  91. >删除本段落</el-button
  92. > -->
  93. <div class="change_btns">
  94. <div @click="addEmit">新增标题</div>
  95. <div @click="delEmit">删除标题</div>
  96. </div>
  97. </el-form-item>
  98. </el-form>
  99. </template>
  100. <script>
  101. import "quill/dist/quill.core.css";
  102. import "quill/dist/quill.snow.css";
  103. import "quill/dist/quill.bubble.css";
  104. import { quillEditor, Quill } from "vue-quill-editor";
  105. import config from "@api/config";
  106. import { container, ImageExtend, QuillWatch } from "quill-image-extend-module";
  107. Quill.register("modules/ImageExtend", ImageExtend);
  108. export default {
  109. props: ["data", "index", "isEdit", "isCopy", "total", "showType"],
  110. name: "DevInfo",
  111. components: {
  112. quillEditor
  113. },
  114. data() {
  115. return {
  116. moveTopHover: false,
  117. moveBottomHover: false,
  118. toolbars: [
  119. [
  120. ["bold", "underline", "strike"],
  121. [{ list: "ordered" }, { list: "bullet" }],
  122. [{ script: "sub" }, { script: "super" }],
  123. [{ color: [] }, { background: [] }],
  124. [{ align: [] }],
  125. ["image"]
  126. ]
  127. ],
  128. toolbarMode: 0,
  129. editorOption: {
  130. modules: {
  131. ImageExtend: {
  132. loading: true,
  133. name: "upfile",
  134. size: 1,
  135. sizeError: () => {
  136. this.$message({
  137. showClose: true,
  138. message: "请上传 1M 以内的图片!",
  139. type: "warning"
  140. });
  141. },
  142. action: config.urls.promptServer,
  143. response: (res) => {
  144. if (res.code == "0") {
  145. return config.imgHost + res.data.url;
  146. } else {
  147. this.$message({
  148. showClose: true,
  149. message: res.msg,
  150. type: "warning"
  151. });
  152. }
  153. }
  154. },
  155. toolbar: {
  156. container: container,
  157. handlers: {
  158. image: function () {
  159. QuillWatch.emit(this.quill.id);
  160. }
  161. }
  162. }
  163. }
  164. },
  165. form: {
  166. position: [],
  167. orderNo: 0
  168. },
  169. positions: [], //位置列表
  170. rules: {}
  171. };
  172. },
  173. watch: {
  174. "data.content": function () {
  175. if (this.data.content !== "") {
  176. this.$refs.editor && this.$refs.editor.clearValidate(); // 清除校验
  177. }
  178. if (this.data.content === "") {
  179. // console.log('内容为空');
  180. this.$refs["form"].validateField("content"); // 手动校验
  181. }
  182. this.data.text = this.$refs.quillEditor.quill.root.innerText;
  183. }
  184. },
  185. created() {
  186. // console.log(this.showType, 'showType','需要显示的类型');
  187. this.editorOption.modules.toolbar.container =
  188. this.toolbars[this.toolbarMode];
  189. this.renderPositions();
  190. if (this.isEdit || this.isCopy) {
  191. setTimeout(() => {
  192. this.rules = {
  193. position: [
  194. { required: true, message: "请选择内容类型", trigger: "change" }
  195. ],
  196. title: [
  197. {
  198. validator: (rule, value, callback) => {
  199. if (!value.trim()) {
  200. callback(new Error("请输入段落标题"));
  201. } else {
  202. callback();
  203. }
  204. },
  205. trigger: "change"
  206. },
  207. { max: 30, message: "标题名称不能超过30字", trigger: "change" }
  208. ],
  209. content: [
  210. { required: true, message: "请输入段落内容", trigger: "change" }
  211. ]
  212. };
  213. }, 100);
  214. } else {
  215. this.rules = {
  216. position: [
  217. { required: true, message: "请选择内容类型", trigger: "change" }
  218. ],
  219. title: [
  220. {
  221. validator: (rule, value, callback) => {
  222. if (!value.trim()) {
  223. callback(new Error("请输入段落标题"));
  224. } else {
  225. callback();
  226. }
  227. },
  228. trigger: "change"
  229. },
  230. { max: 30, message: "标题名称不能超过30字", trigger: "change" }
  231. ],
  232. content: [
  233. { required: true, message: "请输入段落内容", trigger: "change" }
  234. ]
  235. };
  236. }
  237. setTimeout(() => {
  238. this.filterHiddenPosition();
  239. }, 200);
  240. },
  241. mounted() {},
  242. methods: {
  243. reOrder(i) {
  244. this.$emit("reOrder", i, this.index);
  245. },
  246. addEmit() {
  247. this.$emit("add");
  248. },
  249. delEmit() {
  250. this.$emit("del", this.index);
  251. },
  252. filterHiddenPosition() {
  253. const pos = this.data.position;
  254. const pArr = this.positions.map((it) => {
  255. return it.key;
  256. });
  257. const pStr = pArr.join(",");
  258. const arr = pos.filter((it) => {
  259. return pStr.indexOf(it) > -1;
  260. });
  261. this.data.position = arr;
  262. },
  263. // 渲染内容类型
  264. renderPositions() {
  265. //显示位置枚举列表
  266. const pos = localStorage.getItem("knowledgeEnumsData");
  267. let positions = config.contentTypes;
  268. if (this.showType == 1) {
  269. // 诊断
  270. this.positions = positions.filter((item) => item.key !== 2);
  271. } else if (
  272. this.showType == 3 ||
  273. this.showType == 4 ||
  274. this.showType == 5 ||
  275. this.showType == 6
  276. ) {
  277. // 检验/检查
  278. this.positions = positions.filter((item) => {
  279. return item.key <= 2;
  280. });
  281. } else if (
  282. this.showType == 2 ||
  283. this.showType == 7 ||
  284. this.showType == 8 ||
  285. this.showType == 9
  286. ) {
  287. // 药品/手术
  288. this.positions = positions.filter((item) => item.key === 1);
  289. } else {
  290. this.positions = positions;
  291. }
  292. }
  293. /*emitVal(){
  294. let data = this.form;
  295. let pst=this.form.position;
  296. const content = this.form.content.replace(config.imgHost,'{imageUrlPrefix}');
  297. const text = this.$refs.quillEditor;console.log(text)
  298. pst = typeof pst=='string'?pst:pst.join(',');
  299. data = Object.assign({},data,{
  300. position:this.form.position?pst:'',
  301. orderNo:this.index,
  302. text:'',
  303. content:content});
  304. this.$emit("change",this.index,data);
  305. }*/
  306. }
  307. };
  308. </script>
  309. <style lang="less" scoped>
  310. .quill-editor.ql-editor {
  311. padding-left: 0 !important;
  312. }
  313. .is-error .el-form-item__error {
  314. top: auto;
  315. }
  316. .sub-form {
  317. position: relative;
  318. }
  319. .order-btn {
  320. // position: absolute;
  321. top: 12px;
  322. right: 0;
  323. display: flex;
  324. a {
  325. margin-bottom: 20px;
  326. border: 1px solid #22ccc8;
  327. color: #22ccc8;
  328. padding: 5px 10px;
  329. border-radius: 4px;
  330. cursor: pointer;
  331. font-size: 12px;
  332. }
  333. .order-spc {
  334. margin-top: 28px;
  335. }
  336. .order-down {
  337. margin-left: 20px;
  338. }
  339. }
  340. /**富文本编辑器样式修改***/
  341. .ql-snow .ql-picker.ql-size .ql-picker-label::before,
  342. .ql-snow .ql-picker.ql-size .ql-picker-item::before,
  343. .ql-snow .ql-picker.ql-header .ql-picker-label::before,
  344. it .ql-editor,
  345. .quill-editor {
  346. padding-top: 0px !important;
  347. margin-top: -8px;
  348. min-height: 48px;
  349. p {
  350. padding-top: 8px;
  351. }
  352. }
  353. .ql-editor.ql-blank::before {
  354. padding-top: 0px;
  355. }
  356. .btns {
  357. margin-top: 20px;
  358. }
  359. .move_btn {
  360. position: absolute;
  361. top: 12px;
  362. right: 0;
  363. font-size: 14px;
  364. margin-left: 10px;
  365. display: flex;
  366. div {
  367. width: 12px;
  368. height: 16px;
  369. margin-right: 8px;
  370. img {
  371. width: 100%;
  372. height: 100%;
  373. cursor: pointer;
  374. }
  375. }
  376. }
  377. /deep/ .el-form-item.is-success .el-input__inner,
  378. .el-form-item.is-success .el-textarea__inner {
  379. border-color: #c9c9c9 !important;
  380. }
  381. /deep/ .el-form-item.is-success .el-textarea__inner {
  382. border-color: #c9c9c9 !important;
  383. }
  384. /deep/ .el-form-item.is-success .el-textarea__inner {
  385. border-color: #c9c9c9 !important;
  386. }
  387. .change_btns {
  388. // width: 100%;
  389. margin-top: 10px;
  390. display: flex;
  391. box-sizing: border-box;
  392. div {
  393. width: 90px;
  394. height: 30px;
  395. line-height: 30px;
  396. text-align: center;
  397. border-radius: 2px;
  398. border: 1px solid #21cbc7;
  399. color: #21cbc7;
  400. font-size: 14px;
  401. margin-right: 30px;
  402. cursor: pointer;
  403. &:nth-child(1) {
  404. &:hover {
  405. background: rgba(97, 218, 215, 0.1);
  406. }
  407. }
  408. &:nth-child(2) {
  409. border-color: #ff5b5b;
  410. color: #ff5b5b;
  411. &:hover {
  412. background: rgba(255, 91, 91, 0.1);
  413. }
  414. }
  415. }
  416. }
  417. </style>