merchant.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655
  1. <template>
  2. <s-layout class="set-wrap" title="商家入驻" :bgStyle="{ color: '#FFF' }">
  3. <template v-if="state.canUse">
  4. <uni-forms :model="state.model" :rules="state.rules" validateTrigger="bind" labelPosition="left" border
  5. class="form-box" labelWidth='200' ref="merchantFormRef">
  6. <view class="bg-white ss-p-x-30">
  7. <uni-forms-item name="name" label="商家名称" :required="!state.formStatus">
  8. <uni-easyinput v-model="state.model.name" type="name" placeholder="请输入商家名称" :inputBorder="false"
  9. :placeholderStyle="placeholderStyle" :clearable="false" :disabled="state.formStatus" />
  10. </uni-forms-item>
  11. <uni-forms-item name="contact" label="联络人" :required="!state.formStatus">
  12. <uni-easyinput v-model="state.model.contact" type="contact" placeholder="请输入联络人"
  13. :inputBorder="false" :placeholderStyle="placeholderStyle" :clearable="false"
  14. :disabled="state.formStatus" />
  15. </uni-forms-item>
  16. <uni-forms-item name="contactNumber" label="联络人手机号" :required="!state.formStatus">
  17. <uni-easyinput v-model="state.model.contactNumber" type="contactNumber" placeholder="请输入联络人手机号"
  18. :inputBorder="false" :placeholderStyle="placeholderStyle" :clearable="false"
  19. :disabled="state.formStatus" />
  20. </uni-forms-item>
  21. <uni-forms-item name="legalPerson" label="法人" :required="!state.formStatus">
  22. <uni-easyinput v-model="state.model.legalPerson" type="legalPerson" placeholder="请输入法人"
  23. :inputBorder="false" :placeholderStyle="placeholderStyle" :clearable="false"
  24. :disabled="state.formStatus" />
  25. </uni-forms-item>
  26. <uni-forms-item name="legalPersonNumber" label="法人手机号" :required="!state.formStatus">
  27. <uni-easyinput v-model="state.model.legalPersonNumber" type="legalPersonNumber"
  28. placeholder="请输入法人手机号" :inputBorder="false" :placeholderStyle="placeholderStyle"
  29. :clearable="false" :disabled="state.formStatus" />
  30. </uni-forms-item>
  31. <uni-forms-item name="identityCardFront" label="法人身份证正面" :required="!state.formStatus"
  32. :errorMessage="state.identityCardFrontError">
  33. <s-uploader v-model:url="state.model.identityCardFront" fileMediatype="image" limit="1"
  34. mode="grid" :imageStyles="{ width: '299rpx', height: '168rpx' }"
  35. :readonly="state.formStatus" />
  36. </uni-forms-item>
  37. <uni-forms-item name="identityCardReverseSide" label="法人身份证反面" :required="!state.formStatus"
  38. :errorMessage="identityCardReverseSideError">
  39. <s-uploader v-model:url="state.model.identityCardReverseSide" fileMediatype="image" limit="1"
  40. mode="grid" :imageStyles="{ width: '299rpx', height: '168rpx' }"
  41. :readonly="state.formStatus" />
  42. </uni-forms-item>
  43. <uni-forms-item name="areaId" label="所在地" :required="!state.formStatus"
  44. :errorMessage="state.areaIdError">
  45. <uni-data-picker v-model="state.model.areaId" :localdata="areaTree"
  46. :readonly="state.formStatus" />
  47. </uni-forms-item>
  48. <uni-forms-item name="email" label="邮箱" :required="!state.formStatus">
  49. <uni-easyinput v-model="state.model.email" type="email" placeholder="请输入邮箱" :inputBorder="false"
  50. :placeholderStyle="placeholderStyle" :clearable="false" :disabled="state.formStatus" />
  51. </uni-forms-item>
  52. <uni-forms-item name="address" label="办公地址">
  53. <uni-easyinput v-model="state.model.address" type="address" placeholder="请输入办公地址"
  54. :inputBorder="false" :placeholderStyle="placeholderStyle" :clearable="false"
  55. :disabled="state.formStatus" />
  56. </uni-forms-item>
  57. <uni-forms-item name="complaintsHotline" label="维权电话">
  58. <uni-easyinput v-model="state.model.complaintsHotline" type="complaintsHotline"
  59. placeholder="请输入维权电话" :inputBorder="false" :placeholderStyle="placeholderStyle"
  60. :clearable="false" :disabled="state.formStatus" />
  61. </uni-forms-item>
  62. <uni-forms-item name="customerServiceHotline" label="客服电话" :required="!state.formStatus">
  63. <uni-easyinput v-model="state.model.customerServiceHotline" type="customerServiceHotline"
  64. placeholder="请输入客服电话" :inputBorder="false" :placeholderStyle="placeholderStyle"
  65. :clearable="false" :disabled="state.formStatus" />
  66. </uni-forms-item>
  67. <uni-forms-item name="website" label="官网">
  68. <uni-easyinput v-model="state.model.website" type="website" placeholder="请输入官网"
  69. :inputBorder="false" :placeholderStyle="placeholderStyle" :clearable="false"
  70. :disabled="state.formStatus" />
  71. </uni-forms-item>
  72. <uni-forms-item name="bankName" label="开户银行" :required="!state.formStatus">
  73. <uni-easyinput v-model="state.model.bankName" type="bankName" placeholder="请输入开户银行"
  74. :inputBorder="false" :placeholderStyle="placeholderStyle" :clearable="false"
  75. :disabled="state.formStatus" />
  76. </uni-forms-item>
  77. <uni-forms-item name="accountName" label="账户名称" :required="!state.formStatus">
  78. <uni-easyinput v-model="state.model.accountName" type="accountName" placeholder="请输入账户名称"
  79. :inputBorder="false" :placeholderStyle="placeholderStyle" :clearable="false"
  80. :disabled="state.formStatus" />
  81. </uni-forms-item>
  82. <uni-forms-item name="accountNumber" label="账户号码" :required="!state.formStatus">
  83. <uni-easyinput v-model="state.model.accountNumber" type="number" placeholder="请输入账户号码"
  84. :inputBorder="false" :placeholderStyle="placeholderStyle" :clearable="false"
  85. :disabled="state.formStatus" />
  86. </uni-forms-item>
  87. <uni-forms-item name="logoUrl" label="Logo">
  88. <s-uploader v-model:url="state.model.logoUrl" fileMediatype="image" limit="1" mode="grid"
  89. :imageStyles="{ width: '299rpx', height: '168rpx' }" :readonly="state.formStatus" />
  90. </uni-forms-item>
  91. <uni-forms-item name="businessLicensePicture" label="营业执照" :required="!state.formStatus"
  92. :errorMessage="state.businessLicensePictureError">
  93. <s-uploader v-model:url="state.model.businessLicensePicture" fileMediatype="image" limit="1"
  94. mode="grid" :imageStyles="{ width: '299rpx', height: '168rpx' }"
  95. :readonly="state.formStatus" />
  96. </uni-forms-item>
  97. <uni-forms-item name="brandLicensing" label="品牌授权书" :required="!state.formStatus"
  98. :errorMessage="state.brandLicensingError">
  99. <s-uploader v-model:url="state.model.brandLicensing" fileMediatype="image" limit="1" mode="grid"
  100. :imageStyles="{ width: '299rpx', height: '168rpx' }" :readonly="state.formStatus" />
  101. <view class="ss-m-t-20 " style="color: var(--ui-BG-Main);" @click="downloadTemplate"
  102. v-if="!state.model.brandLicensing">
  103. 下载模板
  104. </view>
  105. </uni-forms-item>
  106. <uni-forms-item name="otherCertificate" label="其他证书">
  107. <s-uploader v-model:url="state.model.otherCertificate" fileMediatype="image" limit="9"
  108. mode="grid" :imageStyles="{ width: '299rpx', height: '168rpx' }"
  109. :readonly="state.formStatus" />
  110. </uni-forms-item>
  111. <uni-forms-item name="description" label="简介" :required="!state.formStatus">
  112. <uni-easyinput v-model="state.model.description" type="description" placeholder="请输入简介"
  113. :inputBorder="false" :placeholderStyle="placeholderStyle" :clearable="false"
  114. :disabled="state.formStatus" />
  115. </uni-forms-item>
  116. <uni-forms-item name="description" label="状态" v-if="state.userApplyStatus">
  117. <uni-easyinput v-model="statusName" type="description" :inputBorder="false"
  118. :placeholderStyle="placeholderStyle" :clearable="false" :disabled="true" />
  119. </uni-forms-item>
  120. </view>
  121. </uni-forms>
  122. <su-fixed bottom placeholder bg="none">
  123. <view class="footer-box ss-p-20 ss-flex">
  124. <!-- 审核中不允许改 -->
  125. <!-- 通过后 变动 -->
  126. <!-- {{"用户是否申请过:"+state.userApplyStatus}}
  127. {{"当前状态"+state.model.checkStatus}}
  128. {{"当前状态是否能改动:" + !state.formStatus}} -->
  129. <button class="ss-rest-button btn" @tap="onSubmit" v-if="!state.userApplyStatus">提交</button>
  130. <template v-if="[0].includes(state.model.checkStatus)">
  131. <button class="ss-rest-button btn">审核中</button>
  132. </template>
  133. <template v-if="[1,2].includes(state.model.checkStatus)">
  134. <template v-if="!state.changeIng">
  135. <button class="ss-rest-button btn-two" @tap="openList">审核记录</button>
  136. <button class="ss-rest-button btn-two" @tap="onChange">变动</button>
  137. </template>
  138. <template v-else>
  139. <button class="ss-rest-button btn-two" @tap="onCancel">取消</button>
  140. <button class="ss-rest-button btn-two" @tap="onSave">保存并提交</button>
  141. </template>
  142. </template>
  143. </view>
  144. </su-fixed>
  145. </template>
  146. <template v-if="!state.canUse">
  147. <view style="position: fixed;top: 50%;left: 50%;transform: translate(-50%,-50%);text-align:center">当前用户({{userInfo.mobile}})<br/>
  148. 已存在商户账号<br/>
  149. 请更换账号申请!
  150. </view>
  151. </template>
  152. </s-layout>
  153. </template>
  154. <script setup>
  155. import {
  156. computed,
  157. reactive,
  158. onBeforeMount,
  159. ref,
  160. unref,
  161. watch
  162. } from 'vue';
  163. import sheep from '@/sheep';
  164. import {
  165. clone
  166. } from 'lodash';
  167. import {
  168. onLoad
  169. } from '@dcloudio/uni-app';
  170. import SaleApi from '@/sheep/api/sale/sale';
  171. import AreaApi from '@/sheep/api/system/area'
  172. import {
  173. email
  174. } from '@/sheep/validate/form';
  175. import {
  176. showAuthModal
  177. } from '@/sheep/hooks/useModal';
  178. const userInfo = computed(() => sheep.$store('user').userInfo);
  179. const state = reactive({
  180. canUse: true, //用户是否可以打开页面true 可以,false不行
  181. userApplyStatus: false, //用户是否已经申请过false未无 true为有
  182. formStatus: false, // 当前表单是否可以修改
  183. changeIng: false, //当前是否在修改
  184. model: {
  185. checkStatus: undefined,
  186. id: undefined,
  187. name: undefined,
  188. status: undefined,
  189. description: undefined,
  190. contact: undefined,
  191. address: undefined,
  192. contactNumber: undefined,
  193. website: undefined,
  194. createTime: undefined,
  195. complaintsHotline: undefined,
  196. customerServiceHotline: undefined,
  197. email: undefined,
  198. businessLicensePicture: undefined,
  199. expireTime: undefined,
  200. areaId: undefined,
  201. accountName: undefined,
  202. accountNumber: undefined,
  203. bankName: undefined,
  204. logoUrl: undefined,
  205. brandLicensing: undefined,
  206. otherCertificate: [],
  207. legalPerson: undefined,
  208. legalPersonNumber: undefined,
  209. identityCardFront: undefined,
  210. identityCardReverseSide: undefined,
  211. },
  212. areaIdError: '',
  213. businessLicensePictureError: '',
  214. brandLicensingError: '',
  215. identityCardFrontError: '',
  216. identityCardReverseSideError: '',
  217. rules: {
  218. name: {
  219. rules: [{
  220. required: true,
  221. errorMessage: '商户名称不能为空',
  222. }, ],
  223. },
  224. description: {
  225. rules: [{
  226. required: true,
  227. errorMessage: '简介不能为空',
  228. }, ],
  229. },
  230. contact: {
  231. rules: [{
  232. required: true,
  233. errorMessage: '联络人不能为空',
  234. }, ],
  235. },
  236. contactNumber: {
  237. rules: [{
  238. required: true,
  239. errorMessage: '联络人手机号不能为空',
  240. }, ],
  241. },
  242. customerServiceHotline: {
  243. rules: [{
  244. required: true,
  245. errorMessage: '客服电话不能为空',
  246. }, ],
  247. },
  248. email,
  249. legalPerson: {
  250. rules: [{
  251. required: true,
  252. errorMessage: '法人不能为空',
  253. }, ],
  254. },
  255. legalPersonNumber: {
  256. rules: [{
  257. required: true,
  258. errorMessage: '法人电话不能为空',
  259. }, ],
  260. },
  261. accountName: {
  262. rules: [{
  263. required: true,
  264. errorMessage: '账户名称不能为空',
  265. }, ],
  266. },
  267. accountNumber: {
  268. rules: [{
  269. required: true,
  270. errorMessage: '账户号码不能为空',
  271. }, ],
  272. },
  273. bankName: {
  274. rules: [{
  275. required: true,
  276. errorMessage: '开户银行不能为空',
  277. }, ],
  278. },
  279. }
  280. });
  281. const placeholderStyle = 'color:#BBBBBB;font-size:28rpx;line-height:normal';
  282. const statusName = computed(() => {
  283. const status = state.model.checkStatus;
  284. if (status === 0) {
  285. return '审核中';
  286. } else if (status === 1) {
  287. return '通过';
  288. } else if (status === 2) {
  289. return '拒绝';
  290. } else {
  291. return '';
  292. }
  293. });
  294. // 下载模板
  295. const downloadTemplate = () => {
  296. // console.log('下载模板')
  297. const fileUrl =
  298. 'https://zxgz.newfeifan.cn/static/file/%E9%9D%9E%E7%8B%AC%E5%AE%B6%E5%93%81%E7%89%8C%E6%8E%88%E6%9D%83%E4%B9%A6.docx'
  299. // 创建并触发下载链接
  300. const a = document.createElement('a');
  301. a.href = fileUrl;
  302. a.download = '非独家品牌授权书.docx'; // 下载文件的名称(可以修改为你希望的名称)
  303. document.body.appendChild(a);
  304. a.click();
  305. // 移除下载链接
  306. document.body.removeChild(a);
  307. }
  308. // 校验联络人是否已经申请入驻,如果已经入驻,那就不给提交
  309. const checkNumber = () => {
  310. const {
  311. data,
  312. code
  313. } = SaleApi.checkContactNumber({
  314. mobile: state.model.contactNumber
  315. });
  316. }
  317. // 提交审核
  318. const merchantFormRef = ref(null);
  319. const onSubmit = async () => {
  320. // 参数校验
  321. const validate = await unref(merchantFormRef)
  322. .validate()
  323. .catch((error) => {
  324. console.log('error: ', error);
  325. });
  326. if (!validate) {
  327. return;
  328. }
  329. if (!state.model.areaId) {
  330. state.areaIdError = '请选择所在地';
  331. return;
  332. }
  333. if (!state.model.identityCardFront) {
  334. state.identityCardFrontError = '请选择上传法人身份证正面(国徽面)';
  335. return;
  336. }
  337. if (!state.model.identityCardReverseSide) {
  338. state.identityCardReverseSideError = '请选择上传法人身份证背面(人像面)';
  339. return;
  340. }
  341. if (!state.model.businessLicensePicture) {
  342. state.businessLicensePictureError = '请上传营业执照';
  343. return;
  344. }
  345. if (!state.model.brandLicensing) {
  346. state.brandLicensingError = '请上传品牌授权书';
  347. return;
  348. }
  349. const {
  350. data,
  351. code
  352. } = await SaleApi.createMerchant(state.model);
  353. if (code === 0) {
  354. await getInfo()
  355. }
  356. }
  357. // 修改
  358. const onChange = () => {
  359. state.formStatus = false;
  360. state.changeIng = true;
  361. }
  362. // 取消修改
  363. const onCancel = () => {
  364. state.formStatus = true;
  365. state.changeIng = false;
  366. }
  367. const openList = () => {
  368. sheep.$router.go('/pages/public/merchantApplyList', {
  369. merchantApplyId: state.model.id
  370. })
  371. }
  372. // 保存并提交
  373. const onSave = async () => {
  374. // 参数校验
  375. const validate = await unref(merchantFormRef)
  376. .validate()
  377. .catch((error) => {
  378. console.log('error: ', error);
  379. });
  380. if (!validate) {
  381. return;
  382. }
  383. const {
  384. data,
  385. code
  386. } = await SaleApi.updateMerchant(state.model);
  387. if (code === 0) {
  388. state.formStatus = true;
  389. state.changeIng = false;
  390. await getInfo()
  391. }
  392. }
  393. // 地区树
  394. const areaTree = ref([])
  395. function format(data) {
  396. return data.map((item) => ({
  397. text: item.name, // 显示的文本
  398. value: item.id, // 值
  399. children: item.children.length ? format(item.children) : null // 子项
  400. }));
  401. }
  402. const getInfo = async () => {
  403. const {
  404. data,
  405. code
  406. } = await SaleApi.getMerchant();
  407. if (code === 0 && data) {
  408. // 如果能查到东西就证明当前用户已经申请了商户,只需要展示即可
  409. state.model = data;
  410. state.userApplyStatus = true;
  411. state.formStatus = true;
  412. } else {
  413. state.userApplyStatus = false;
  414. state.formStatus = false;
  415. }
  416. }
  417. const isLogin = computed(() => sheep.$store('user').isLogin);
  418. // 监听到在这个页面登陆,并刷新页面
  419. watch(
  420. () => isLogin.value,
  421. (newVal) => {
  422. if (newVal) {
  423. window.location.reload()
  424. }
  425. }, {
  426. deep: true, // 深度监听
  427. },
  428. );
  429. onLoad(async (options) => {
  430. if (!isLogin.value) {
  431. showAuthModal();
  432. }else{
  433. await SaleApi.checkSystemUser().then(res => {
  434. console.log(!res.data)
  435. state.canUse = !res.data;
  436. })
  437. await AreaApi.getAreaTree().then(res => {
  438. areaTree.value = format(res.data)
  439. })
  440. await getInfo();
  441. }
  442. });
  443. </script>
  444. <style lang="scss" scoped>
  445. .icon {
  446. display: flex;
  447. align-items: center;
  448. margin-right: 7rpx
  449. }
  450. .icon image {
  451. width: 35rpx;
  452. height: 35rpx;
  453. }
  454. :deep() {
  455. .file-picker__progress {
  456. height: 0 !important;
  457. }
  458. .uni-list-item__content-title {
  459. font-size: 28rpx !important;
  460. color: #333333 !important;
  461. line-height: normal !important;
  462. }
  463. .uni-icons {
  464. font-size: 40rpx !important;
  465. }
  466. .is-disabled {
  467. color: #333333;
  468. }
  469. }
  470. :deep(.disabled) {
  471. opacity: 1;
  472. }
  473. .gender-name {
  474. font-size: 28rpx;
  475. font-weight: 500;
  476. line-height: normal;
  477. color: #333333;
  478. }
  479. .title-box {
  480. font-size: 28rpx;
  481. font-weight: 500;
  482. color: #666666;
  483. line-height: 100rpx;
  484. }
  485. .btn {
  486. width: 710rpx;
  487. height: 80rpx;
  488. background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
  489. border-radius: 40rpx;
  490. font-size: 30rpx;
  491. font-weight: 500;
  492. color: $white;
  493. }
  494. .btn-two {
  495. width: 310rpx;
  496. height: 80rpx;
  497. background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
  498. border-radius: 40rpx;
  499. font-size: 30rpx;
  500. font-weight: 500;
  501. color: $white;
  502. }
  503. .radio-dark {
  504. filter: grayscale(100%);
  505. filter: gray;
  506. opacity: 0.4;
  507. }
  508. .content-img {
  509. border-radius: 50%;
  510. }
  511. .header-box-content {
  512. position: relative;
  513. width: 160rpx;
  514. height: 160rpx;
  515. overflow: hidden;
  516. border-radius: 50%;
  517. }
  518. .avatar-action {
  519. position: absolute;
  520. left: 50%;
  521. transform: translateX(-50%);
  522. bottom: 0;
  523. z-index: 1;
  524. width: 160rpx;
  525. height: 46rpx;
  526. background: rgba(#000000, 0.3);
  527. .avatar-action-btn {
  528. width: 160rpx;
  529. height: 46rpx;
  530. font-weight: 500;
  531. font-size: 24rpx;
  532. color: #ffffff;
  533. }
  534. }
  535. // 绑定项
  536. .account-list {
  537. background-color: $white;
  538. height: 100rpx;
  539. padding: 0 20rpx;
  540. .list-img {
  541. width: 40rpx;
  542. height: 40rpx;
  543. margin-right: 10rpx;
  544. }
  545. .list-name {
  546. font-size: 28rpx;
  547. color: #333333;
  548. }
  549. .info {
  550. .avatar {
  551. width: 38rpx;
  552. height: 38rpx;
  553. border-radius: 50%;
  554. overflow: hidden;
  555. }
  556. .name {
  557. font-size: 28rpx;
  558. font-weight: 400;
  559. color: $dark-9;
  560. }
  561. }
  562. .bind-box {
  563. width: 100rpx;
  564. height: 50rpx;
  565. line-height: normal;
  566. display: flex;
  567. justify-content: center;
  568. align-items: center;
  569. font-size: 24rpx;
  570. .bind-btn {
  571. width: 100%;
  572. height: 100%;
  573. border-radius: 25rpx;
  574. background: #f4f4f4;
  575. color: #999999;
  576. }
  577. .relieve-btn {
  578. width: 100%;
  579. height: 100%;
  580. border-radius: 25rpx;
  581. background: var(--ui-BG-Main-opacity-1);
  582. color: var(--ui-BG-Main);
  583. }
  584. }
  585. }
  586. .list-border {
  587. font-size: 28rpx;
  588. font-weight: 400;
  589. color: #333333;
  590. border-bottom: 2rpx solid #eeeeee;
  591. }
  592. image {
  593. width: 100%;
  594. height: 100%;
  595. }
  596. </style>