activityEdit.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  1. <template>
  2. <view>
  3. <view v-if="stepOne">
  4. <view class="form">
  5. <view class="form-title">基本信息</view>
  6. <view class="form-item-title">封面图</view>
  7. <view class="upload-pic ddflex" v-if="!pic" @click="uploadImage(1)">
  8. <image src="../static/images/pic.png"></image>
  9. <view style="margin-top: 30rpx;">上传封面图</view>
  10. </view>
  11. <image v-else class="upload-image" :src="pic" @click="uploadImage(1)"></image>
  12. <view class="form-limit">* 图片尺寸限制:680*350</view>
  13. <view class="form-item-title">活动详情轮播图</view>
  14. <view class="ddflex" style="margin-top: 30rpx;">
  15. <view class="upload-photo-image" v-for="item ,index in fileList" @click="uploadImage(2,index+1)">
  16. <image :src="item" mode="aspectFill"></image>
  17. <image class="upload-photo-close" src="/static/pages/images/close3.png"
  18. @click.stop="deleteImage(2,index+1)"></image>
  19. </view>
  20. <view class="upload-photo ddflex" @click="uploadImage(2)" v-if="fileList.length<9">
  21. <image src="../static/images/photo.png"></image>
  22. </view>
  23. </view>
  24. <view class="form-limit">* 图片尺寸限制:670*350</view>
  25. </view>
  26. <view class="form-border"></view>
  27. <view class="form">
  28. <view class="form-item-title">活动标题</view>
  29. <view class="form-input-box">
  30. <input v-model="title" placeholder-class="form-input-placeholder" placeholder="请输入活动标题" />
  31. </view>
  32. <view class="form-item-title">活动说明</view>
  33. <view class="form-input-box">
  34. <input v-model="brief" placeholder-class="form-input-placeholder" placeholder="请填写活动简介说明" />
  35. </view>
  36. <view class="form-item-title">
  37. 活动详情
  38. <view class="more ddflex" @click="jumpUrl('/match/editorContent/editorContent')">
  39. <text v-if="!text">编辑</text>
  40. <text v-else style="color: var(--main);">已完善</text>
  41. <image src="../../static/pages/images/more.png"></image>
  42. </view>
  43. </view>
  44. <view class="form-input-box" style="padding: 18rpx 0;">
  45. </view>
  46. <view class="form-item-title">
  47. 自定义报名信息
  48. <view class="more ddflex" @click="jumpUrl('/match/addForm/addForm')">
  49. <text style="color: #999;" v-if="!extForm">添加(非必填)</text>
  50. <text v-else style="color: var(--main);">已添加</text>
  51. <image src="../../static/pages/images/more.png"></image>
  52. </view>
  53. </view>
  54. <view class="next-btn" @click="next">下一步</view>
  55. </view>
  56. </view>
  57. <!-- 第二步 -->
  58. <view v-if="stepTwo">
  59. <view class="form">
  60. <view class="form-title">报名设置</view>
  61. <view class="form-item-title">最大报名人数</view>
  62. <view class="form-number-select ddflex">
  63. <view>-</view>
  64. <input v-model="personLimit" type="number" placeholder="最大报名人数"
  65. placeholder-class="form-input-placeholder" />
  66. <view>+</view>
  67. </view>
  68. <view class="form-item-title">报名时间</view>
  69. <view class="ddflex" style="margin-top: 20rpx;">
  70. <picker v-model="enlistStartTime" mode="date" class="flex" @change="enlistStartTimeChange">
  71. <view class="form-date-select" :style="enlistStartTime?'color:#333':''">
  72. {{enlistStartTime?enlistStartTime:'开始日期'}}
  73. </view>
  74. </picker>
  75. <text style="margin: 0 20rpx;">至</text>
  76. <picker v-model="enlistEndTime" mode="date" class="flex" @change="enlistEndTimeChange">
  77. <view class="form-date-select" :style="enlistEndTime?'color:#333':''">
  78. {{enlistEndTime?enlistEndTime:'结束日期'}}
  79. </view>
  80. </picker>
  81. </view>
  82. <view class="form-item-title">活动时间</view>
  83. <view class="ddflex" style="margin-top: 20rpx;">
  84. <picker v-model="startTime" mode="date" class="flex" @change="startTimeChange">
  85. <view class="form-date-select" :style="startTime?'color:#333':''">
  86. {{startTime?startTime:"开始日期"}}
  87. </view>
  88. </picker>
  89. <text style="margin: 0 20rpx;">至</text>
  90. <picker v-model="endTime" mode="date" class="flex" @change="endTimeChange">
  91. <view class="form-date-select" :style="endTime?'color:#333':''">
  92. {{endTime?endTime:"结束日期"}}
  93. </view>
  94. </picker>
  95. </view>
  96. </view>
  97. <view class="form-border"></view>
  98. <view class="form">
  99. <view class="form-title">活动地址</view>
  100. <view class="form-item-title">地址名称</view>
  101. <view class="form-input-box">
  102. <input v-model="house" placeholder-class="form-input-placeholder" placeholder="请输入活动地址简称" />
  103. </view>
  104. <view class="form-item-title">选择城市</view>
  105. <view class="form-input-box">
  106. <!-- <picker class="form-input-placeholder" mode="region" @change="bindRegionChange" :value="region" > -->
  107. <view class="picker" :style="region.length>0?'color: #333;':'color:#cccccc'"
  108. @click="chooseLocation()">
  109. {{region.length > 0 ? region[0]+region[1]+region[2] : '请选择所在城市'}}
  110. </view>
  111. <!-- </picker> -->
  112. <!-- <image src="/card/static/images/area.png" class="loca" @click="chooseLocation()"></image> -->
  113. </view>
  114. <view class="form-item-title">
  115. 详细地址
  116. </view>
  117. <view class="form-input-box">
  118. <input v-model="address" placeholder-class="form-input-placeholder" placeholder="请输入详细地址" />
  119. </view>
  120. <view class="form-item-title ddflex" style="justify-content: space-between;">
  121. 是否全省通用
  122. <switch v-model="isAllSee" :checked="isAllSee" style="transform:scale(0.7)" color="var(--main)"
  123. @change="powerChange"></switch>
  124. </view>
  125. <block v-if="!isAllSee">
  126. <view class="form-input-box" style="border-bottom: none;" @click="showPop()">
  127. 已选择{{checkNum}}个区域
  128. <view class="more ddflex">
  129. <!-- <text v-if="!text">编辑</text>
  130. <text v-else style="color: var(--main);">已完善</text> -->
  131. <image src="../../static/pages/images/more.png"></image>
  132. </view>
  133. </view>
  134. <view class="form-item-title" style="color: red;font-size: 24rpx;margin-top: 0rpx;" v-if="checkNum==0">
  135. *请选择活动生效区域
  136. </view>
  137. <view class="mask" v-if="isShowPop" @click="hidePop"></view>
  138. <view class="popup" v-if="isShowPop">
  139. <view class="popupc ddflex">
  140. <view class="pleft">
  141. <view :class="'li ddflex' + (checkIndex == index ? ' active':'')" style="justify-content: space-between;"
  142. v-for="(item,index) in industryList" :key="index" @click="checkIndustry(index)">
  143. <view class="fflex tover">{{item.label}}</view>
  144. <image v-if="item.isActive" style="width: 25rpx;height: 25rpx;margin-left: 10rpx;" src="/match/static/images/checkBox_h.png" @click.stop="checkBoxIndustry(index)"></image>
  145. <image v-else style="width: 25rpx;height: 25rpx;margin-left: 10rpx;" src="/match/static/images/checkBox.png" @click.stop="checkBoxIndustry(index)"></image>
  146. </view>
  147. </view>
  148. <view class="pright">
  149. <view :class="'li ddflex' + (arrayIndex == index ? ' active':'')" style="justify-content: space-between;"
  150. v-for="(item,index) in rightArray" :key="index" @click="checkArray(index)">
  151. <view class="fflex tover">{{item.label}}</view>
  152. <image v-if="item.isActive" style="width: 25rpx;height: 25rpx;margin-left: 10rpx;" src="/match/static/images/checkBox_h.png" @click.stop="checkBoxArray(index)"></image>
  153. <image v-else style="width: 25rpx;height: 25rpx;margin-left: 10rpx;" src="/match/static/images/checkBox.png" @click.stop="checkBoxArray(index)"></image>
  154. </view>
  155. </view>
  156. </view>
  157. </view>
  158. </block>
  159. <view class="next-btn" @click="submit()">提交</view>
  160. </view>
  161. </view>
  162. </view>
  163. </template>
  164. <script>
  165. import util from "../../utils/util.js";
  166. const app = getApp();
  167. const req = require("../../utils/request.js");
  168. export default {
  169. components: {},
  170. props: {},
  171. data() {
  172. return {
  173. stepOne: true,
  174. stepTwo: false,
  175. pic: '', //封面图
  176. fileList: [], //banner
  177. title: '',
  178. brief: '',
  179. text: '',
  180. personLimit: -1,
  181. enlistStartTime: '',
  182. enlistEndTime: '',
  183. startTime: '',
  184. endTime: '',
  185. house: '',
  186. region: [],
  187. address: '',
  188. regionCode: [],
  189. id: '',
  190. longitude: null,
  191. latitude: null,
  192. isAllSee: true,
  193. isShowPop: false,
  194. checkIndex: 0,
  195. industryList: [],
  196. arrayIndex: -1,
  197. rightArray: [],
  198. companyTreeList:[],
  199. checkNum:0,
  200. extForm:''
  201. }
  202. },
  203. async onLoad(options) {
  204. this.id = options.id
  205. await this.getCompanyTreeList()
  206. if (this.id) {
  207. this.getActivityInfo()
  208. }
  209. },
  210. onShow() {
  211. },
  212. methods: {
  213. jumpUrl(url) {
  214. uni.navigateTo({
  215. url: url
  216. })
  217. },
  218. // 获取公司代码
  219. getCompanyTreeList(){
  220. return new Promise((r,j)=>{
  221. req.getRequest('/api/company/treeList',{},res=>{
  222. this.companyTreeList = res
  223. this.industryList = this.companyTreeList[0].children
  224. this.rightArray = this.industryList[0].children
  225. r()
  226. })
  227. })
  228. },
  229. checkIndustry(index){
  230. if(this.checkIndex == index) return false;
  231. this.checkIndex = index;
  232. this.rightArray = this.industryList[this.checkIndex].children;
  233. },
  234. checkBoxIndustry(index){
  235. if(this.industryList[index].isActive){
  236. this.industryList[index].isActive = false
  237. this.industryList[index].children.map(item=>{item.isActive = false})
  238. }else{
  239. this.industryList[index].isActive = true
  240. this.industryList[index].children.map(item=>{item.isActive = true})
  241. }
  242. this.industryList = JSON.parse(JSON.stringify(this.industryList))
  243. this.checkIndex = index;
  244. this.rightArray = this.industryList[this.checkIndex].children;
  245. },
  246. checkBoxArray(index){
  247. if(this.industryList[this.checkIndex].children[index].isActive){
  248. this.industryList[this.checkIndex].children[index].isActive = false
  249. }else{
  250. this.industryList[this.checkIndex].children[index].isActive = true
  251. }
  252. console.log(this.industryList[this.checkIndex].children.some(item=>item.isActive == false))
  253. if(this.industryList[this.checkIndex].children.some(item=>item.isActive == true)){
  254. this.industryList[this.checkIndex].isActive = true
  255. }else{
  256. this.industryList[this.checkIndex].isActive = false
  257. }
  258. this.industryList = JSON.parse(JSON.stringify(this.industryList))
  259. this.rightArray = this.industryList[this.checkIndex].children;
  260. },
  261. getCheckNum(){
  262. console.log(this.checkNum)
  263. this.checkNum = 0
  264. if(!this.isAllSee){
  265. this.industryList.map(item=>{
  266. item.children.map(it=>{
  267. if(it.isActive){
  268. this.checkNum++
  269. }
  270. })
  271. })
  272. }
  273. },
  274. getActivityInfo() {
  275. req.getRequest('/api/match/detail', {
  276. id: this.id
  277. }, res => {
  278. this.pic = res.pic
  279. this.fileList = res.imageList.map(item => {
  280. return item.url
  281. })
  282. this.title = res.title
  283. this.brief = res.brief
  284. this.text = res.text
  285. this.personLimit = res.personLimit
  286. this.extForm = res.extForm
  287. this.enlistStartTime = this.formatTime(res.enlistStartTime)
  288. this.enlistEndTime = this.formatTime(res.enlistEndTime)
  289. this.startTime = this.formatTime(res.startTime)
  290. this.endTime = this.formatTime(res.endTime)
  291. this.house = res.house
  292. this.regionCode = [res.province, res.city, res.country]
  293. this.region = res.areaAdd.split(',')
  294. this.address = res.address
  295. this.longitude = res.lng ? res.lng : null
  296. this.latitude = res.lat ? res.lat : null
  297. if(res.areaCodeList.length>0){
  298. this.isAllSee = false
  299. let areaCodeList = res.areaCodeList.map(item=>item.areaCode)
  300. this.industryList.map(item=>{
  301. item.children.map(it=>{
  302. if(areaCodeList.indexOf(it.value)>-1){
  303. it.isActive = true
  304. }else{
  305. it.isActive = false
  306. }
  307. })
  308. if(item.children.some(it=>it.isActive == true)){
  309. item.isActive = true
  310. }else{
  311. item.isActive = false
  312. }
  313. })
  314. this.getCheckNum()
  315. }else{
  316. this.isAllSee = true
  317. }
  318. })
  319. },
  320. next() {
  321. if (!this.pic) {
  322. return req.msg('请上传封面图')
  323. }
  324. if (this.fileList.length == 0) {
  325. return req.msg('请上传活动轮播图')
  326. }
  327. if (!this.title) {
  328. return req.msg('请填写活动名称')
  329. }
  330. if (!this.brief) {
  331. return req.msg('请填写活动简介')
  332. }
  333. if (!this.text) {
  334. return req.msg('请填写活动详情')
  335. }
  336. this.stepOne = false
  337. this.stepTwo = true
  338. },
  339. uploadImage(type, index) {
  340. let that = this;
  341. let count = 1
  342. if (type == 1) {
  343. count = 1
  344. } else if (type == 2) {
  345. if (index) {
  346. count = 1
  347. } else {
  348. count = 9 - that.fileList.length
  349. }
  350. }
  351. uni.chooseImage({
  352. count: count,
  353. sizeType: ['original', 'compressed'],
  354. sourceType: ['album', 'camera'],
  355. success: function({
  356. tempFilePaths
  357. }) {
  358. var promise = Promise.all(
  359. tempFilePaths.map(tempFilePath => {
  360. return new Promise(function(resolve, reject) {
  361. req.uploadFile('/api/nocheck/upload', tempFilePath,
  362. res => {
  363. // type 1 封面图
  364. if (type == 1) {
  365. that.pic = res.src
  366. } else if (type == 2) {
  367. if (index) {
  368. that.fileList[index] = res.src
  369. that.fileList = JSON.parse(JSON
  370. .stringify(that.fileList))
  371. } else {
  372. that.fileList = that.fileList.concat(
  373. res.src)
  374. }
  375. }
  376. });
  377. });
  378. })
  379. );
  380. promise
  381. .then(function(results) {
  382. console.log(results);
  383. })
  384. .catch(function(err) {
  385. console.log(err);
  386. });
  387. }
  388. });
  389. },
  390. deleteImage(type, index) {
  391. if (type == 2)
  392. this.fileList.splice(index, 1)
  393. },
  394. enlistStartTimeChange(e) {
  395. if (this.enlistEndTime) {
  396. if (this.enlistEndTime < e.detail.value)
  397. return req.msg('报名开始时间不能大于结束时间')
  398. }
  399. this.enlistStartTime = e.detail.value
  400. },
  401. enlistEndTimeChange(e) {
  402. if (this.enlistStartTime) {
  403. if (this.enlistStartTime > e.detail.value)
  404. return req.msg('报名结束时间不能小于开始时间')
  405. }
  406. this.enlistEndTime = e.detail.value
  407. },
  408. startTimeChange(e) {
  409. if (this.endTime) {
  410. if (this.endTime < e.detail.value)
  411. return req.msg('活动开始时间不能大于结束时间')
  412. }
  413. this.startTime = e.detail.value
  414. },
  415. endTimeChange(e) {
  416. if (this.startTime) {
  417. if (this.startTime > e.detail.value)
  418. return req.msg('活动结束时间不能小于开始时间')
  419. }
  420. this.endTime = e.detail.value
  421. },
  422. chooseLocation() {
  423. var tha = this;
  424. uni.chooseLocation({
  425. success: function(res) {
  426. if (res.name) {
  427. tha.address = res.name;
  428. tha.reverseGeocoder(res);
  429. console.log('地址数据》》》:', res);
  430. }
  431. }
  432. });
  433. },
  434. reverseGeocoder(location) {
  435. // #ifdef H5
  436. location = location.latitude + ',' + location.longitude
  437. let url = 'https://apis.map.qq.com/ws/geocoder/v1/?address=';
  438. this.$jsonp(url, {
  439. key: req.public.mapLBSKEY,
  440. location: location,
  441. output: 'jsonp'
  442. }).then(data => {
  443. console.log('解析后的地址地址数据:', data);
  444. data = data.result
  445. this.region = [data.ad_info.province, data.ad_info.city, data.ad_info.district]
  446. this.regionCode = [data.ad_info.adcode.substring(0, 2) + '0000', data.ad_info.adcode.substring(
  447. 0, 4) + '00', data.ad_info.adcode]
  448. this.longitude = data.ad_info.location.lng
  449. this.latitude = data.ad_info.location.lat
  450. }).catch(err => {
  451. console.log(err);
  452. });
  453. // #endif
  454. // #ifndef H5
  455. QQMapWX.initMap();
  456. QQMapWX.reverseGeocoder(location, data => {
  457. console.log('解析后的地址地址数据:', data);
  458. this.region = [data.ad_info.province, data.ad_info.city, data.ad_info.district]
  459. this.regionCode = [data.ad_info.adcode.substring(0, 2) + '0000', data.ad_info.adcode.substring(
  460. 0, 4) + '00', data.ad_info.adcode]
  461. this.longitude = data.ad_info.location.lng
  462. this.latitude = data.ad_info.location.lat
  463. });
  464. //#endif
  465. },
  466. bindRegionChange(event) {
  467. console.log(event)
  468. this.region = event.detail.value
  469. this.regionCode = event.detail.code
  470. },
  471. powerChange(e) {
  472. this.isAllSee = e.detail.value
  473. },
  474. showPop(){
  475. this.isShowPop = true;
  476. },
  477. hidePop(){
  478. this.isShowPop = false;
  479. this.getCheckNum()
  480. },
  481. submit() {
  482. if (!this.pic) {
  483. return req.msg('请上传封面图')
  484. }
  485. if (this.fileList.length == 0) {
  486. return req.msg('请上传活动轮播图')
  487. }
  488. if (!this.title) {
  489. return req.msg('请填写活动名称')
  490. }
  491. if (!this.brief) {
  492. return req.msg('请填写活动简介')
  493. }
  494. if (!this.text) {
  495. return req.msg('请填写活动详情')
  496. }
  497. if (!this.enlistStartTime) {
  498. return req.msg('请选择报名开始时间')
  499. }
  500. if (!this.enlistEndTime) {
  501. return req.msg('请选择报名结束时间')
  502. }
  503. if (!this.startTime) {
  504. return req.msg('请选择活动开始时间')
  505. }
  506. if (!this.endTime) {
  507. return req.msg('请选择活动结束时间')
  508. }
  509. if (!this.house) {
  510. return req.msg('请填写活动地址')
  511. }
  512. if (this.regionCode.length == 0) {
  513. return req.msg('请选择活动所在城市')
  514. }
  515. if (!this.address) {
  516. return req.msg('请填写详细地址')
  517. }
  518. let areaCodeList = []
  519. if(!this.isAllSee){
  520. this.industryList.map(item=>{
  521. item.children.map(it=>{
  522. if(it.isActive){
  523. areaCodeList.push({
  524. areaCode:it.value
  525. })
  526. }
  527. })
  528. })
  529. if(areaCodeList.length==0){
  530. return req.msg('请选择活动生效区域')
  531. }
  532. }else{
  533. areaCodeList.push({
  534. areaCode:this.companyTreeList[0].value
  535. })
  536. }
  537. let dataP = {
  538. pic: this.pic,
  539. fileList: JSON.stringify(this.fileList.map(item => {
  540. return {
  541. url: item
  542. }
  543. })),
  544. title: this.title,
  545. brief: this.brief,
  546. text: this.text,
  547. personLimit: this.personLimit,
  548. enlistStartTime: this.enlistStartTime,
  549. enlistEndTime: this.enlistEndTime,
  550. startTime: this.startTime,
  551. endTime: this.endTime,
  552. house: this.house,
  553. province: this.regionCode[0],
  554. city: this.regionCode[1],
  555. country: this.regionCode[2],
  556. areaAdd: this.region.join(','),
  557. address: this.address,
  558. lng: this.longitude,
  559. lat: this.latitude,
  560. areaCodeList:areaCodeList
  561. }
  562. let prices = [{
  563. title: "VIP",
  564. marketMoney: 0,
  565. money: 0,
  566. vipMoney: 0,
  567. vipModels: [],
  568. personCount: 1,
  569. isDefault: 0
  570. }]
  571. dataP.prices = prices
  572. dataP.extForm = this.extForm?this.extForm:null
  573. let url = '/api/match/save'
  574. if (this.id) {
  575. dataP.id = this.id
  576. url = '/api/match/update'
  577. uni.showModal({
  578. title: '提示',
  579. content: '修改活动将重新审核,确定修改?',
  580. success: (res) => {
  581. if (res.confirm) {
  582. req.postRequest(url, dataP, res => {
  583. req.msg('创建成功')
  584. let pages = getCurrentPages();
  585. var prevPage = pages[pages.length - 2];
  586. if (prevPage) {
  587. prevPage.$vm.isLoad = true
  588. prevPage.$vm.form.page = 1
  589. prevPage.$vm.getPageList()
  590. }
  591. setTimeout(() => {
  592. uni.navigateBack()
  593. }, 1000)
  594. })
  595. }
  596. }
  597. })
  598. } else {
  599. req.postRequest(url, dataP, res => {
  600. req.msg('创建成功')
  601. let pages = getCurrentPages();
  602. var prevPage = pages[pages.length - 2];
  603. if (prevPage) {
  604. prevPage.$vm.isLoad = true
  605. prevPage.$vm.form.page = 1
  606. prevPage.$vm.getPageList()
  607. }
  608. setTimeout(() => {
  609. uni.navigateBack()
  610. }, 1000)
  611. })
  612. }
  613. },
  614. formatTime(date) {
  615. date = new Date(date.replace(/-/g, '/'))
  616. return util.formatTime(date).t3
  617. },
  618. },
  619. mounted() {
  620. }
  621. }
  622. </script>
  623. <style>
  624. @import "./activityEdit.css";
  625. </style>