entryOperation.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. <template>
  2. <div class="m-container">
  3. <h2>
  4. <el-page-header @back="onCancel"
  5. :content="(pageType == 'create' ? '添加时间充值活动' : '查看时间充值活动')"></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="name">
  15. <el-input v-model.trim="form.name"
  16. placeholder="请输入活动名称"
  17. :disabled="pageType=='create'?false:true"></el-input>
  18. </el-form-item>
  19. <el-form-item label="适用范围"
  20. prop="suitableUser">
  21. <el-select v-model="form.suitableUser"
  22. :disabled="pageType=='create'?false:true"
  23. placeholder="请选择适用范围">
  24. <el-option label="全部"
  25. value="ALL"></el-option>
  26. <el-option label="新用户"
  27. value="NEW"></el-option>
  28. </el-select>
  29. </el-form-item>
  30. <el-form-item label="有效期"
  31. prop="date">
  32. <!-- <el-input v-model="form.memo"></el-input> -->
  33. <el-date-picker :disabled="pageType=='create'?false:true"
  34. v-model="form.date"
  35. type="datetimerange"
  36. :picker-options="{
  37. firstDayOfWeek:1
  38. }"
  39. align="right"
  40. unlink-panels
  41. value-format="yyyy-MM-dd HH:mm:ss"
  42. range-separator="至"
  43. start-placeholder="开始日期"
  44. end-placeholder="结束日期"></el-date-picker>
  45. </el-form-item>
  46. <!-- -->
  47. <el-form-item label="价格"
  48. prop="totalPrice">
  49. <el-input type="number"
  50. @mousewheel.native.prevent
  51. v-model.trim="form.totalPrice"
  52. placeholder="请输入价格"
  53. :disabled="pageType=='create'?false:true"></el-input>
  54. </el-form-item>
  55. <el-form-item label="折扣价"
  56. prop="discountPrice">
  57. <el-input type="number"
  58. @mousewheel.native.prevent
  59. v-model.trim="form.discountPrice"
  60. placeholder="请输入折价格"
  61. :disabled="pageType=='create'?false:true"></el-input>
  62. </el-form-item>
  63. <el-form-item label="购买分钟数"
  64. prop="purchaseMinutes">
  65. <el-input type="number"
  66. @mousewheel.native.prevent
  67. v-model.trim="form.purchaseMinutes"
  68. placeholder="请输入购买分钟"
  69. :disabled="pageType=='create'?false:true"></el-input>
  70. </el-form-item>
  71. <el-form-item label="赠送分钟数"
  72. prop="giveMinutes">
  73. <el-input type="number"
  74. @mousewheel.native.prevent
  75. v-model.trim="form.giveMinutes"
  76. placeholder="请输入赠送分钟"
  77. :disabled="pageType=='create'?false:true"></el-input>
  78. </el-form-item>
  79. <el-form-item label="活动图"
  80. prop="coverImg">
  81. <el-upload class="avatar-uploader"
  82. action="/api-web/uploadFile"
  83. :disabled="pageType=='create'?false:true"
  84. :headers="headers"
  85. :show-file-list="false"
  86. accept=".jpg, .jpeg, .png"
  87. :on-success="handleAvatarSuccess"
  88. :before-upload="beforeAvatarUpload">
  89. <img v-if="form.coverImg"
  90. :src="form.coverImg"
  91. class="avatar" />
  92. <i v-else
  93. class="el-icon-plus avatar-uploader-icon"></i>
  94. </el-upload>
  95. <p class="imageSize"
  96. v-if="imageSize">上传图片尺寸为:{{ imageSize }}</p>
  97. </el-form-item>
  98. <el-form-item label="活动详情"
  99. prop="detail">
  100. <!-- bidirectional data binding(双向数据绑定) -->
  101. <quill-editor class="ql-editor"
  102. :disabled="pageType=='create'?false:true"
  103. v-model="form.detail"
  104. ref="myQuillEditor"
  105. :options="editorOption"
  106. @change="onEditorChange($event)"></quill-editor>
  107. <el-upload class="ivu-upload"
  108. :show-upload-list="false"
  109. :headers="headers"
  110. :on-success="handleSuccess"
  111. accept=".jpg, .jpeg, .png"
  112. :max-size="2048"
  113. multiple
  114. action="/api-web/uploadFile">
  115. <Button icon="ios-cloud-upload-outline"></Button>
  116. </el-upload>
  117. </el-form-item>
  118. <el-form-item v-if="pageType == 'create'">
  119. <el-button @click="onSubmit('form')"
  120. type="primary">立即{{ pageType == "create" ? '创建' : '修改' }}</el-button>
  121. <el-button @click="onReSet('form')">重置</el-button>
  122. </el-form-item>
  123. </el-form>
  124. </div>
  125. </div>
  126. </template>
  127. <script>
  128. import { getActivitieQuery, getActivitieMerge } from "@/api/appTenant";
  129. import store from "@/store";
  130. import { getToken } from "@/utils/auth";
  131. import { vaildStudentUrl } from "@/utils/validate";
  132. import load from '@/utils/loading'
  133. // import E from 'wangeditor'
  134. // require styles
  135. import "quill/dist/quill.core.css";
  136. import "quill/dist/quill.snow.css";
  137. import "quill/dist/quill.bubble.css";
  138. import Quill from "quill";
  139. import { quillEditor } from "vue-quill-editor";
  140. // 工具栏配置
  141. const toolbarOptions = [
  142. ["bold", "italic", "underline", "strike"], // 加粗 斜体 下划线 删除线
  143. ["blockquote", "code-block"], // 引用 代码块
  144. [{ header: 1 }, { header: 2 }], // 1、2 级标题
  145. [{ list: "ordered" }, { list: "bullet" }], // 有序、无序列表
  146. [{ script: "sub" }, { script: "super" }], // 上标/下标
  147. [{ indent: "-1" }, { indent: "+1" }], // 缩进
  148. // [{'direction': 'rtl'}], // 文本方向
  149. [{ size: ["small", false, "large", "huge"] }], // 字体大小
  150. [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题
  151. [{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色
  152. [{ font: [] }], // 字体种类
  153. [{ align: [] }], // 对齐方式
  154. ["clean"], // 清除文本格式
  155. // ["image", "video"] // 链接、图片、视频
  156. // ["link", "image", "video"] // 链接、图片、视频
  157. ];
  158. // 标题
  159. const titleConfig = {
  160. "ql-bold": "加粗",
  161. "ql-color": "颜色",
  162. "ql-font": "字体",
  163. "ql-code": "插入代码",
  164. "ql-italic": "斜体",
  165. // 'ql-link': '添加链接',
  166. "ql-background": "背景颜色",
  167. "ql-size": "字体大小",
  168. "ql-strike": "删除线",
  169. "ql-script": "上标/下标",
  170. "ql-underline": "下划线",
  171. "ql-blockquote": "引用",
  172. "ql-header": "标题",
  173. "ql-indent": "缩进",
  174. "ql-list": "列表",
  175. "ql-align": "文本对齐",
  176. "ql-direction": "文本方向",
  177. "ql-code-block": "代码块",
  178. "ql-formula": "公式",
  179. "ql-image": "图片",
  180. "ql-video": "视频",
  181. "ql-clean": "清除字体样式",
  182. "ql-upload": "文件"
  183. };
  184. let validPrice = (rule, value, callback) => {
  185. if (value == '' && typeof value == 'string' || value == null) {
  186. callback(new Error('请输入金额'))
  187. } else if (value < 0) {
  188. callback(new Error('输入金额必须大于或等于0'))
  189. } else if (value >= 100000) {
  190. callback(new Error('输入金额必须小于100000'))
  191. } else {
  192. callback()
  193. }
  194. }
  195. let validMinutes = (rule, value, callback) => {
  196. if (value == '' && typeof value == 'string' || value == null) {
  197. callback(new Error('请输入分钟数'))
  198. } else if (value < 0) {
  199. callback(new Error('输入分钟数必须大于或等于0'))
  200. } else if (value >= 100000) {
  201. callback(new Error('输入分钟数必须小于100000'))
  202. } else {
  203. callback()
  204. }
  205. }
  206. // 这里引入修改过的video模块并注册
  207. import Video from "../quill/video.js";
  208. Quill.register(Video, true);
  209. export default {
  210. name: "contentOperation",
  211. components: {
  212. quillEditor
  213. },
  214. data () {
  215. let that = this;
  216. return {
  217. categoryList: [],
  218. pageType: this.$route.query.type,
  219. headers: {
  220. Authorization: getToken()
  221. },
  222. content: null,
  223. editorIndex: 0, // 光标位置
  224. editorOption: {
  225. placeholder: "请输入内容",
  226. modules: {
  227. toolbar: {
  228. container: toolbarOptions,
  229. handlers: {
  230. image: function (value) {
  231. if (value) {
  232. // 调用iview图片上传
  233. document.querySelector(".ivu-upload .el-upload").click();
  234. } else {
  235. this.quill.format("image", false);
  236. }
  237. }
  238. }
  239. }
  240. }
  241. },
  242. form: {
  243. name: null,
  244. suitableUser: null,
  245. date: null,
  246. startDate: null,
  247. endDate: null,
  248. totalPrice: null,
  249. discountPrice: null,
  250. purchaseMinutes: null,
  251. giveMinutes: null,
  252. coverImg: null,
  253. detail: null
  254. },
  255. rules: {
  256. name: [
  257. { required: true, message: "请输入活动名称", trigger: "blur" },
  258. { min: 2, max: 30, message: "长度在 2 到 30 个字符", trigger: "blur" }
  259. ],
  260. suitableUser: [{ required: true, message: "请选择适用范围", trigger: "change" }],
  261. date: [{ required: true, message: '请选择有效期', trigger: 'change' }],
  262. totalPrice: [{ required: true, validator: validPrice, trigger: 'blur' }],
  263. discountPrice: [{ required: true, validator: validPrice, trigger: 'blur' }],
  264. purchaseMinutes: [{ required: true, validator: validMinutes, trigger: 'blur' }],
  265. giveMinutes: [{ required: true, validator: validMinutes, trigger: 'blur' }],
  266. coverImg: [
  267. { required: true, message: "请选择活动图", trigger: "blur" }
  268. ],
  269. detail: [{ required: true, message: "请编辑活动内容", trigger: "blur" }]
  270. },
  271. imageSize: null
  272. };
  273. },
  274. created () { },
  275. mounted () {
  276. this.init();
  277. },
  278. activated () {
  279. if (this.$route.query.type == "create") {
  280. this.form = {
  281. name: null,
  282. suitableUser: null,
  283. date: null,
  284. startDate: null,
  285. endDate: null,
  286. totalPrice: null,
  287. discountPrice: null,
  288. purchaseMinutes: null,
  289. giveMinutes: null,
  290. coverImg: null,
  291. detail: null
  292. }
  293. this.$refs["form"].resetFields();
  294. }
  295. this.pageType = this.$route.query.type;
  296. this.init();
  297. },
  298. methods: {
  299. init () {
  300. this.getList();
  301. this.addQuillTitle();
  302. // this.form.type
  303. let tempTitle = {
  304. 1: "468px * 552px",
  305. 2: "456px * 288px",
  306. 3: "686px * 140px",
  307. 4: null
  308. };
  309. this.imageSize = tempTitle[this.form.type];
  310. },
  311. addQuillTitle () {
  312. const oToolBar = document.querySelector(".ql-toolbar"),
  313. aButton = oToolBar.querySelectorAll("button"),
  314. aSelect = oToolBar.querySelectorAll("select");
  315. aButton.forEach(function (item) {
  316. if (item.className === "ql-script") {
  317. item.value === "sub" ? (item.title = "下标") : (item.title = "上标");
  318. } else if (item.className === "ql-indent") {
  319. item.value === "+1"
  320. ? (item.title = "向右缩进")
  321. : (item.title = "向左缩进");
  322. } else {
  323. item.title = titleConfig[item.classList[0]];
  324. }
  325. });
  326. aSelect.forEach(function (item) {
  327. item.parentNode.title = titleConfig[item.classList[0]];
  328. });
  329. },
  330. onSubmit (formName) {
  331. this.$refs[formName].validate(valid => {
  332. if (valid) {
  333. if (this.pageType == "create") {
  334. let form = this.form
  335. let params = {
  336. name: form.name,
  337. suitableUser: form.suitableUser,
  338. startDate: form.date[0],
  339. endDate: form.date[1],
  340. totalPrice: form.totalPrice,
  341. discountPrice: form.discountPrice,
  342. purchaseMinutes: form.purchaseMinutes,
  343. giveMinutes: form.giveMinutes,
  344. coverImg: form.coverImg,
  345. detail: form.detail,
  346. delFlag: false
  347. }
  348. // return false
  349. getActivitieMerge(params).then(res => {
  350. this.messageTips("添加", res);
  351. });
  352. }
  353. } else {
  354. return false;
  355. }
  356. });
  357. },
  358. messageTips (title, res) {
  359. if (res.code == 200) {
  360. this.$message.success(title + "成功");
  361. this.$router.push({
  362. path: "/insideSetting/entryActivities"
  363. });
  364. } else {
  365. this.$message.error(res.msg);
  366. }
  367. },
  368. onCancel () {
  369. this.$router.push({
  370. path: "/insideSetting/entryActivities"
  371. });
  372. },
  373. handleSuccess (res) {
  374. // 获取富文本组件实例
  375. let quill = this.editor;
  376. // 如果上传成功
  377. if (res.code) {
  378. // 获取光标所在位置
  379. let length = quill.getSelection().index;
  380. // 插入图片,res为服务器返回的图片链接地址
  381. quill.insertEmbed(length, "image", res.data.url);
  382. // 调整光标到最后
  383. quill.setSelection(length + 1);
  384. } else {
  385. // 提示信息,需引入Message
  386. this.$message.error("图片插入失败");
  387. }
  388. },
  389. onReSet (formName) {
  390. this.$refs[formName].resetFields();
  391. },
  392. getList () {
  393. if (this.pageType == "create") {
  394. return;
  395. } else {
  396. getActivitieQuery({ id: this.$route.query.id }).then(res => {
  397. if (res.code == 200) {
  398. let result = res.data;
  399. let form = this.form;
  400. this.form = {
  401. name: result.name,
  402. suitableUser: result.suitableUser,
  403. date: [result.startDate, result.endDate],
  404. startDate: result.startDate,
  405. endDate: result.endDate,
  406. totalPrice: result.totalPrice,
  407. discountPrice: result.discountPrice,
  408. purchaseMinutes: result.purchaseMinutes,
  409. giveMinutes: result.giveMinutes,
  410. coverImg: result.coverImg,
  411. detail: result.detail,
  412. };
  413. }
  414. });
  415. }
  416. },
  417. handleAvatarSuccess (res, file) {
  418. load.endLoading()
  419. this.form.coverImg = res.data.url;
  420. },
  421. beforeAvatarUpload (file) {
  422. const imageType = {
  423. "image/png": true,
  424. "image/jpeg": true
  425. };
  426. const isImage = imageType[file.type];
  427. const isLt2M = file.size / 1024 / 1024 < 2;
  428. if (!isImage) {
  429. this.$message.error("只能上传图片格式!");
  430. }
  431. if (!isLt2M) {
  432. this.$message.error("上传头像图片大小不能超过 2MB!");
  433. }
  434. if (isImage && isLt2M) { // 判断是否满足条件
  435. load.startLoading()
  436. }
  437. return isImage && isLt2M;
  438. },
  439. onEditorChange ({ quill, html, text }) {
  440. this.form.detail = html;
  441. }
  442. },
  443. computed: {
  444. editor () {
  445. return this.$refs.myQuillEditor.quill;
  446. }
  447. }
  448. };
  449. </script>
  450. <style lang="scss" scoped>
  451. .m-container {
  452. min-width: 100%;
  453. }
  454. .el-input {
  455. width: 400px;
  456. }
  457. /deep/.ql-editor {
  458. min-height: 300px;
  459. padding: 0;
  460. }
  461. /deep/.ql-container .ql-editor {
  462. max-height: 500px;
  463. }
  464. .el-button--primary {
  465. background: #14928a;
  466. border-color: #14928a;
  467. color: #fff;
  468. &:hover,
  469. &:active,
  470. &:focus {
  471. background: #14928a;
  472. border-color: #14928a;
  473. color: #fff;
  474. }
  475. }
  476. .el-row {
  477. margin-top: 40px;
  478. }
  479. .el-col {
  480. display: flex;
  481. align-items: center;
  482. margin-bottom: 20px;
  483. justify-content: flex-end;
  484. margin-right: 50%;
  485. }
  486. .el-input-group {
  487. width: 200px;
  488. margin: 0 20px;
  489. }
  490. /deep/.el-tree-node__content {
  491. height: 40px !important;
  492. }
  493. /deep/.avatar-uploader .el-upload {
  494. border: 1px dashed #d9d9d9;
  495. border-radius: 6px;
  496. cursor: pointer;
  497. position: relative;
  498. overflow: hidden;
  499. }
  500. .avatar-uploader .el-upload:hover {
  501. border-color: #409eff;
  502. }
  503. .avatar-uploader-icon {
  504. font-size: 28px;
  505. color: #8c939d;
  506. width: 240px;
  507. height: 120px;
  508. line-height: 120px;
  509. text-align: center;
  510. }
  511. /deep/.el-date-editor {
  512. width: 400px;
  513. }
  514. .avatar {
  515. width: 240px;
  516. height: 120px;
  517. display: block;
  518. }
  519. .ivu-upload {
  520. display: none;
  521. }
  522. </style>