edit_activity_edit_form.vue 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. <template>
  2. <div class="edit-form-main">
  3. <div class="form-title">
  4. <img class="icon" src="@/assets/img/sa_7.png" />
  5. <span>活动编辑</span>
  6. </div>
  7. <div class="form-content">
  8. <div class="module-panel">
  9. <p class="module-title">
  10. <img src="@/assets/img/sa_13.png" />
  11. 基本信息
  12. </p>
  13. <div class="module-item">
  14. <label class="item-title">海报</label>
  15. <div class="poster-photo-panel">
  16. <el-input v-model="poster_photo_file_name" :readonly="true" class="input"></el-input>
  17. <el-upload
  18. action="https://upload.qiniup.com"
  19. :data="{ token: qntoken, key: poster_photo_file_key }"
  20. :show-file-list="false"
  21. :on-error="posterPhotoUploadFail"
  22. :on-success="posterPhotoUploadSuccess"
  23. :before-upload="beforePosterPhotoUpload"
  24. >
  25. <el-button type="primary" style="margin-left: 10px;" :loading="uploading_poster_photo">上传图片</el-button>
  26. </el-upload>
  27. </div>
  28. </div>
  29. <div class="poster-photo-hint">图片建议尺寸828*430,大小不超过3M</div>
  30. <div class="module-item">
  31. <label class="item-title">标题</label>
  32. <el-input v-model="activity.title" class="item-input"></el-input>
  33. </div>
  34. <div class="module-item">
  35. <label class="item-title">名称</label>
  36. <el-input v-model="activity.subtitle" class="item-input"></el-input>
  37. </div>
  38. <div class="module-item">
  39. <label class="item-title">商户简称</label>
  40. <el-input v-model="$store.getters.xt_user.org.org_name" class="item-input" readonly></el-input>
  41. </div>
  42. <div class="module-item">
  43. <label class="item-title">报名时间</label>
  44. <el-date-picker v-model="sign_up_deadline" :picker-options="pickerOptions" value-format="timestamp" type="datetime" format="yyyy-MM-dd HH:mm" class="item-input"></el-date-picker>
  45. </div>
  46. <div class="module-item">
  47. <label class="item-title">活动时间</label>
  48. <el-date-picker v-model="activity_time" :picker-options="pickerOptions" value-format="timestamp" type="datetime" format="yyyy-MM-dd HH:mm" class="item-input"></el-date-picker>
  49. </div>
  50. <div class="module-item">
  51. <label class="item-title">活动地址</label>
  52. <el-input v-model="activity.address" class="item-input"></el-input>
  53. </div>
  54. <div class="module-item">
  55. <label class="item-title">限定人数</label>
  56. <el-input v-model="limit_num" class="item-input" :maxlength="9" @keyup.native="limit_num=limit_num.replace(/\D/g,'')" @afterpaste.native="limit_num=limit_num.replace(/\D/g,'')"></el-input>
  57. <span class="limit-text">不填写默认为无限制</span>
  58. </div>
  59. <div class="module-item">
  60. <label class="item-title">联系方式</label>
  61. <el-input v-model="activity.phone_number" class="item-input"></el-input>
  62. </div>
  63. </div>
  64. <div class="module-panel" style="margin-top: 30px;">
  65. <p class="module-title">
  66. <img src="@/assets/img/sa_13.png" />
  67. 报名须知
  68. </p>
  69. <div class="module-item">
  70. <label class="item-title">报名须知</label>
  71. <el-input v-model="activity.sign_up_notice" class="item-input" type="textarea" :rows="4" resize="none"></el-input>
  72. </div>
  73. </div>
  74. <div class="module-panel" style="margin-top: 30px;">
  75. <p class="module-title">
  76. <img src="@/assets/img/sa_13.png" />
  77. 详细说明
  78. </p>
  79. <div class="module-item">
  80. <label class="item-title">标题</label>
  81. <el-input v-model="paragraph.title" class="item-input"></el-input>
  82. </div>
  83. <div class="module-item">
  84. <label class="item-title">详情</label>
  85. <div class="item-input">
  86. <keep-alive>
  87. <neditor ref="neditor" id="editor" :r_content="paragraph_init_content" @content_changed="paragraphContentChanged"></neditor>
  88. </keep-alive>
  89. </div>
  90. </div>
  91. </div>
  92. <div class="submit-button-panel">
  93. <el-button style="padding: 10px 30px;" type="primary" @click="publishAction" :loading="publishing_activity" :disabled="saving_activity || saving_before_preview_activity">发 布</el-button>
  94. <el-button style="color: #409eff; border-color: #409eff; padding: 10px 30px;" @click="saveAction" :loading="saving_activity" :disabled="publishing_activity || saving_before_preview_activity">保存草稿</el-button>
  95. <el-button style="color: #409eff; border-color: #409eff; padding: 10px 30px;" @click="previewAction" :loading="saving_before_preview_activity" :disabled="publishing_activity || saving_activity">预 览</el-button>
  96. </div>
  97. </div>
  98. </div>
  99. </template>
  100. <script>
  101. import Neditor from '@/components/Neditor'
  102. import { getToken } from "@/api/qiniu"
  103. import { getFileExtension } from "@/utils/tools"
  104. import { parseTime } from "@/utils"
  105. import { submitActivity } from "@/api/activity/activity"
  106. export default {
  107. name: "EditActivityEditForm",
  108. components: {
  109. Neditor,
  110. },
  111. props: {
  112. activity: {
  113. type: Object,
  114. required: true,
  115. },
  116. paragraph: {
  117. type: Object,
  118. required: true,
  119. },
  120. },
  121. data() {
  122. return {
  123. saving_activity: false,
  124. publishing_activity: false,
  125. saving_before_preview_activity: false,
  126. uploading_poster_photo: false,
  127. qntoken: "",
  128. poster_photo_file_key: "",
  129. poster_photo_file_name: "",
  130. limit_num: "",
  131. activity_time: 0,
  132. sign_up_deadline: 0,
  133. paragraph_init_content: "",
  134. pickerOptions: {
  135. disabledDate: (time) => {
  136. return time.getTime() < Date.now() - 8.64e7
  137. }
  138. }
  139. }
  140. },
  141. created() {
  142. this.activity_time = (new Date()).getTime()
  143. this.sign_up_deadline = (new Date()).getTime()
  144. },
  145. watch: {
  146. limit_num: function(new_val) {
  147. if (/^[1-9]+[0-9]*]*$/.test(new_val)) {
  148. this.activity.limit_num = parseInt(new_val)
  149. } else {
  150. this.activity.limit_num = 0
  151. }
  152. },
  153. activity_time: function(new_val) {
  154. this.activity.start_time = parseInt(new_val / 1000)
  155. },
  156. sign_up_deadline: function(new_val) {
  157. this.activity.sign_up_deadline = parseInt(new_val / 1000)
  158. },
  159. },
  160. methods: {
  161. initForms: function() {
  162. this.poster_photo_file_name = this.activity.poster_photo
  163. this.limit_num = this.activity.limit_num > 0 ? this.activity.limit_num : ""
  164. this.activity_time = this.activity.start_time
  165. this.sign_up_deadline = this.activity.sign_up_deadline
  166. this.paragraph_init_content = this.paragraph.content
  167. },
  168. paragraphContentChanged: function(content) {
  169. this.paragraph.content = content
  170. },
  171. posterPhotoUploadFail: function(err, file, fileList) {
  172. this.uploading_poster_photo = false
  173. this.$message.error(err)
  174. },
  175. posterPhotoUploadSuccess: function(res, file) {
  176. this.poster_photo_file_name = file.name
  177. this.uploading_poster_photo = false
  178. this.activity.poster_photo = "https://images.shengws.com/" + res.url
  179. },
  180. beforePosterPhotoUpload: function(file) {
  181. var is_image = file.type.indexOf("image") > -1
  182. var mb = file.size / 1024 / 1024
  183. if (!is_image) {
  184. this.$message.error("请上传图片")
  185. return false
  186. }
  187. if (mb > 3) {
  188. this.$message.error("上传主图大小不能超过3MB")
  189. return false
  190. }
  191. var rand = Math.floor(Math.random() * 1000000000)
  192. var date = new Date()
  193. var ext = getFileExtension(file.name)
  194. var key = "" + date.getFullYear() + (date.getMonth() + 1) + date.getDate() + "_activity_" + rand + "." + ext
  195. this.uploading_poster_photo = true
  196. return new Promise((resolve, reject) => {
  197. getToken().then(rs => {
  198. var token = rs.data.data.uptoken
  199. this.qntoken = token
  200. this.poster_photo_file_key = key
  201. resolve(true)
  202. }).catch(err => {
  203. this.uploading_poster_photo = false
  204. reject(false)
  205. })
  206. })
  207. },
  208. saveAction: function() {
  209. this.saving_activity = true
  210. this.submitActivity(false, function() {
  211. // 弹框 => 再发一条/前往列表
  212. })
  213. },
  214. publishAction: function() {
  215. this.publishing_activity = true
  216. this.submitActivity(true, function() {
  217. this.$router.push({ path: "/activity", query: { id: this.activity.id } })
  218. })
  219. },
  220. previewAction: function() {
  221. this.saving_before_preview_activity = true
  222. var t = this
  223. this.submitActivity(false, function() {
  224. var new_page = t.$router.resolve({
  225. path: '/activity/preview',
  226. query: {
  227. id: t.activity.id,
  228. }
  229. })
  230. window.open(new_page.href, '_blank');
  231. })
  232. },
  233. submitActivity: function(is_publish, successCallBack) {
  234. this.validActivityInfo().then(() => {
  235. var activity = {
  236. id: this.activity.id,
  237. poster_photo: this.activity.poster_photo,
  238. title: this.activity.title,
  239. subtitle: this.activity.subtitle,
  240. address: this.activity.address,
  241. limit_num: this.activity.limit_num,
  242. sign_up_deadline: parseTime(this.activity.sign_up_deadline, "{y}-{m}-{d} {h}:{i}"),
  243. start_time: parseTime(this.activity.start_time, "{y}-{m}-{d} {h}:{i}"),
  244. phone_number: this.activity.phone_number,
  245. sign_up_notice: this.activity.sign_up_notice,
  246. paragraph: {
  247. title: this.paragraph.title,
  248. content: this.paragraph.content,
  249. }
  250. }
  251. submitActivity(is_publish, activity).then(rs => {
  252. var resp = rs.data
  253. if (resp.state == 1) {
  254. this.activity.id = resp.data.activity_id
  255. } else {
  256. this.$message.error(resp.msg)
  257. }
  258. if (successCallBack != null || successCallBack != undefined) {
  259. successCallBack()
  260. }
  261. this.saving_activity = false
  262. this.publishing_activity = false
  263. this.saving_before_preview_activity = false
  264. }).catch(err => {
  265. console.log('------ ' + err)
  266. this.$message.error(err)
  267. this.saving_activity = false
  268. this.publishing_activity = false
  269. this.saving_before_preview_activity = false
  270. })
  271. }).catch(err => {
  272. console.log('asdada ' + err)
  273. this.$message.error(err)
  274. this.saving_activity = false
  275. this.publishing_activity = false
  276. this.saving_before_preview_activity = false
  277. })
  278. },
  279. validActivityInfo: function() {
  280. return new Promise((resolve, reject) => {
  281. if (this.activity.poster_photo.length == 0) {
  282. reject("海报不能为空")
  283. return
  284. } else if (this.activity.title.length == 0) {
  285. reject("标题不能为空")
  286. return
  287. } else if (this.activity.subtitle.length == 0) {
  288. reject("副标题不能为空")
  289. return
  290. } else if (this.activity.address.length == 0) {
  291. reject("活动地址不能为空")
  292. return
  293. } else if (this.activity.sign_up_deadline == 0) {
  294. reject("活动报名时间不能为空")
  295. return
  296. } else if (this.activity.start == 0) {
  297. reject("活动时间不能为空")
  298. return
  299. } else {
  300. if (this.activity.phone_number.length > 0) {
  301. if (/^1\d{10}$/.test(this.activity.phone_number) == false && /^(0\d{2,3}-?\d{7,8}$)/.test(this.activity.phone_number) == false) {
  302. reject("联系方式格式错误")
  303. return
  304. }
  305. }
  306. }
  307. resolve()
  308. })
  309. },
  310. },
  311. }
  312. </script>
  313. <style lang="scss" scoped>
  314. .edit-form-main {
  315. .form-title {
  316. width: 100%;
  317. height: 60px;
  318. padding: 20px 0 20px 30px;
  319. border-bottom: 1px #dee2e5 solid;
  320. .icon {
  321. margin-top: -4px;
  322. vertical-align: middle;
  323. }
  324. span {
  325. font-size: 18px;
  326. font-weight: 500;
  327. color: #485b6d;
  328. margin-left: 10px;
  329. }
  330. }
  331. .form-content {
  332. width: 100%;
  333. padding: 14px 30px 14px 30px;
  334. .module-panel {
  335. // padding: 0 30px;
  336. .module-title {
  337. font-size: 18px;
  338. color: #a8b3ba;
  339. img {
  340. float: left;
  341. display: block;
  342. padding: 2px 19px 0 0;
  343. }
  344. }
  345. .module-item {
  346. margin-top: 20px;
  347. display: flex;
  348. // padding: 0 30px;
  349. .item-title {
  350. width: 115px;
  351. height: 40px;
  352. line-height: 40px;
  353. color: #485b6d;
  354. font-size: 13px;
  355. // font-weight: 100;
  356. text-align: right;
  357. padding-right: 22px;
  358. float: left;
  359. }
  360. .item-input {
  361. flex: 1;
  362. color: #485b6d;
  363. }
  364. .limit-text {
  365. line-height: 40px;
  366. color: #a8b3ba;
  367. font-size: 13px;
  368. // font-weight: 100;
  369. text-align: left;
  370. padding-left: 10px;
  371. }
  372. .poster-photo-panel {
  373. display: flex;
  374. flex: 1;
  375. align-items: center;
  376. .input {
  377. flex: 1;
  378. color: #485b6d;
  379. cursor: pointer;
  380. }
  381. }
  382. }
  383. .poster-photo-hint {
  384. font-size: 12px;
  385. line-height: 16px;
  386. color: #a8b3ba;
  387. margin-left: 115px;
  388. }
  389. }
  390. .submit-button-panel {
  391. padding: 0 0 0 115px;
  392. margin-top: 30px;
  393. }
  394. }
  395. }
  396. </style>