contentOperation.vue 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097
  1. <template>
  2. <div class="m-container">
  3. <h2>
  4. <el-page-header @back="onCancel"
  5. :content="(pageType == 'create' ? '添加' : '修改') + typeChange(type)"></el-page-header>
  6. </h2>
  7. <div class="m-core">
  8. <el-form :model="form"
  9. :rules="rules"
  10. ref="form"
  11. label-width="120px"
  12. style="width: 100%">
  13. <el-form-item label="标题"
  14. prop="title">
  15. <el-input v-model.trim="form.title" placeholder="请输入标题"></el-input>
  16. </el-form-item>
  17. <el-form-item label="排序值" prop="order">
  18. <el-input v-model.trim="form.order" placeholder=""></el-input>
  19. </el-form-item>
  20. <!-- 平台的功能不需要选择分部 -->
  21. <el-form-item label="所属分部"
  22. v-if="type != 4 && type != 6"
  23. prop="organIdList">
  24. <select-all v-model.trim="form.organIdList"
  25. style="width: 400px !important"
  26. filterable
  27. placeholder="请选择分部"
  28. multiple
  29. clearable>
  30. <el-option v-for="(item,index) in selects.branchs"
  31. :key="index"
  32. :label="item.name"
  33. :value="item.id"></el-option>
  34. </select-all>
  35. </el-form-item>
  36. <el-form-item
  37. prop="subjectIdList" v-if="type == 7"
  38. label="所属声部"
  39. :rules="[{required: true, message:'请选择声部', trigger: 'blur, change'}]">
  40. <select-all v-model="form.subjectIdList" clearable filterable multiple placeholder="请选择声部" style="width: 400px !important">
  41. <el-option v-for="item in selects.subjects" :value="item.id" :label="item.name" :key="item.id"></el-option>
  42. </select-all>
  43. </el-form-item>
  44. <!-- banner图 && app按钮管理, 广告管理才需要添加版本号 -->
  45. <el-form-item label="版本号" prop="memo"
  46. v-if="type == 3 || type == 6 || type == 8">
  47. <el-input v-model="form.memo"></el-input>
  48. </el-form-item>
  49. <!-- 1 2 4 7 -->
  50. <el-form-item label="跳转方式" v-if="type == 1 || type == 2 || type == 4 || type == 7">
  51. <el-radio-group v-model="outUrlRadio">
  52. <el-radio :label="1">外部链接</el-radio>
  53. <el-radio :label="0">内容跳转</el-radio>
  54. </el-radio-group>
  55. </el-form-item>
  56. <!-- :rules='[{ required: type == 3 || type == 6 || type == 5 || type == 8 ? false : true, message: "请输入链接地址", trigger: "blur" }]' -->
  57. <!-- 1 2 4 7 -->
  58. <el-form-item label="链接地址" prop="linkUrl" v-if="outUrlRadio == 1"
  59. :rules='[{ required: (type == 3 || type == 6 || type == 5 || type == 8) ? false : true, message: "请输入链接地址", trigger: "blur" }]'>
  60. <el-input v-model.trim="form.linkUrl"></el-input>
  61. </el-form-item>
  62. <!-- 闪页, BANNER, 广告页 -->
  63. <el-form-item label="上架时间" v-if="type == 5 || type == 8 || type == 3" prop="actionTime">
  64. <el-date-picker style="width:400px;"
  65. v-model="form.actionTime"
  66. :clearable="true"
  67. type="datetimerange"
  68. :default-time="['00:00:00', '23:59:59']"
  69. range-separator="至"
  70. :picker-options="{ firstDayOfWeek: 1 }"
  71. start-placeholder="上架开始日期"
  72. end-placeholder="上架结束日期">
  73. </el-date-picker>
  74. </el-form-item>
  75. <!-- 广告管理才有类型 -->
  76. <el-form-item label="广告类型"
  77. v-if="type == 8">
  78. <el-select v-model="uploadType" style="width: 400px !important"
  79. :disabled="pageType != 'create'">
  80. <el-option label="图片"
  81. :value="1"></el-option>
  82. <el-option label="视频"
  83. :value="2"></el-option>
  84. </el-select>
  85. </el-form-item>
  86. <el-form-item v-if="uploadType == 2 && type == 8"
  87. key="coverImage"
  88. label="广告视频"
  89. prop="coverImage">
  90. <div @click="addAdvVideo"
  91. style="display: inline-block;">
  92. <video class="avatar"
  93. v-if="form.coverImage"
  94. type="video/mp4"
  95. preload="auto"
  96. :poster="form.videoCoverImage"
  97. :src="form.coverImage"></video>
  98. <i v-else
  99. class="el-icon-plus avatar-uploader-icon"></i>
  100. </div>
  101. <p style="color: red">上传视频尺寸建议:1242px * 2208px;</p>
  102. </el-form-item>
  103. <el-form-item v-else
  104. key="coverImage1"
  105. :label="type == 8 ? '广告图' : '封面图'"
  106. prop="coverImage">
  107. <el-upload class="avatar-uploader"
  108. action="/api-web/uploadFile"
  109. :headers="headers"
  110. :show-file-list="false"
  111. v-loading="uploadCoverLoading"
  112. accept=".jpg, .jpeg, .png, .gif"
  113. :on-success="handleAvatarSuccess"
  114. :on-error="handleAvatarError"
  115. :before-upload="beforeAvatarUpload">
  116. <img v-if="form.coverImage"
  117. :src="form.coverImage"
  118. class="avatar" />
  119. <i v-else
  120. class="el-icon-plus avatar-uploader-icon"></i>
  121. </el-upload>
  122. <!-- <image-cropper :options="cropperOptions" :imgSize="2" showSize :imageUrl="form.coverImage" @crop-upload-success="cropSuccess" /> -->
  123. <p class="imageSize">图片不能超过 2M;</p>
  124. </el-form-item>
  125. <!-- 广告管理才有时长 -->
  126. <el-form-item label="显示时长(秒)"
  127. prop="attribute1"
  128. :rules="[{required: true, validator: validNum, trigger: 'blur'}]"
  129. v-if="type == 8">
  130. <el-input type="number"
  131. v-model.number="form.attribute1"></el-input>
  132. <p style="color: red">建议时长不超过5秒</p>
  133. </el-form-item>
  134. <!-- 知识库管理才会有类型 -->
  135. <el-form-item v-if="type == 7 || type == 2"
  136. :label="type == 7 ? '知识类别' : '资讯类别'"
  137. prop="subType"
  138. :rules="[{ required: true, message: (type == 7 ? '请选择知识类别' : '请选择资讯类别'), trigger: 'change' }]">
  139. <el-select v-model="form.subType" style="width: 400px !important">
  140. <el-option v-for="item in typeList" :key="item.id" :label="item.name" :value="item.id"></el-option>
  141. </el-select>
  142. </el-form-item>
  143. <!-- 闪页管理 BANNER管理 APP按钮管理 广告管理 广告管理的上传图片-->
  144. <el-form-item label="内容"
  145. v-show="type != 8 && type != 5 && type != 3 && type != 6 && outUrlRadio != 1"
  146. prop="content"
  147. :rules="[{ required: type != 8 && type != 5 && type != 3 && type != 6 && outUrlRadio != 1 ? true : false, message: '请编辑内容', trigger: 'blur' }]">
  148. <!-- <quill-editor class="ql-editor"
  149. v-model="form.content"
  150. ref="myQuillEditor"
  151. :options="editorOption"
  152. @change="onEditorChange($event)"></quill-editor>
  153. <el-upload class="ivu-upload"
  154. :show-upload-list="false"
  155. :headers="headers"
  156. :on-success="handleSuccess"
  157. accept=".jpg, .jpeg, .png, .gif"
  158. :max-size="2048"
  159. multiple
  160. action="/api-web/uploadFile">
  161. <Button icon="ios-cloud-upload-outline"></Button>
  162. </el-upload> -->
  163. <Editor :form="form.content" id='Editor1' alias="Editor1" ref="opFlow" :keyWord="'opFlow'" class="Editor" @onEditorChange='onEditorChange'/>
  164. </el-form-item>
  165. <el-form-item>
  166. <el-button @click="onSubmit('form')"
  167. type="primary">立即{{ pageType == "create" ? '创建' : '修改' }}</el-button>
  168. <el-button @click="onReSet('form')">重置</el-button>
  169. <el-button @click="onLook"
  170. v-if="type != 8 && type != 5 && type != 3 && type != 6">预览</el-button>
  171. </el-form-item>
  172. </el-form>
  173. </div>
  174. <el-dialog title="插入视频"
  175. width="500px"
  176. @close="onDialogClose('diologForm')"
  177. :visible.sync="dialogFormVisible">
  178. <el-form :model="dialogForm"
  179. ref="diologForm"
  180. :rules="dialogFormRules">
  181. <el-form-item label="封面图地址"
  182. prop="poster"
  183. :rules="[{required: uploadType == 2 ? true : false, message: '请上传封面图', trigger: 'blur'}]"
  184. label-width="120px">
  185. <el-upload class="avatar-uploader"
  186. style="line-height: 0;display: inline-block"
  187. action="/api-web/uploadFile"
  188. :headers="headers"
  189. :show-file-list="false"
  190. v-loading="uploadImgLoading"
  191. accept=".jpg, .jpeg, .png, .gif"
  192. :on-success="handleImgSuccess"
  193. :on-error="handleUploadImgError"
  194. :before-upload="beforeImgUpload">
  195. <img v-if="dialogForm.poster"
  196. :src="dialogForm.poster"
  197. class="avatar" />
  198. <i v-else
  199. class="el-icon-plus avatar-uploader-icon"></i>
  200. </el-upload>
  201. </el-form-item>
  202. <el-form-item label="视频类型"
  203. label-width="120px">
  204. <el-radio-group v-model="formRadio">
  205. <el-radio :label="1">外部链接</el-radio>
  206. <el-radio :label="2">上传</el-radio>
  207. </el-radio-group>
  208. </el-form-item>
  209. <el-form-item v-if="formRadio == 1"
  210. label="视频地址"
  211. label-width="120px"
  212. prop="url">
  213. <el-input v-model="dialogForm.url"
  214. style="width: 100%;"
  215. autocomplete="off"></el-input>
  216. </el-form-item>
  217. <el-form-item v-if="formRadio == 2"
  218. label="上传视频"
  219. label-width="120px"
  220. prop="videoUrl">
  221. <el-upload class="upload-demo"
  222. style="display: inline-block"
  223. v-loading="uploadLoading"
  224. action="/api-web/uploadFile"
  225. :before-upload="beforeUpload"
  226. :on-success="handleUploadSuccess"
  227. :on-error="handleUploadError"
  228. :show-file-list="false"
  229. accept=".mp4"
  230. :file-list="fileList"
  231. :on-exceed="handleExceed">
  232. <video style="width: 120px; height: 120px"
  233. v-if="dialogForm.videoUrl"
  234. type="video/mp4"
  235. preload="auto"
  236. :src="dialogForm.videoUrl"></video>
  237. <i v-else
  238. class="el-icon-plus avatar-uploader-icon"></i>
  239. </el-upload>
  240. <p class="imageSize">
  241. <!-- 广告管理 & 广告类型为 视频 -->
  242. <span v-if="uploadType == 2 && type == 8">上传视频尺寸建议:1242px * 2208px;</span><br />
  243. 只能上传mp4文件, 且不超过100M
  244. </p>
  245. </el-form-item>
  246. </el-form>
  247. <div slot="footer"
  248. class="dialog-footer">
  249. <el-button @click="dialogFormVisible = false">取 消</el-button>
  250. <el-button type="primary"
  251. @click="onVideoComfirm('diologForm')">确 定</el-button>
  252. </div>
  253. </el-dialog>
  254. <el-dialog width="375px" title="预览"
  255. :visible.sync="lookVisible">
  256. <div class="sd-container">
  257. <h2>{{ dataInfo.title }}</h2>
  258. <div class="titleInfo">
  259. <!-- <p>{{ dataInfo.tenantId == 2 ? '' : '管乐迷' }}</p> -->
  260. <p>{{ typeCheck(dataInfo.type) }}</p>
  261. <p>{{ dataInfo.updateTime }}</p>
  262. </div>
  263. <div class="msgWrap quill-editor ql-editor"
  264. v-html="dataInfo.content"></div>
  265. </div>
  266. </el-dialog>
  267. </div>
  268. </template>
  269. <script>
  270. import { newsQueryId, newsAdd, newsUpdate, newsTypeList } from "@/api/contentManager";
  271. import store from "@/store";
  272. import { getToken } from "@/utils/auth";
  273. import { vaildStudentUrl } from "@/utils/validate";
  274. import "quill/dist/quill.core.css";
  275. import "quill/dist/quill.snow.css";
  276. import "quill/dist/quill.bubble.css";
  277. import Quill from "quill";
  278. import { quillEditor } from "vue-quill-editor";
  279. import Editor from "@/components/Editor";
  280. // 工具栏配置
  281. const toolbarOptions = [
  282. ["bold", "italic", "underline", "strike"], // 加粗 斜体 下划线 删除线
  283. ["blockquote", "code-block"], // 引用 代码块
  284. [{ header: 1 }, { header: 2 }], // 1、2 级标题
  285. [{ list: "ordered" }, { list: "bullet" }], // 有序、无序列表
  286. [{ script: "sub" }, { script: "super" }], // 上标/下标
  287. [{ indent: "-1" }, { indent: "+1" }], // 缩进
  288. // [{'direction': 'rtl'}], // 文本方向
  289. [{ size: ["small", false, "large", "huge"] }], // 字体大小
  290. [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题
  291. [{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色
  292. [{ font: [] }], // 字体种类
  293. [{ align: [] }], // 对齐方式
  294. ["clean"], // 清除文本格式
  295. ["image", "video"] // 链接、图片、视频
  296. // ["link", "image", "video"] // 链接、图片、视频
  297. ];
  298. // 标题
  299. const titleConfig = {
  300. "ql-bold": "加粗",
  301. "ql-color": "颜色",
  302. "ql-font": "字体",
  303. "ql-code": "插入代码",
  304. "ql-italic": "斜体",
  305. // 'ql-link': '添加链接',
  306. "ql-background": "背景颜色",
  307. "ql-size": "字体大小",
  308. "ql-strike": "删除线",
  309. "ql-script": "上标/下标",
  310. "ql-underline": "下划线",
  311. "ql-blockquote": "引用",
  312. "ql-header": "标题",
  313. "ql-indent": "缩进",
  314. "ql-list": "列表",
  315. "ql-align": "文本对齐",
  316. "ql-direction": "文本方向",
  317. "ql-code-block": "代码块",
  318. "ql-formula": "公式",
  319. "ql-image": "图片",
  320. "ql-video": "视频",
  321. "ql-clean": "清除字体样式",
  322. "ql-upload": "文件"
  323. };
  324. let validNum = (rule, value, callback) => {
  325. if (typeof value == 'string' || value == null) {
  326. callback(new Error('请输入显示时长'))
  327. } else if (value < 0) {
  328. callback(new Error('输入显示时长必须大于0'))
  329. } else {
  330. callback()
  331. }
  332. }
  333. import ImageCropper from '@/components/ImageCropper'
  334. // 这里引入修改过的video模块并注册
  335. import Video from "../quill/video.js";
  336. import dayjs from 'dayjs'
  337. Quill.register(Video, true);
  338. export default {
  339. name: "contentOperation",
  340. components: {
  341. quillEditor,
  342. ImageCropper,
  343. Editor
  344. },
  345. data () {
  346. let that = this;
  347. const query = this.$route.query
  348. let url = ''
  349. // let url = query.type == 7 ? vaildStudentUrl() + "/#/knowledge" : vaildStudentUrl() + "/#/specialdetail"
  350. // console.log(query.type)
  351. if (query.type == 7) {
  352. url = vaildStudentUrl() + "/#/knowledge"
  353. } else if (query.type == 8 || query.type == 5) {
  354. url = ''
  355. } else {
  356. url = vaildStudentUrl() + "/#/specialdetail"
  357. }
  358. return {
  359. validNum: validNum,
  360. uploadType: 1, // 上传类型
  361. uploadStatus: false,
  362. categoryList: [],
  363. type: query.type,
  364. pageType: query.pageType,
  365. organId: null,
  366. headers: {
  367. Authorization: getToken()
  368. },
  369. content: null,
  370. dialogFormVisible: false,
  371. formRadio: 1,
  372. lookVisible: false,
  373. dataInfo: {
  374. title: '',
  375. type: query.type,
  376. updateTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
  377. content: null
  378. },
  379. outUrlRadio: 1, // 默认使用内部连接跳转
  380. editorIndex: 0, // 光标位置
  381. editorOption: {
  382. placeholder: "请输入内容",
  383. modules: {
  384. toolbar: {
  385. container: toolbarOptions,
  386. handlers: {
  387. image: function (value) {
  388. if (value) {
  389. // 调用iview图片上传
  390. document.querySelector(".ivu-upload .el-upload").click();
  391. } else {
  392. this.quill.format("image", false);
  393. }
  394. },
  395. video: function (value) {
  396. if (value) {
  397. that.dialogFormVisible = true;
  398. let editor = that.$refs.myQuillEditor.quill;
  399. that.editorIndex = editor.getSelection().index;
  400. } else {
  401. this.quill.format("image", false);
  402. }
  403. }
  404. }
  405. }
  406. }
  407. },
  408. dialogForm: {
  409. poster: null,
  410. url: null,
  411. videoUrl: null
  412. },
  413. uploadCoverLoading: false,
  414. uploadLoading: false, // 上传视屏loading
  415. uploadImgLoading: false, // 上传封面图地址 loading
  416. fileList: [],
  417. dialogFormRules: {
  418. url: [{ required: true, message: "请输入视频地址", trigger: "blur" }],
  419. videoUrl: [{ required: true, message: "请上传视频", trigger: 'blur' }]
  420. },
  421. form: {
  422. title: null,
  423. order: null,
  424. // tenantId: null,
  425. coverImage: null,
  426. videoCoverImage: null,
  427. attribute1: null, // 时长
  428. linkUrl: null,
  429. subjectIdList: null, // 声部编号
  430. type: query.type,
  431. status: 1,
  432. content: null,
  433. subType: null,
  434. actionTime: null,
  435. organIdList: [],
  436. },
  437. rules: {
  438. title: [
  439. { required: true, message: "请输入标题", trigger: "blur" },
  440. { min: 2, max: 30, message: "长度在 2 到 30 个字符", trigger: "blur" }
  441. ],
  442. coverImage: [
  443. { required: true, message: '请选择封面图或广告视频', trigger: "blur" }
  444. ],
  445. organIdList: [{ required: true, message: "请选择分部", trigger: "change" }],
  446. },
  447. typeList: [], //子分类列表
  448. cropperOptions: {
  449. autoCrop: true, //是否默认生成截图框
  450. autoCropWidth: 300, //默认生成截图框宽度
  451. autoCropHeight: 300, //默认生成截图框高度
  452. fixedBox: true, //是否固定截图框大小 不允许改变
  453. previewsCircle: false, //预览图是否是圆形
  454. full: true, // 是否输出原图比例的截图
  455. title: '上传图片', //模态框上显示的标题
  456. },
  457. };
  458. },
  459. created () { },
  460. mounted () {
  461. const query = this.$route.query
  462. if (query.pageType == "create") {
  463. this.$refs["form"].clearValidate();
  464. this.dialogForm = {
  465. poster: null,
  466. url: null,
  467. videoUrl: null
  468. }
  469. this.fileList = []
  470. }
  471. this.type = query.type;
  472. this.pageType = query.pageType;
  473. // 获取声部
  474. this.$store.dispatch('setSubjects')
  475. this.$store.dispatch("setBranchs");
  476. this.init();
  477. },
  478. methods: {
  479. init () {
  480. const query = this.$route.query
  481. this.type = query.type;
  482. this.pageType = query.pageType;
  483. this.initCrop()
  484. this.getList();
  485. this.addQuillTitle();
  486. this.$refs["form"].clearValidate();
  487. },
  488. initCrop() {
  489. // this.form.type
  490. // 1: "精彩活动",
  491. // 2: "热门资讯",
  492. // 4: "专项训练",
  493. // 5: "闪页管理",
  494. // 3: "BANNER管理",
  495. // 6: "APP按钮管理",
  496. // 7: "知识库管理",
  497. // 8: "广告管理"
  498. // let tempTitle = {
  499. // 1: "468px * 552px;图片不能超过 2M;", 2
  500. // 2: "456px * 288px; 图片不能超过 2M;", 1.56
  501. // 3: "686px * 140px; 图片不能超过 2M;", 2.63
  502. // 4: "图片不能超过 2M;", 1
  503. // 5: "图片不能超过 2M;", 0.73
  504. // 6: "图片不能超过 2M;", 60 * 60 1
  505. // 7: "图片不能超过 2M;", 2
  506. // 8: "1242px * 2208px; 图片不能超过 2M;" 1.77
  507. // };
  508. // this.imageSize = tempTitle[this.form.type];
  509. // console.log(this.imageSize)
  510. let type = Number(this.type)
  511. let corp = {}
  512. switch(type) {
  513. case 1:
  514. corp = {
  515. enlarge: 2,
  516. autoCropWidth: 316,
  517. autoCropHeight: 156
  518. }
  519. break;
  520. case 2:
  521. corp = {
  522. enlarge: 2,
  523. autoCropWidth: 350,
  524. autoCropHeight: 224
  525. }
  526. break;
  527. case 3:
  528. corp = {
  529. enlarge: 2.63,
  530. autoCropWidth: 350,
  531. autoCropHeight: 133
  532. }
  533. break;
  534. case 5:
  535. corp = {
  536. enlarge: 0.73,
  537. autoCropWidth: 255,
  538. autoCropHeight: 350
  539. }
  540. break;
  541. case 6:
  542. corp = {
  543. enlarge: 1,
  544. autoCropWidth: 112,
  545. autoCropHeight: 134
  546. }
  547. break;
  548. case 7:
  549. corp = {
  550. enlarge: 2,
  551. autoCropWidth: 167,
  552. autoCropHeight: 100
  553. }
  554. break;
  555. }
  556. const { cropperOptions } = this
  557. this.cropperOptions = Object.assign({}, cropperOptions, corp)
  558. console.log(this.cropperOptions, cropperOptions, type, corp)
  559. },
  560. //上传图片成功
  561. cropSuccess(data) {
  562. // this.imgUrl = data.data.avatar
  563. this.form.coverImage = data.data.url;
  564. },
  565. addAdvVideo () {
  566. this.dialogFormVisible = true
  567. let dialogForm = this.dialogForm
  568. dialogForm.poster = this.form.videoCoverImage
  569. if (this.formRadio == 1) {
  570. dialogForm.url = this.form.coverImage
  571. } else {
  572. dialogForm.videoUrl = this.form.coverImage
  573. }
  574. this.uploadStatus = true
  575. },
  576. onVideoComfirm (formName) {
  577. this.$refs[formName].validate(valid => {
  578. if (valid) {
  579. let dialogForm = this.dialogForm;
  580. if (this.uploadStatus) {
  581. // 添加视频类型
  582. let form = this.form
  583. form.coverImage = this.formRadio == 1 ? dialogForm.url : dialogForm.videoUrl
  584. form.videoCoverImage = dialogForm.poster
  585. this.uploadStatus = false
  586. } else {
  587. // 编辑器输入视频
  588. // 获取富文本组件实例
  589. let quill = this.editor;
  590. // 插入图片,res为服务器返回的图片链接地址
  591. const params = {
  592. poster: dialogForm.poster,
  593. url: this.formRadio == 1 ? dialogForm.url : dialogForm.videoUrl,
  594. }
  595. quill.insertEmbed(this.editorIndex, "video", params);
  596. // 调整光标到最后
  597. quill.setSelection(this.editorIndex + 1, { preload: false });
  598. }
  599. this.dialogFormVisible = false;
  600. this.dialogForm = {
  601. poster: null,
  602. url: null,
  603. videoUrl: null
  604. };
  605. } else {
  606. return false;
  607. }
  608. });
  609. },
  610. onDialogClose (diologForm) {
  611. this.dialogForm = {
  612. poster: null,
  613. url: null,
  614. videoUrl: null
  615. }
  616. this.$refs[diologForm].resetFields()
  617. },
  618. addQuillTitle () {
  619. this.$nextTick(() => {
  620. const oToolBar = document.querySelector(".ql-toolbar")
  621. console.log(oToolBar)
  622. if(oToolBar) {
  623. const aButton = oToolBar.querySelectorAll("button")
  624. const aSelect = oToolBar.querySelectorAll("select");
  625. aButton.forEach(function (item) {
  626. if (item.className === "ql-script") {
  627. item.value === "sub" ? (item.title = "下标") : (item.title = "上标");
  628. } else if (item.className === "ql-indent") {
  629. item.value === "+1"
  630. ? (item.title = "向右缩进")
  631. : (item.title = "向左缩进");
  632. } else {
  633. item.title = titleConfig[item.classList[0]];
  634. }
  635. });
  636. aSelect.forEach(function (item) {
  637. item.parentNode.title = titleConfig[item.classList[0]];
  638. });
  639. }
  640. })
  641. },
  642. onSubmit (formName) {
  643. this.$refs[formName].validate(valid => {
  644. if (valid) {
  645. let { subjectIdList, organIdList, ...rest } = this.form
  646. let form = {
  647. ...rest,
  648. subjectIdList: subjectIdList ? subjectIdList.join(',') : null,
  649. organIdList: organIdList ? organIdList.join(',') : null
  650. }
  651. let actionTime = form.actionTime
  652. // console.log(actionTime)
  653. if(actionTime && actionTime.length > 0) {
  654. form.onlineTime = dayjs(actionTime[0]).format('YYYY-MM-DD HH:mm:ss')
  655. form.offlineTime = dayjs(actionTime[1]).format('YYYY-MM-DD HH:mm:ss')
  656. } else {
  657. form.onlineTime = null
  658. form.offlineTime = null
  659. }
  660. if(this.outUrlRadio != 1) {
  661. form.linkUrl = null
  662. }
  663. if (this.pageType == "create") {
  664. if (form.id) {
  665. // 判断有没有Id,如果有则删除
  666. delete form.id;
  667. }
  668. if(this.type == 5) {
  669. form.status = 0
  670. }
  671. // return false
  672. newsAdd(form).then(res => {
  673. this.messageTips("添加", res);
  674. });
  675. } else if (this.pageType == "update") {
  676. newsUpdate(form).then(res => {
  677. this.messageTips("修改", res);
  678. });
  679. }
  680. } else {
  681. this.$nextTick(() => {
  682. let isError = document.getElementsByClassName('is-error')
  683. isError[0].scrollIntoView({
  684. block: 'center',
  685. behavior: 'smooth',
  686. })
  687. })
  688. return false;
  689. }
  690. });
  691. },
  692. messageTips (title, res) {
  693. if (res.code == 200) {
  694. this.$message.success(title + "成功");
  695. this.onCancel()
  696. } else {
  697. this.$message.error(res.msg);
  698. }
  699. },
  700. onCancel () {
  701. // 是否是平台功能
  702. const isPlat = this.type == 4 || this.type == 6 ? true : false
  703. this.$store.dispatch('delVisitedViews', this.$route)
  704. this.$router.push({
  705. path: isPlat ? "/platformIndex" : "/contentManager/contentManager",
  706. query: {
  707. tabrouter: this.typeIndex(this.type)
  708. }
  709. });
  710. },
  711. handleSuccess (res) {
  712. // 获取富文本组件实例
  713. let quill = this.editor;
  714. // 如果上传成功
  715. if (res.code) {
  716. // 获取光标所在位置
  717. let length = quill.getSelection().index;
  718. // 插入图片,res为服务器返回的图片链接地址
  719. quill.insertEmbed(length, "image", res.data.url);
  720. // 调整光标到最后
  721. quill.setSelection(length + 1);
  722. } else {
  723. // 提示信息,需引入Message
  724. this.$message.error("图片插入失败");
  725. }
  726. },
  727. onReSet (formName) {
  728. const query = this.$route.query
  729. this.form = {
  730. title: null,
  731. order: null,
  732. coverImage: null,
  733. videoCoverImage: null,
  734. attribute1: null,
  735. linkUrl: null,
  736. type: query.type,
  737. status: 1,
  738. content: null,
  739. // tenantId: null,
  740. organIdList: null,
  741. subType: null,
  742. actionTime: null
  743. };
  744. this.$refs[formName].resetFields();
  745. },
  746. onLook () {
  747. // 预览
  748. let dataInfo = this.dataInfo
  749. dataInfo.title = this.form.title
  750. dataInfo.content = this.form.content
  751. // 处理图片显示问题
  752. setTimeout(() => {
  753. let imgNode = document.querySelectorAll(".msgWrap img");
  754. if (imgNode.length > 0) {
  755. imgNode.forEach(item => {
  756. item.style.width = "100%";
  757. });
  758. }
  759. let videoNode = document.querySelectorAll(".msgWrap .ql-video");
  760. if (videoNode.length > 0) {
  761. videoNode.forEach(item => {
  762. item.style.width = "100%";
  763. item.style.height = "195px";
  764. });
  765. }
  766. }, 500);
  767. this.lookVisible = true
  768. },
  769. async getList () {
  770. if(this.type == 7 || this.type == 2) {
  771. await newsTypeList({ parentId: this.type }).then(res => {
  772. console.log(res)
  773. if(res.code ==200) {
  774. this.typeList = res.data
  775. }
  776. })
  777. }
  778. if (this.pageType == "create") {
  779. return;
  780. } else {
  781. newsQueryId({ id: this.$route.query.id }).then(res => {
  782. if (res.code == 200) {
  783. let result = res.data;
  784. let form = this.form;
  785. if (result.videoCoverImage) {
  786. this.uploadType = 2
  787. } else {
  788. this.uploadType = 1
  789. }
  790. let tempActionTime = null
  791. if(result.onlineTime && result.offlineTime) {
  792. tempActionTime = [result.onlineTime, result.offlineTime]
  793. }
  794. let subject = result.subjectIdList ? result.subjectIdList.split(',') : []
  795. let organ = result.organIdList ? result.organIdList.split(',') : []
  796. // 1 2 4 7
  797. if(this.type == 3 || this.type == 5 || this.type == 6 || this.type == 8) {
  798. this.outUrlRadio = 1
  799. } else {
  800. if(result.linkUrl) {
  801. this.outUrlRadio = 1
  802. } else {
  803. this.outUrlRadio = 0
  804. }
  805. }
  806. this.form = {
  807. id: result.id,
  808. title: result.title,
  809. order: result.order,
  810. coverImage: result.coverImage,
  811. videoCoverImage: result.videoCoverImage,
  812. attribute1: Number(result.attribute1),
  813. linkUrl: result.linkUrl,
  814. type: result.type,
  815. status: result.status,
  816. // tenantId: result.tenantId.toString(),
  817. subjectIdList: subject.map(item => { return +item }),
  818. organIdList: organ.map(item => { return +item }),
  819. memo: result.memo,
  820. content: result.content,
  821. actionTime: tempActionTime,
  822. subType: result.subType ? result.subType : null
  823. };
  824. this.dataInfo.updateTime = result.updateTime
  825. }
  826. });
  827. }
  828. },
  829. handleUploadImgError (file) {
  830. this.uploadImgLoading = false
  831. this.$message.error('上传失败')
  832. },
  833. handleImgSuccess (res, file) {
  834. this.uploadImgLoading = false
  835. if (res.code == 200) {
  836. this.dialogForm.poster = res.data.url
  837. } else {
  838. this.$message.error('上传失败')
  839. }
  840. },
  841. beforeImgUpload (file) {
  842. const imageType = {
  843. "image/png": true,
  844. "image/jpeg": true,
  845. "image/gif": true
  846. };
  847. const isImage = imageType[file.type];
  848. const isLt2M = file.size / 1024 / 1024 < 2;
  849. // console.log(isImage, isLt2M)
  850. if (!isImage) {
  851. this.$message.error("只能上传图片格式!");
  852. }
  853. if (!isLt2M) {
  854. this.$message.error("上传图片大小不能超过 2MB!");
  855. }
  856. if (isImage && isLt2M) {
  857. this.uploadImgLoading = true
  858. }
  859. return isImage && isLt2M;
  860. },
  861. handleAvatarSuccess (res, file) {
  862. this.uploadCoverLoading = false
  863. if (res.code == 200) {
  864. this.form.coverImage = res.data.url;
  865. } else {
  866. this.$message.error('上传失败')
  867. }
  868. },
  869. handleAvatarError() {
  870. this.uploadCoverLoading = false
  871. },
  872. beforeAvatarUpload (file) {
  873. const imageType = {
  874. "image/png": true,
  875. "image/jpeg": true,
  876. "image/gif": true
  877. };
  878. const isImage = imageType[file.type];
  879. const isLt2M = file.size / 1024 / 1024 < 2;
  880. if (!isImage) {
  881. this.$message.error("只能上传图片格式!");
  882. }
  883. if (!isLt2M) {
  884. this.$message.error("上传图片大小不能超过 2M!");
  885. }
  886. this.uploadCoverLoading = true
  887. return isImage && isLt2M;
  888. },
  889. typeChange (type) {
  890. let tempTitle = {
  891. 1: "精彩活动",
  892. 2: "热门资讯",
  893. 4: "专项训练",
  894. 5: "闪页管理",
  895. 3: "BANNER管理",
  896. 6: "APP按钮管理",
  897. 7: "知识库管理",
  898. 8: "广告管理"
  899. };
  900. return tempTitle[type];
  901. },
  902. typeCheck (type) {
  903. // 精彩活动 1 0
  904. // 热门资讯 2 1
  905. // 专项训练 4 2
  906. // 闪页管理 5 3
  907. // BANNER管理 3 4
  908. // APP按钮管理 6 5
  909. // 知识库 7 5
  910. let params = {
  911. 1: '精彩活动',
  912. 2: '热门资讯',
  913. 4: '专项训练',
  914. 7: '知识库'
  915. }
  916. return params[type] ? params[type] : '管乐迷'
  917. },
  918. typeIndex (type) {
  919. let tempTitle = {
  920. 1: 0,
  921. 2: 1,
  922. 3: 4,
  923. 4: 2,
  924. 5: 3,
  925. 6: 5,
  926. 7: 6,
  927. 8: 7
  928. };
  929. return tempTitle[type];
  930. },
  931. onEditorChange ( html ) {
  932. // console.log(html,'html')
  933. this.form.content = html;
  934. },
  935. beforeUpload (file) {
  936. // const isJPG = file.type === 'image/jpeg';
  937. const isLt2M = file.size / 1024 / 1024 < 100;
  938. // if (!isJPG) {
  939. // this.$message.error('上传头像图片只能是 JPG 格式!');
  940. // }
  941. if (!isLt2M) {
  942. this.$message.error('上传视频大小不能超过 100MB!');
  943. }
  944. this.uploadLoading = true
  945. return isLt2M;
  946. },
  947. handleUploadError (file) {
  948. this.uploadLoading = false
  949. this.$message.error('上传视频失败')
  950. },
  951. handleUploadSuccess (file, fileList) {
  952. this.uploadLoading = false
  953. if (file.code == 200) {
  954. this.$message.success('上传视频成功')
  955. this.dialogForm.videoUrl = file.data.url;
  956. } else {
  957. this.$message.error('上传视频失败')
  958. }
  959. },
  960. handleExceed (files, fileList) {
  961. this.$message.error('您已上传过视频')
  962. // this.$message.warning(`当前限制选择 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
  963. }
  964. },
  965. computed: {
  966. editor () {
  967. return this.$refs.myQuillEditor.quill;
  968. }
  969. }
  970. };
  971. </script>
  972. <style lang="scss" scoped>
  973. .m-container {
  974. min-width: 100%;
  975. }
  976. .el-input {
  977. width: 400px;
  978. }
  979. ::v-deep .ql-editor {
  980. min-height: 300px;
  981. padding: 0;
  982. }
  983. ::v-deep .ql-container .ql-editor {
  984. max-height: 500px;
  985. }
  986. .el-row {
  987. margin-top: 40px;
  988. }
  989. .el-col {
  990. display: flex;
  991. align-items: center;
  992. margin-bottom: 20px;
  993. justify-content: flex-end;
  994. margin-right: 50%;
  995. }
  996. .el-input-group {
  997. width: 200px;
  998. margin: 0 20px;
  999. }
  1000. ::v-deep .el-tree-node__content {
  1001. height: 40px !important;
  1002. }
  1003. ::v-deep .avatar-uploader .el-upload,
  1004. ::v-deep .upload-demo .el-upload {
  1005. border-radius: 6px;
  1006. cursor: pointer;
  1007. position: relative;
  1008. overflow: hidden;
  1009. }
  1010. .avatar-uploader .el-upload:hover {
  1011. border-color: #409eff;
  1012. }
  1013. .avatar-uploader-icon {
  1014. border: 1px dashed #d9d9d9;
  1015. font-size: 28px;
  1016. color: #8c939d;
  1017. width: 120px;
  1018. height: 120px;
  1019. line-height: 120px;
  1020. text-align: center;
  1021. }
  1022. .avatar {
  1023. width: 120px;
  1024. height: 120px;
  1025. display: block;
  1026. }
  1027. .ivu-upload {
  1028. display: none;
  1029. }
  1030. .sd-container {
  1031. // padding: 15px;
  1032. h2 {
  1033. height: auto;
  1034. font-weight: 500;
  1035. color: rgba(68, 68, 68, 1);
  1036. line-height: 37px;
  1037. font-size: 26px;
  1038. margin-bottom: 10px;
  1039. }
  1040. .titleInfo {
  1041. height: 15px;
  1042. line-height: 15px;
  1043. display: flex;
  1044. flex-direction: row;
  1045. justify-content: space-between;
  1046. color: #444;
  1047. margin-bottom: 25px;
  1048. }
  1049. .imgWrap {
  1050. /* width: 100;
  1051. height: 1.45rem; */
  1052. margin-bottom: 0.15rem;
  1053. p {
  1054. font-size: 0.16rem;
  1055. font-family: PingFangSC;
  1056. font-weight: 400;
  1057. color: rgba(68, 68, 68, 1);
  1058. line-height: 0.28rem;
  1059. text-indent: 0.32rem;
  1060. }
  1061. img {
  1062. width: 100%;
  1063. }
  1064. }
  1065. }
  1066. .imageSize {
  1067. color: red;
  1068. line-height: 1.5;
  1069. }
  1070. </style>