addActivity.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. <template>
  2. <div class="addActivity app-container">
  3. <el-form
  4. :model="setQuery"
  5. ref="setQuery"
  6. :rules="rules"
  7. v-loading="loading"
  8. label-width="170px"
  9. :disabled="mode == 'detail'"
  10. >
  11. <el-form-item label="活动名称:" prop="activityName">
  12. <el-input
  13. v-model="setQuery.activityName"
  14. class="item-width-300"
  15. ></el-input>
  16. </el-form-item>
  17. <el-form-item label="活动时间:" prop="activityEndTime">
  18. <el-date-picker
  19. v-model="date"
  20. value-format="yyyy-MM-dd HH:mm:ss"
  21. class="item-width-350"
  22. type="datetimerange"
  23. :default-time="['00:00:00', '23:59:00']"
  24. range-separator="至"
  25. start-placeholder="开始日期"
  26. end-placeholder="结束日期">
  27. </el-date-picker>
  28. </el-form-item>
  29. <el-form-item label="活动类型:">
  30. <el-radio-group v-model="setQuery.activityType">
  31. <el-radio :label="1">海报</el-radio>
  32. <el-radio :label="2">报名</el-radio>
  33. </el-radio-group>
  34. </el-form-item>
  35. <template v-if="setQuery.activityType == 2">
  36. <el-form-item label="活动地址:" prop="address">
  37. <el-input
  38. v-model="setQuery.address"
  39. class="item-width-300"
  40. maxlength="100"
  41. show-word-limit
  42. ></el-input>
  43. </el-form-item>
  44. <el-form-item label="活动报名:">
  45. <el-checkbox :true-label="1" :false-label="2" v-model="setQuery.activityEnable"></el-checkbox>
  46. </el-form-item>
  47. <template v-if="setQuery.activityEnable == 1">
  48. <el-form-item label="报名次数限制:" prop="limited">
  49. <el-radio-group v-model="limited">
  50. <el-radio :label="1">每人报名次数不限</el-radio>
  51. <el-radio :label="2">每人最多报名</el-radio>
  52. </el-radio-group>
  53. <el-input
  54. v-if="limited == 2"
  55. type="number"
  56. v-model.number="setQuery.limited"
  57. class="item-width-150 ml10"
  58. >
  59. <template slot="append">人</template>
  60. </el-input>
  61. </el-form-item>
  62. <el-form-item label="报名时间:" prop="signupEndTime">
  63. <el-date-picker
  64. v-model="date1"
  65. value-format="yyyy-MM-dd HH:mm:ss"
  66. class="item-width-350"
  67. type="datetimerange"
  68. :default-time="['00:00:00', '23:59:00']"
  69. range-separator="至"
  70. start-placeholder="开始日期"
  71. end-placeholder="结束日期">
  72. </el-date-picker>
  73. </el-form-item>
  74. <el-form-item label="付费报名:" prop="price">
  75. <el-checkbox :true-label="1" :false-label="2" v-model="setQuery.payEnable">开启付费</el-checkbox>
  76. <el-input
  77. v-if="setQuery.payEnable == 1"
  78. type="number"
  79. v-model="setQuery.price"
  80. class="item-width-150 ml10"
  81. >
  82. <template slot="append">元</template>
  83. </el-input>
  84. </el-form-item>
  85. <el-form-item v-if="setQuery.payEnable == 1" label="收款方:" prop="authAccount">
  86. <el-select
  87. v-model="setQuery.authAccount"
  88. class="item-width-300"
  89. placeholder="请选择收款方"
  90. :disabled="mode == 'edit'&&status == '进行中'"
  91. >
  92. <el-option
  93. v-for="item in authOptions"
  94. :key="item.value"
  95. :label="item.label"
  96. :value="item.value"
  97. >
  98. </el-option>
  99. </el-select>
  100. </el-form-item>
  101. <el-form-item label="采集信息模板:" prop="dataCollectId">
  102. <el-select
  103. v-model="setQuery.dataCollectId"
  104. class="item-width-300"
  105. placeholder="请选择采集信息模板"
  106. :disabled="mode == 'edit'&&status == '进行中'"
  107. >
  108. <el-option
  109. v-for="item in options1"
  110. :key="item.value"
  111. :label="item.label"
  112. :value="item.value"
  113. >
  114. </el-option>
  115. </el-select>
  116. </el-form-item>
  117. </template>
  118. </template>
  119. <el-form-item label="活动封面:" prop="activityCover">
  120. <Upload
  121. width="100px"
  122. height="100px"
  123. id="activityCover"
  124. type="activityCover"
  125. :imgUrl="setQuery.activityCover"
  126. @uploadEnd="uploadEnd"
  127. :disabled="mode == 'detail'"
  128. ></Upload>
  129. </el-form-item>
  130. <el-form-item v-if="setQuery.activityType == 2" label="活动主图:" prop="activityMain">
  131. <Upload
  132. width="100px"
  133. height="100px"
  134. type="activityMain"
  135. id="activityMain"
  136. :imgUrl="setQuery.activityMain"
  137. @uploadEnd="uploadEnd"
  138. :disabled="mode == 'detail'"
  139. ></Upload>
  140. </el-form-item>
  141. <el-form-item label="活动详情:" prop="activityDetail">
  142. <div style="border: 1px solid #ccc; width: 500px">
  143. <Toolbar
  144. style="border-bottom: 1px solid #ccc"
  145. :editor="editor"
  146. :defaultConfig="toolbarConfig"
  147. :mode="editorMode"
  148. />
  149. <Editor
  150. style="height: 500px; overflow-y: hidden"
  151. v-model="setQuery.activityDetail"
  152. :defaultConfig="editorConfig"
  153. :mode="editorMode"
  154. @onCreated="onCreated"
  155. />
  156. </div>
  157. </el-form-item>
  158. </el-form>
  159. <div class="btn-group" v-if="mode != 'detail'">
  160. <el-button>取 消</el-button>
  161. <el-button type="primary" :loading="loading" @click="save"
  162. >确 定</el-button
  163. >
  164. </div>
  165. </div>
  166. </template>
  167. <script>
  168. import {activityDetail,activityAddOrUpdate,getDataTemplate,finishComplexList} from '@/api/activity'
  169. import { allFinish } from '@/api/user'
  170. import Upload from "@/components/Upload";
  171. import Vue from "vue";
  172. import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
  173. import OSS from "ali-oss";
  174. import { requestUploadImg, finishUploadImg } from "@/api/common";
  175. export default Vue.extend({
  176. components: {
  177. Upload,
  178. Editor,
  179. Toolbar,
  180. },
  181. data() {
  182. return {
  183. status:'',
  184. date:'',
  185. date1:'',
  186. editor: null,
  187. editorMode: "default", // or 'simple'
  188. toolbarConfig: {},
  189. editorConfig: {
  190. placeholder: "请输入内容...",
  191. MENU_CONF: {
  192. uploadImage: {
  193. // 自定义上传
  194. customUpload(file, insertFn) {
  195. // file 即选中的文件
  196. requestUploadImg({
  197. fineName: file.name,
  198. operate: "OTHER",
  199. }).then((res) => {
  200. if (res.state == "Success") {
  201. const client = new OSS({
  202. // yourregion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
  203. region: res.content.endPoint.split(".")[0],
  204. // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
  205. accessKeyId: res.content.token.accessKeyId,
  206. accessKeySecret: res.content.token.accessKeySecret,
  207. // 填写Bucket名称。
  208. bucket: res.content.bucket,
  209. stsToken: res.content.token.securityToken,
  210. });
  211. client
  212. .multipartUpload(res.content.paths[0].join("/"), file)
  213. .then((r) => {
  214. // 上传完成
  215. finishUploadImg([{ path: res.content.paths[0] }]).then(
  216. (msg) => {
  217. if (msg.state == "Success") {
  218. let url =
  219. "http://" +
  220. res.content.bucket +
  221. "." +
  222. res.content.endPoint +
  223. "/" +
  224. res.content.paths[0].join("/");
  225. insertFn(url, "", "");
  226. }
  227. }
  228. );
  229. })
  230. .catch((err) => {
  231. console.log(err); //上传失败之后
  232. });
  233. }
  234. });
  235. },
  236. },
  237. },
  238. },
  239. mode: "add",
  240. loading: false,
  241. limited:1,
  242. setQuery: {
  243. shopId: 0,
  244. activityType:1,
  245. "activityCover": "",
  246. "activityMain":"",
  247. "activityDetail": "",
  248. "activityEnable": 1,
  249. "activityEndTime": "",
  250. "activityName": "",
  251. "activityStartTime": "",
  252. "authAccount": "",
  253. "dataCollectId": '',
  254. "limited": 0,
  255. "payEnable": 1,
  256. "price": 0,
  257. "signupEndTime": "",
  258. "signupStartTime": ""
  259. },
  260. authOptions:[],
  261. options: [],
  262. options1:[],
  263. pickerOptions: {
  264. shortcuts: [
  265. {
  266. text: "最近一周",
  267. onClick(picker) {
  268. const end = new Date();
  269. const start = new Date();
  270. start.setTime(start.getTime() - 3600 * 1000 * 24 * 6);
  271. picker.$emit("pick", [start, end]);
  272. },
  273. },
  274. {
  275. text: "最近一个月",
  276. onClick(picker) {
  277. const end = new Date();
  278. const start = new Date();
  279. start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
  280. picker.$emit("pick", [start, end]);
  281. },
  282. },
  283. {
  284. text: "最近三个月",
  285. onClick(picker) {
  286. const end = new Date();
  287. const start = new Date();
  288. start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
  289. picker.$emit("pick", [start, end]);
  290. },
  291. },
  292. ],
  293. },
  294. };
  295. },
  296. computed: {
  297. rules() {
  298. if(this.setQuery.activityType == 1){
  299. return {
  300. activityName: [
  301. { required: true, message: "请输入活动名称", trigger: "blur" },
  302. ],
  303. activityEndTime: [
  304. { required: true, message: "请选择活动时间", trigger: "change" },
  305. ],
  306. activityDetail: [
  307. { required: true, message: "请输入活动详情", trigger: "blur" },
  308. ],
  309. activityCover: [
  310. { required: true, message: "请上传活动封面", trigger: "change" },
  311. ],
  312. }
  313. }else{
  314. return {
  315. activityName: [
  316. { required: true, message: "请输入活动名称", trigger: "blur" },
  317. ],
  318. activityEndTime: [
  319. { required: true, message: "请选择活动时间", trigger: "change" },
  320. ],
  321. signupEndTime: [
  322. { required: true, message: "请选择报名时间", trigger: "change" },
  323. ],
  324. // limited: [
  325. // { required: true, message: "请输入报名人数", trigger: "blur" },
  326. // { type:'number',min:1, message: "报名人数不能小于1", trigger: "blur" },
  327. // ],
  328. price:[
  329. { required: true, message: "请输入报名费用", trigger: "blur" },
  330. { validator: this.validatePrice, trigger: 'blur' }
  331. ],
  332. authAccount: [
  333. { required: true, message: "请选择收款账户", trigger: "change" },
  334. ],
  335. dataCollectId: [
  336. { required: true, message: "请选择信息模板", trigger: "change" },
  337. ],
  338. activityCover: [
  339. { required: true, message: "请上传活动封面", trigger: "change" },
  340. ],
  341. activityMain: [
  342. { required: true, message: "请上传活动主图", trigger: "change" },
  343. ],
  344. activityDetail: [
  345. { required: true, message: "请输入活动详情", trigger: "blur" },
  346. ],
  347. }
  348. }
  349. }
  350. },
  351. watch: {
  352. date(val){
  353. if(val){
  354. this.setQuery.activityStartTime = val[0]
  355. this.setQuery.activityEndTime = val[1]
  356. }else{
  357. this.setQuery.activityStartTime = ''
  358. this.setQuery.activityEndTime = ''
  359. }
  360. },
  361. date1(val){
  362. if(val){
  363. this.setQuery.signupStartTime = val[0]
  364. this.setQuery.signupEndTime = val[1]
  365. }else{
  366. this.setQuery.signupStartTime = ''
  367. this.setQuery.signupEndTime = ''
  368. }
  369. },
  370. limited(val){
  371. if(val == 1){
  372. this.setQuery.limited = 0
  373. this.rules.limited = [
  374. ]
  375. }else{
  376. this.setQuery.limited = 1
  377. this.rules.limited = [
  378. { required: true, message: "请输入报名人数", trigger: "blur" },
  379. { type:'number',min:1, message: "报名人数不能小于1", trigger: "blur" },
  380. ]
  381. }
  382. },
  383. 'setQuery.payEnable'(val){
  384. if(val == 1){
  385. this.rules.price = [
  386. { required: true, message: "请输入报名费用", trigger: "blur" },
  387. { validator: this.validatePrice, trigger: 'blur' }
  388. ]
  389. }else if(val == 2){
  390. delete this.rules.price
  391. this.$nextTick(()=>{
  392. this.$refs.setQuery.clearValidate('price')
  393. })
  394. }
  395. },
  396. "setQuery.activityEnable"(val){
  397. if(val == 2){//不需要报名
  398. this.setQuery.authAccount = ''
  399. this.setQuery.dataCollectId = ''
  400. this.setQuery.payEnable = 1
  401. this.limited = 1
  402. this.date1 = ''
  403. }
  404. }
  405. },
  406. methods: {
  407. validatePrice (rule, value, callback) {
  408. if(value<0.01||value>999999){
  409. callback(new Error('价格只支持0.01~999999'));
  410. }else{
  411. callback()
  412. }
  413. },
  414. onCreated(editor) {
  415. this.editor = Object.seal(editor); // 一定要用 Object.seal() ,否则会报错
  416. if (this.mode == "detail") {
  417. this.editor.disable();
  418. }
  419. },
  420. uploadEnd(val) {
  421. console.log(val);
  422. this.setQuery[val.type] = val.url;
  423. },
  424. save() {
  425. this.$refs.setQuery.validate((v) => {
  426. if (v) {
  427. this.loading = true;
  428. if(this.setQuery.activityType == 1){
  429. this.setQuery.activityEnable = 2
  430. }
  431. activityAddOrUpdate(this.setQuery).then((res) => {
  432. this.loading = false;
  433. if (res.state == "Success") {
  434. this.$notify({
  435. title: "成功",
  436. message: "操作成功",
  437. type: "success",
  438. });
  439. this.$router.push("/operationManage/activityManage/index");
  440. }else{
  441. this.loading = false;
  442. }
  443. });
  444. }else{
  445. this.$message.error('请检查是否有必填项未填');
  446. }
  447. });
  448. },
  449. // 详情
  450. get() {
  451. this.loading = true;
  452. let id = this.$route.query.id
  453. activityDetail({id}).then((res) => {
  454. this.loading = false;
  455. if (res.state == "Success") {
  456. this.setQuery = res.content;
  457. this.setQuery.id = id
  458. this.date = [this.setQuery.activityStartTime+':00',this.setQuery.activityEndTime+':00']
  459. this.date1 = [this.setQuery.signupStartTime+':00',this.setQuery.signupEndTime+':00']
  460. if(this.setQuery.limited){
  461. this.limited = 2
  462. }else{
  463. this.limited = 1
  464. }
  465. }
  466. });
  467. },
  468. // 获取模板
  469. getDataTemplate(){
  470. getDataTemplate({shopId:0}).then(res=>{
  471. if (res.state == "Success") {
  472. this.options1 = []
  473. for (const key in res.content) {
  474. if (Object.hasOwnProperty.call(res.content, key)) {
  475. this.options1.push({
  476. label:res.content[key],
  477. value:Number(key)
  478. })
  479. }
  480. }
  481. }
  482. })
  483. },
  484. // 获取当前主体下面的已签约银联账号
  485. finishComplexList(){
  486. finishComplexList({
  487. "accesseId": "",
  488. "epId": '657c35e3cae1326607ea9ed2'
  489. }).then(res=>{
  490. if(res.state == 'Success'){
  491. let list = []
  492. res.content.map(item=>{
  493. list.push({
  494. value:item.accesser_user_id,
  495. label:item.externalName
  496. })
  497. })
  498. this.authOptions = list
  499. }
  500. })
  501. },
  502. // 获取所有的已认证银联号
  503. allFinish() {
  504. allFinish().then((res) => {
  505. if (res.state == "Success") {
  506. this.authOptions = []
  507. res.content.map(item=>{
  508. this.authOptions.push({
  509. label:item.shop_name||item.accesser_user_id,
  510. value:item.accesser_user_id,
  511. })
  512. })
  513. }
  514. });
  515. }
  516. },
  517. created() {
  518. this.getDataTemplate()
  519. this.allFinish()
  520. this.mode = this.$route.query.mode || "add";
  521. this.status = this.$route.query.status
  522. if (this.$route.query.id) {
  523. this.get();
  524. }
  525. },
  526. })
  527. </script>
  528. <style src="@wangeditor/editor/dist/css/style.css"></style>
  529. <style lang="scss" >
  530. @import "@/styles/element-variables";
  531. .addActivity {
  532. padding-bottom: 40px;
  533. .item {
  534. display: flex;
  535. align-items: flex-start;
  536. margin-bottom: 10px;
  537. .ml20{
  538. margin-left: 20px !important;
  539. }
  540. .mb20{
  541. margin-bottom: 20px;
  542. }
  543. .textarea textarea{
  544. height: 40px;
  545. }
  546. .icon {
  547. font-size: 18px;
  548. font-weight: bold;
  549. margin-left: 10px;
  550. cursor: pointer;
  551. margin-top: 10px;
  552. }
  553. .box {
  554. }
  555. }
  556. .btn-group {
  557. display: flex;
  558. align-items: center;
  559. justify-content: center;
  560. }
  561. }
  562. </style>