apply.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613
  1. <!-- 门店入驻 -->
  2. <template>
  3. <view class="apply-commission-wrap page_box">
  4. <!-- 标题栏 -->
  5. <view class="head-box"><shopro-navbar back-icon-color="#fff" :background="{}"></shopro-navbar></view>
  6. <!-- 表单 -->
  7. <view class="apply-form content_box">
  8. <u-form :model="model" :rules="rules" ref="uForm" :errorType="errorType">
  9. <u-form-item :labelStyle="labelStyle"   label-width="150" label-position="left" label="姓名" prop="realname">
  10. <u-input placeholder="请输入姓名" :placeholderStyle="placeholderStyle" v-model="model.realname" type="text"></u-input>
  11. </u-form-item>
  12. <u-form-item :labelStyle="labelStyle" label-position="left" label="手机号" prop="phone" label-width="150">
  13. <u-input placeholder="请输入手机号" :placeholderStyle="placeholderStyle" v-model="model.phone" type="number"></u-input>
  14. </u-form-item>
  15. <u-form-item :labelStyle="labelStyle" label-width="150" label-position="left" label="申请名称" prop="name">
  16. <u-input placeholder="请输入门店名称" :placeholderStyle="placeholderStyle" v-model="model.name" type="text"></u-input>
  17. </u-form-item>
  18. <u-form-item :labelStyle="labelStyle" prop="images" label="展示图片" label-position="top" label-width="150" :borderBottom="true">
  19. <u-upload
  20. :placeholderStyle="placeholderStyle"
  21. :showProgress="false"
  22. @on-uploaded="uploadSuccess($event, 'storeImg')"
  23. @on-remove="uploadRemove($event, 'storeImg')"
  24. :action="`${$API_URL}/index/upload`"
  25. :file-list="model.fileImages"
  26. width="148"
  27. height="148"
  28. maxCount="1"
  29. ></u-upload>
  30. </u-form-item>
  31. <u-form-item :labelStyle="labelStyle"   label-width="150" label-position="left" label="营业时间" prop="openhours">
  32. <u-input
  33. type="select"
  34. :select-open="selectShow"
  35. v-model="model.openhours"
  36. placeholder="请选择营业时间"
  37. :placeholderStyle="placeholderStyle"
  38. @click="onSelect('time')"
  39. ></u-input>
  40. </u-form-item>
  41. <u-form-item :labelStyle="labelStyle" label-width="150" label-position="left" label="营业天数" prop="weeks">
  42. <u-input type="select" placeholder="请选择营业天数" disabled :placeholderStyle="placeholderStyle" v-model="model.weeks" @click="onSelect('week')"></u-input>
  43. </u-form-item>
  44. <u-form-item :labelStyle="labelStyle" right-icon="map-fill" :right-icon-style="{color:'#4CB89D'}" label-width="150" label-position="left" label="所在地区" prop="area">
  45. <u-input type="text" disabled v-model="model.area" placeholder="请点击定位" @click="chooseLocation"></u-input>
  46. </u-form-item>
  47. <u-form-item :border-bottom="false" :labelStyle="labelStyle" label-width="150" label-position="left" label="详细地址" prop="address">
  48. <u-input type="textarea" border placeholder="请输入详细地址~" :placeholderStyle="placeholderStyle" v-model="model.address"></u-input>
  49. </u-form-item>
  50. <view class="agreement u-flex u-col-center">
  51. <u-checkbox v-model="model.agreement" activeColor="#4CB89D" shape="circle" @change="onAgreement"></u-checkbox>
  52. <view class="agreement-text" @tap="toProtocol">勾选代表同意《申请协议》</view>
  53. </view>
  54. <view class="u-flex u-row-center u-col-center"><button class="u-reset-button save-btn" @tap="onSubmit" :disabled="isFormEnd">确认提交</button></view>
  55. </u-form>
  56. </view>
  57. <!-- 弹窗 -->
  58. <u-select v-if="selectShow" :mode="selectMode" :list="selectList" v-model="selectShow" @confirm="selectConfirm"></u-select>
  59. <!-- 选择星期 -->
  60. <u-popup v-model="showWeeksModal" safe-area-inset-bottom mode="bottom">
  61. <view class="week-modal">
  62. <view class="u-flex u-row-between u-p-x-30 week-modal--head ">
  63. <view></view>
  64. <view class="action text-green" @tap="saveWeekModal">确定</view>
  65. </view>
  66. <view class="u-flex u-flex-wrap u-p-x-30 u-p-y-30 week-modal--content">
  67. <view v-for="(item, index) in weekcheckbox" class="week-btn" :key="index">
  68. <button @tap="onSelectWeek(index)" class="cu-btn" :class="!item.checked ? 'line-green' : 'bg-green'">{{ item.name }}</button>
  69. </view>
  70. </view>
  71. </view>
  72. </u-popup>
  73. <!-- 权限验证 -->
  74. <u-popup v-model="showNotice" mode="center" border-radius="20">
  75. <view class="notice-modal">
  76. <view class="img-wrap"><image class="notice-img" :src="authNotice.img" mode=""></image></view>
  77. <view class="notice-title">{{ authNotice.title }}</view>
  78. <view class="notice-detail">{{ authNotice.detail || '' }}</view>
  79. <button class="u-reset-button notice-btn" @tap="onAuthBtn(authNotice.btnPath)">{{ authNotice.btnText }}</button>
  80. <button class="u-reset-button back-btn" @tap="$Router.back()">返回</button>
  81. </view>
  82. </u-popup>
  83. </view>
  84. </template>
  85. <script>
  86. import Auth from '@/shopro/permission/index.js';
  87. import { mapMutations, mapActions, mapState,mapGetters } from 'vuex';
  88. import { MAP_KEY } from '@/env.js';
  89. export default {
  90. components: {},
  91. data() {
  92. return {
  93. showNotice: false,
  94. showWeeksModal: false, //星期弹窗
  95. isFormEnd: false,
  96. weekcheckbox: [
  97. {
  98. value: '1',
  99. name: '周一',
  100. checked: false
  101. },
  102. {
  103. value: '2',
  104. name: '周二',
  105. checked: false
  106. },
  107. {
  108. value: '3',
  109. name: '周三',
  110. checked: false
  111. },
  112. {
  113. value: '4',
  114. name: '周四',
  115. checked: false
  116. },
  117. {
  118. value: '5',
  119. name: '周五',
  120. checked: false
  121. },
  122. {
  123. value: '6',
  124. name: '周六',
  125. checked: false
  126. },
  127. {
  128. value: '7',
  129. name: '周日',
  130. checked: false
  131. }
  132. ],
  133. authNotice: {},
  134. // 表单
  135. errorType: ['message'],
  136. selectShow: false,
  137. selectMode: 'mutil-column', // single-column, mutil-column, mutil-column-auto
  138. selectType: '',
  139. selectList: [],
  140. labelStyle: {
  141. 'font-size': '28rpx',
  142. 'font-weight': '500',
  143. color: '#333'
  144. },
  145. placeholderStyle: 'font-size: 28rpx;color:#c4c4c4;',
  146. model: {
  147. name: '', //门店名称
  148. phone: '', //手机号
  149. realname: '', //真实姓名
  150. openhours: '', //营业时间
  151. openweeks: '', //营业周期
  152. weeks: '',
  153. area: '',
  154. area_id: '', //行政区域ID
  155. address: '', //门店地址
  156. latitude: '', //纬度
  157. longitude: '', //京都
  158. images: [], //门店图片
  159. images_original: [],
  160. fileImages: [],
  161. agreement: false
  162. },
  163. rules: {
  164. name: [
  165. {
  166. required: true,
  167. message: '请输入门店名称',
  168. trigger: ['change', 'blur']
  169. }
  170. ],
  171. realname: [
  172. {
  173. required: true,
  174. message: '请输入真实姓名',
  175. trigger: ['change', 'blur']
  176. }
  177. ],
  178. area: [
  179. {
  180. required: true,
  181. message: '请定位所在地区',
  182. trigger: ['change', 'blur']
  183. }
  184. ],
  185. phone: [
  186. {
  187. required: true,
  188. message: '请输入手机号',
  189. trigger: ['change', 'blur']
  190. },
  191. {
  192. validator: (rule, value, callback) => {
  193. return this.$u.test.mobile(value);
  194. },
  195. message: '手机号码不正确',
  196. // 触发器可以同时用blur和change,二者之间用英文逗号隔开
  197. trigger: ['change', 'blur']
  198. }
  199. ],
  200. openhours: [
  201. {
  202. required: true,
  203. message: '请选择营业时间',
  204. trigger: ['change', 'blur']
  205. }
  206. ],
  207. weeks: [
  208. {
  209. required: true,
  210. message: '请选择营业天数',
  211. trigger: ['change', 'blur']
  212. }
  213. ],
  214. address: [
  215. {
  216. required: true,
  217. message: '请输入详细地址',
  218. trigger: ['change', 'blur']
  219. }
  220. ]
  221. }
  222. };
  223. },
  224. computed: {
  225. ...mapGetters(['initStore']),
  226. selectWorkerTime() {
  227. let mArr = [];
  228. for (let i = 0; i <= 24; i++) {
  229. let t = String(i).padStart(2, '0');
  230. mArr.push(
  231. {
  232. value: `${t}:00`,
  233. label: `${t}:00`
  234. },
  235. {
  236. value: `${t}:30`,
  237. label: `${t}:30`
  238. }
  239. );
  240. }
  241. mArr.pop();
  242. return [mArr, mArr];
  243. }
  244. },
  245. onLoad() {
  246. this.getStoreInfo();
  247. },
  248. onReady() {
  249. this.$refs.uForm.setRules(this.rules);
  250. },
  251. methods: {
  252. // 选择星期
  253. saveWeekModal() {
  254. this.showWeeksModal = false;
  255. let arr = [];
  256. let arr2 = [];
  257. this.weekcheckbox.forEach(item => {
  258. if (item.checked) {
  259. arr.push(item.value);
  260. arr2.push(item.name);
  261. }
  262. });
  263. this.model.openweeks = arr.join(',');
  264. this.model.weeks = arr2.join(',');
  265. },
  266. // 选择星期
  267. onSelectWeek(index) {
  268. this.weekcheckbox[index].checked = !this.weekcheckbox[index].checked;
  269. },
  270. // 弹窗按钮
  271. onAuthBtn(path) {
  272. path &&
  273. this.$Router.push({
  274. path: path
  275. });
  276. this.showNotice = false;
  277. },
  278. // 上传图片成功
  279. uploadSuccess(e, type) {
  280. switch (type) {
  281. case 'storeImg':
  282. this.model.images = [];
  283. e.forEach(item => {
  284. this.model.images.push(item.response.data.url);
  285. });
  286. break;
  287. default:
  288. return;
  289. }
  290. },
  291. // 移除图片
  292. uploadRemove(index, type) {
  293. switch (type) {
  294. case 'storeImg':
  295. this.model.images.splice(index, 1);
  296. break;
  297. default:
  298. return;
  299. }
  300. },
  301. // 地址选择
  302. async chooseLocation() {
  303. let authState = await new Auth('userLocation').check();
  304. authState &&
  305. uni.chooseLocation({
  306. success: res => {
  307. this.model.latitude = res.latitude;
  308. this.model.longitude = res.longitude;
  309. this.getLocationInfo();
  310. },
  311. fail: err => {
  312. console.log(err);
  313. }
  314. });
  315. },
  316. //逆坐标解析
  317. async getLocationInfo() {
  318. this.chooseAddress = '定位中...';
  319. const [error, res] = await uni.request({
  320. url: `https://restapi.amap.com/v3/geocode/regeo?location=${this.model.longitude},${this.model.latitude}&key=${MAP_KEY}`
  321. });
  322. if (res.data.status === '1') {
  323. const addressComponent = res.data.regeocode.addressComponent;
  324. this.model.area_id = addressComponent.adcode;
  325. this.model.area = `${addressComponent.province}-${addressComponent.city.length ? addressComponent.city : addressComponent.province}-${addressComponent.district}`;
  326. this.model.address = res.data.regeocode.formatted_address.replace(`${addressComponent.province}${addressComponent.city}${addressComponent.district}`, '');
  327. } else {
  328. console.log('%c逆地址解析失败,请检查是否在env中配置地图key', 'color:green;background:yellow');
  329. }
  330. },
  331. onSelect(type) {
  332. this.selectType = type;
  333. switch (type) {
  334. case 'time':
  335. this.selectShow = true;
  336. this.selectMode = 'mutil-column';
  337. this.selectList = this.selectWorkerTime;
  338. break;
  339. case 'week':
  340. this.showWeeksModal = true;
  341. break;
  342. default:
  343. return;
  344. }
  345. },
  346. // 选择时间
  347. selectConfirm(e) {
  348. switch (this.selectType) {
  349. case 'time':
  350. this.model.openhours = '';
  351. e.map((val, index) => {
  352. this.model.openhours += this.model.openhours == '' ? val.label : ' - ' + val.label;
  353. });
  354. break;
  355. default:
  356. return;
  357. }
  358. },
  359. // 勾选同意
  360. onAgreement(e) {
  361. this.model.agreement = e.value;
  362. },
  363. // 门店详情
  364. getStoreInfo() {
  365. let that = this;
  366. that.$http('store.shopInfo').then(res => {
  367. if (res.code === 1) {
  368. res.data && this.authStatus(res.data);
  369. }
  370. });
  371. },
  372. // 跳转门店协议
  373. toProtocol() {
  374. this.initStore.protocol && this.jump('/pages/public/richtext', { id: this.initStore.protocol })
  375. },
  376. // 初始化model
  377. initModel() {
  378. // 构建星期
  379. let weeksArr = this.model.openweeks.split(',');
  380. let weekTextArr = [];
  381. this.weekcheckbox.forEach(item => {
  382. if (weeksArr.includes(item.value)) {
  383. weekTextArr.push(item.name);
  384. item.checked = true;
  385. }
  386. });
  387. this.model.weeks = weekTextArr.join(',');
  388. // 构建省市区
  389. if (this.model.province_name) {
  390. this.model.area = `${this.model.province_name}-${this.model.city_name}-${this.model.area_name}`;
  391. }
  392. if (this.model.images) {
  393. this.model.images.forEach(item => {
  394. this.model.fileImages.push({
  395. url: item
  396. });
  397. });
  398. }
  399. // 协议
  400. this.$set(this.model, 'agreement', false);
  401. },
  402. // 状态鉴权
  403. authStatus(data) {
  404. switch (String(data.status)) {
  405. case '0':
  406. this.showNotice = true;
  407. this.model = { ...this.model, ...data };
  408. this.initModel();
  409. this.authNotice = {
  410. img: this.$IMG_URL + '/imgs/commission/auth_check.png',
  411. title: '正在审核中',
  412. detail: data.status_msg,
  413. btnText: '修改信息',
  414. btnPath: ''
  415. };
  416. break;
  417. case '-1':
  418. this.showNotice = true;
  419. this.model = { ...this.model, ...data };
  420. this.initModel();
  421. this.authNotice = {
  422. img: this.$IMG_URL + '/imgs/commission/auth_reject.png',
  423. title: '您的申请已被驳回!',
  424. detail: data.status_msg,
  425. btnText: '重新申请',
  426. btnPath: ''
  427. };
  428. break;
  429. case '1':
  430. this.showNotice = false;
  431. break;
  432. default:
  433. }
  434. },
  435. // 申请门店
  436. applyStore() {
  437. let that = this;
  438. this.isFormEnd = false;
  439. that.$http('store.apply', that.model, '提交中...').then(res => {
  440. this.isFormEnd = true;
  441. if (res.code === 1) {
  442. // #ifdef MP-WEIXIN
  443. this.$store.commit('subscribeMessage', 'storeApply');
  444. // #endif
  445. uni.showToast({
  446. title: res.msg,
  447. success: () => {
  448. that.$Router.back();
  449. }
  450. });
  451. }
  452. });
  453. },
  454. // 提交
  455. onSubmit() {
  456. let that = this;
  457. if (!that.model.images.length) {
  458. this.$u.toast('请上传门店图片');
  459. return;
  460. }
  461. this.$refs.uForm.validate(valid => {
  462. if (valid) {
  463. if (!this.model.agreement) return this.$u.toast('请勾选协议');
  464. this.applyStore();
  465. } else {
  466. this.$u.toast('请完善表单');
  467. }
  468. });
  469. },
  470. jump(path, parmas) {
  471. this.$Router.push({
  472. path: path,
  473. query: parmas
  474. });
  475. }
  476. }
  477. };
  478. </script>
  479. <style lang="scss">
  480. .apply-commission-wrap {
  481. background-color: #fff;
  482. .head-box {
  483. background: url($IMG_URL+'/imgs/user/sh_leader_apply_head.png') no-repeat;
  484. background-size: 100% auto;
  485. height: 370rpx;
  486. }
  487. }
  488. // 表单
  489. .apply-form {
  490. width: 750rpx;
  491. background: #ffffff;
  492. border-radius: 20rpx;
  493. padding: 30rpx;
  494. .agreement {
  495. margin-top: 20rpx;
  496. .agreement-text {
  497. font-size: 24rpx;
  498. font-weight: 500;
  499. color: #4cb89d;
  500. }
  501. }
  502. .save-btn {
  503. width: 690rpx;
  504. line-height: 86rpx;
  505. background: linear-gradient(90deg, #2dae9c, #6bc29e);
  506. box-shadow: 0px 7rpx 11rpx 2rpx rgba(61, 179, 156, 0.34);
  507. border-radius: 43rpx;
  508. font-weight: 500;
  509. color: #ffffff;
  510. margin: 30rpx 0;
  511. }
  512. }
  513. // 星期
  514. .week-modal {
  515. .week-modal--head {
  516. height: 100rpx;
  517. border-bottom: 1rpx solid $u-border-color;
  518. .text-cancel {
  519. color: #ccc;
  520. }
  521. .text-green {
  522. color: #18b566;
  523. }
  524. }
  525. .week-modal--content {
  526. .week-btn {
  527. margin-right: 56rpx;
  528. margin-bottom: 30rpx;
  529. &:nth-of-type(4n) {
  530. margin-right: 0;
  531. }
  532. }
  533. }
  534. }
  535. // 提示
  536. .notice-modal {
  537. display: flex;
  538. flex-direction: column;
  539. justify-content: center;
  540. align-items: center;
  541. width: 612rpx;
  542. min-height: 658rpx;
  543. background: #ffffff;
  544. padding: 30rpx;
  545. border-radius: 20rpx;
  546. .img-wrap {
  547. margin-bottom: 50rpx;
  548. .notice-img {
  549. width: 180rpx;
  550. height: 170rpx;
  551. }
  552. }
  553. .notice-title {
  554. font-size: 35rpx;
  555. font-weight: bold;
  556. color: #46351b;
  557. margin-bottom: 28rpx;
  558. }
  559. .notice-detail {
  560. font-size: 28rpx;
  561. font-weight: 400;
  562. color: #999999;
  563. line-height: 36rpx;
  564. margin-bottom: 50rpx;
  565. }
  566. .notice-btn {
  567. width: 492rpx;
  568. height: 70rpx;
  569. line-height: 70rpx;
  570. background: linear-gradient(90deg, #2dae9c, #6bc29e);
  571. box-shadow: 0 7rpx 11rpx 2rpx rgba(61, 179, 156, 0.34);
  572. border-radius: 35rpx;
  573. font-size: 28rpx;
  574. font-weight: 500;
  575. color: #ffffff;
  576. margin-bottom: 10rpx;
  577. }
  578. .back-btn {
  579. width: 492rpx;
  580. height: 70rpx;
  581. line-height: 70rpx;
  582. font-size: 28rpx;
  583. font-weight: 500;
  584. color: #3ab29c;
  585. background: none;
  586. }
  587. }
  588. </style>