JPattributeEditor.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. <template>
  2. <div class="JPattributeEditor">
  3. <van-nav-bar class="navBar" title="金牌店档案编辑" left-arrow @click-left="onClickLeft" />
  4. <div class="content" v-if="detail">
  5. <van-form ref="tabstoreVal">
  6. <van-field
  7. class="sendCode"
  8. v-model="detail.ownerMobile"
  9. label="主经营者电话"
  10. placeholder="请输入主经营者电话"
  11. @blur="sendCodeTelFn(detail.ownerMobile)"
  12. type="tel">
  13. <template #button v-if="!verifyMobile">
  14. <van-button
  15. size="small"
  16. style="color: white; background: rgb(0, 87, 186); border-radius: 6px"
  17. @click="sendCode(detail.ownerMobile)"
  18. :disabled="time != null">
  19. <span v-if="time">已发送({{ timeNum }})</span>
  20. <span v-else>发送验证码</span>
  21. </van-button>
  22. </template>
  23. </van-field>
  24. <van-field
  25. v-model="verificationVal"
  26. label="主经营者收到的验证码"
  27. placeholder="请输入验证码"
  28. type="number"
  29. @blur="verification(verificationVal)"
  30. v-if="!verifyMobile" />
  31. <van-field v-model="detail.ownerName" :error-message="ownerNameMsg" label="主经营者姓名" />
  32. <van-field
  33. v-model="detail.ownerBirthday"
  34. label="主经营者出生日期"
  35. placeholder="请输入主经营者出生日期"
  36. @click="getNyr('ownerBirthday', detail.ownerBirthday)" />
  37. <van-field autosize type="textarea" label="主营/擅长经营品类">
  38. <template #input>
  39. <van-checkbox-group v-model="detail.mainProductCategorys" direction="horizontal">
  40. <van-checkbox
  41. v-for="(item, index) in mainProductCategorys"
  42. :name="item.dictValue"
  43. shape="square"
  44. :key="index">
  45. {{ item.dictValue }}
  46. </van-checkbox>
  47. </van-checkbox-group>
  48. </template>
  49. </van-field>
  50. <van-field
  51. v-model="detail.totalSalesAmount"
  52. type="number"
  53. :error-message="totalSalesAmountMsg"
  54. label="门店24年总进货额(含所有品牌品类)" />
  55. <van-field v-model="detail.performanceRatio" type="number" :error-message="performanceRatioMsg" label="门店立邦业绩占比(%)" />
  56. <van-field v-model="detail.mainBrand" autosize type="textarea" :error-message="mainBrandMsg" label="门店主营TOP3品牌" />
  57. <van-field label="是否有工地资源(支持工地配送,承接工地双包等)">
  58. <template #input>
  59. <van-radio-group
  60. v-model="detail.constructionResource"
  61. direction="horizontal"
  62. @change="changeResource">
  63. <van-radio name="是">是</van-radio>
  64. <van-radio name="否">否</van-radio>
  65. </van-radio-group>
  66. </template>
  67. </van-field>
  68. <van-field
  69. v-if="detail.constructionResource == '是'"
  70. v-model="detail.constructionYearNum"
  71. type="number"
  72. label="年工地数量" />
  73. <van-field label="是否有双包能力">
  74. <template #input>
  75. <van-radio-group v-model="detail.doubleContracting" direction="horizontal">
  76. <van-radio name="是">是</van-radio>
  77. <van-radio name="否">否</van-radio>
  78. </van-radio-group>
  79. </template>
  80. </van-field>
  81. <van-field label="紧急联系人身份">
  82. <template #input>
  83. <van-radio-group v-model="detail.emergencyContactRelation" direction="horizontal">
  84. <van-radio
  85. v-for="(item, index) in emergencyContactRelation"
  86. :name="item.dictValue"
  87. :key="index">
  88. {{ item.dictValue }}
  89. </van-radio>
  90. </van-radio-group>
  91. </template>
  92. </van-field>
  93. <van-field v-model="detail.emergencyContact" label="紧急联系人姓名" />
  94. <van-field
  95. v-model="detail.emergencyContactBirthday"
  96. label="紧急联系人出生日期"
  97. @click="getNyr('emergencyContactBirthday', detail.emergencyContactBirthday)" />
  98. <van-field
  99. v-model="detail.emergencyContactMobile"
  100. type="number"
  101. @blur="emergencyContactBlur(detail.emergencyContactMobile)"
  102. label="紧急联系人电话" />
  103. </van-form>
  104. </div>
  105. <div class="footer-btn">
  106. <van-button
  107. style="color: white; background: rgb(0, 87, 186); border-radius: 6px; width: 90%"
  108. @click="confirmShare">
  109. 保 存
  110. </van-button>
  111. </div>
  112. <!-- 时间选择 -->
  113. <van-popup v-model="datetimeShowPicker" position="bottom">
  114. <van-datetime-picker
  115. v-model="currentDate"
  116. type="date"
  117. title="选择年月日"
  118. :min-date="minDate"
  119. :max-date="maxDate"
  120. @confirm="datetimeOnConfirm"
  121. @cancel="datetimeShowPicker = false" />
  122. </van-popup>
  123. </div>
  124. </template>
  125. <script>
  126. import { sendAndCheckVerCode, getDictOption } from '@/api/index';
  127. import { getStoreArchives, updateArchives } from '@/api/storeManagement';
  128. export default {
  129. name: 'JPattributeEditor',
  130. data() {
  131. return {
  132. ownerNameMsg: '',
  133. totalSalesAmountMsg: '',
  134. performanceRatioMsg: '',
  135. mainBrandMsg: '',
  136. detail: null,
  137. time: null, //计时
  138. timeNum: 60,
  139. verificationVal: '',
  140. datetimeShowPicker: false,
  141. activatNyrItem: '',
  142. checkboxGroup: [],
  143. mainProductCategorys: [],
  144. emergencyContactRelation: [],
  145. verificationPassedPhoneNum: '', //验证通过手机号
  146. minDate: new Date(1945, 0, 1),
  147. maxDate: new Date(),
  148. currentDate: new Date(1945, 0, 1),
  149. mobileStatus: '0',
  150. verifyMobile: false, //手机号是否验证透通过
  151. };
  152. },
  153. activated() {
  154. this.detail = null;
  155. this.verificationVal = '';
  156. if (this.time) clearInterval(this.time);
  157. this.time = null; //计时
  158. this.timeNum = 60;
  159. this.toastLoading(0, '加载中...', true);
  160. getDictOption({}, 'archives_main_product_categorys').then((res) => {
  161. let mainProductCategorys = [];
  162. let emergencyContactRelation = [];
  163. res.data.forEach((val) => {
  164. if (val.remark == 'mainProductCategorys') {
  165. mainProductCategorys.push(val);
  166. } else {
  167. emergencyContactRelation.push(val);
  168. }
  169. });
  170. this.mainProductCategorys = mainProductCategorys;
  171. this.emergencyContactRelation = emergencyContactRelation;
  172. this.getDetaild();
  173. });
  174. },
  175. methods: {
  176. getDetaild() {
  177. getStoreArchives({ storeCode: this.$route.query.storeCode }).then((res) => {
  178. this.toastLoading().clear();
  179. if (res.code == 200) {
  180. // let copyData = JSON.parse(JSON.stringify(res.data));
  181. res.data.mainProductCategorys = res.data.mainProductCategorys
  182. ? res.data.mainProductCategorys.split(',')
  183. : [];
  184. this.detail = res.data;
  185. this.mobileStatus = res.data.mobileStatus;
  186. // mobileStatus 1是 是否验证通过
  187. if (res.data.mobileStatus == '1') {
  188. this.verificationPassedPhoneNum = this.detail.ownerMobile;
  189. }
  190. // 验证码和发送按钮是否显示
  191. this.verifyMobile = this.mobileStatus == '0' ? false : true;
  192. }
  193. });
  194. },
  195. sendCodeTelFn(tel) {
  196. if (!/^1[123456789]\d{9}$/.test(tel) || tel == '') {
  197. this.$toast('格式错误');
  198. return;
  199. }
  200. if (tel != this.verificationPassedPhoneNum) {
  201. this.verifyMobile = false;
  202. }
  203. },
  204. // 发送验证码
  205. sendCode(val) {
  206. if (!/^1[123456789]\d{9}$/.test(val) || val == '') {
  207. this.$toast('格式错误');
  208. return;
  209. }
  210. if (this.time) return;
  211. clearInterval(this.time);
  212. this.timeNum = 60;
  213. this.sendCodeFun(
  214. {
  215. type: '1', //String 调用类型:1:发送验证码 2:校验验证码
  216. phone: val, //String 手机号
  217. verification: '', //String 手机号验证码
  218. },
  219. () => {
  220. this.time = setInterval(() => {
  221. this.timeNum--;
  222. if (this.timeNum <= 0) {
  223. clearInterval(this.time);
  224. this.time = null;
  225. }
  226. }, 1000);
  227. this.$toast('发送成功');
  228. }
  229. );
  230. },
  231. sendCodeFun(params, callback) {
  232. sendAndCheckVerCode(params).then((res) => {
  233. if (res.code == 200) {
  234. callback && callback(res);
  235. }
  236. });
  237. },
  238. verification(val) {
  239. // 验证码
  240. if (val == '') {
  241. return;
  242. }
  243. // 手机号
  244. if (this.detail.ownerMobile == '') {
  245. return;
  246. }
  247. this.sendCodeFun(
  248. {
  249. type: '2', //String 调用类型:1:发送验证码 2:校验验证码
  250. phone: this.detail.ownerMobile, //String 手机号
  251. verification: val, //String 手机号验证码
  252. },
  253. (res) => {
  254. if (res.data) this.verificationPassedPhoneNum = this.detail.ownerMobile;
  255. this.$toast(res.data ? '验证成功' : '验证码错误');
  256. }
  257. );
  258. },
  259. getNyr(val, date) {
  260. this.activatNyrItem = val;
  261. if (date && date != '') {
  262. let time = date.split('-');
  263. this.currentDate = new Date(time[0], Number(time[1]) - 1, time[2]);
  264. } else {
  265. this.currentDate = new Date(1945, 0, 1);
  266. }
  267. this.datetimeShowPicker = true;
  268. },
  269. datetimeOnConfirm(time) {
  270. this.$set(this.detail, this.activatNyrItem, this.parseTime(time, '{y}-{m}-{d}'));
  271. // this.detail.ownerBirthday = this.parseTime(time, '{y}-{m}-{d}');
  272. this.datetimeShowPicker = false;
  273. },
  274. isValidOwnerName(){
  275. this.ownerNameMsg = '';
  276. let ownerName = this.detail.ownerName;
  277. if(ownerName.length < 2){
  278. this.ownerNameMsg = '最短字数2';
  279. return true;
  280. }
  281. if(ownerName.length > 20){
  282. this.ownerNameMsg = '最长字数20';
  283. return true;
  284. }
  285. const chineseChars = ownerName.match(/[\u4e00-\u9fa5]/g) || [];
  286. if (chineseChars.length < 1) {
  287. this.ownerNameMsg = '至少一个汉字';
  288. return true;
  289. }
  290. if (/[^a-zA-Z0-9\u4e00-\u9fa5]/.test(ownerName)) {
  291. this.ownerNameMsg = '不可输入特殊符号';
  292. return true;
  293. }
  294. return false;
  295. },
  296. isValidTotalSalesAmount(){
  297. this.totalSalesAmountMsg = '';
  298. let totalSalesAmount = this.detail.totalSalesAmount;
  299. const value = parseFloat(totalSalesAmount);
  300. if (isNaN(value)) {
  301. this.totalSalesAmountMsg = '请输入数字';
  302. return true;
  303. }
  304. if (value < 1) {
  305. this.totalSalesAmountMsg = '最小值1';
  306. return true;
  307. }
  308. if (value > 1000) {
  309. this.totalSalesAmountMsg = '最大值1000';
  310. return true;
  311. }
  312. return false;
  313. },
  314. isPerformanceRatio(){
  315. this.performanceRatioMsg = '';
  316. let performanceRatio = this.detail.performanceRatio;
  317. const value = parseFloat(performanceRatio);
  318. if (isNaN(value)) {
  319. this.performanceRatioMsg = '请输入数字';
  320. return true;
  321. }
  322. if (value < 1) {
  323. this.performanceRatioMsg = '最小值1';
  324. return true;
  325. }
  326. if (value > 100) {
  327. this.performanceRatioMsg = '最大值100';
  328. return true;
  329. }
  330. return false;
  331. },
  332. isValidMainBrand(){
  333. this.mainBrandMsg = '';
  334. let mainBrand = this.detail.mainBrand;
  335. const chineseChars = mainBrand.match(/[\u4e00-\u9fa5]/g) || [];
  336. if (chineseChars.length < 1) {
  337. this.mainBrandMsg = '至少一个汉字';
  338. return true;
  339. }
  340. return false;
  341. },
  342. // 保存
  343. confirmShare() {
  344. if (
  345. this.verificationPassedPhoneNum == '' ||
  346. this.detail.ownerMobile != this.verificationPassedPhoneNum
  347. ) {
  348. this.$toast('请验证手机号');
  349. return;
  350. }
  351. if(this.isValidOwnerName()) return;
  352. if(this.isValidTotalSalesAmount()) return;
  353. if(this.isPerformanceRatio()) return;
  354. if(this.isValidMainBrand()) return;
  355. if (this.detail.emergencyContactMobile != '') {
  356. if (!/^1[123456789]\d{9}$/.test(this.detail.emergencyContactMobile)) {
  357. this.$toast('紧急联系人电话格式错误');
  358. return;
  359. }
  360. }
  361. this.toastLoading(0, '加载中...', true);
  362. let params = JSON.parse(JSON.stringify(this.detail));
  363. params.mainProductCategorys = params.mainProductCategorys.join(',');
  364. params.storeCode = this.$route.query.storeCode;
  365. updateArchives(params).then((res) => {
  366. this.toastLoading().clear();
  367. if (res.code == 200) {
  368. this.$toast(res.msg);
  369. this.$router.go(-1);
  370. } else {
  371. this.$toast(res.msg);
  372. }
  373. });
  374. },
  375. emergencyContactBlur(val) {
  376. if (!/^1[123456789]\d{9}$/.test(val)) {
  377. this.$toast('紧急联系人电话格式错误');
  378. }
  379. },
  380. changeResource(val) {
  381. if (val == '否') {
  382. this.detail.constructionYearNum = '';
  383. }
  384. },
  385. onClickLeft() {
  386. this.$router.go(-1);
  387. },
  388. },
  389. };
  390. </script>
  391. <style lang="scss">
  392. .JPattributeEditor {
  393. width: 100%;
  394. height: 100%;
  395. display: flex;
  396. flex-direction: column;
  397. justify-content: space-between;
  398. overflow: hidden;
  399. .content {
  400. flex: 1;
  401. overflow-y: auto;
  402. background: #fff;
  403. padding: 10px 15px;
  404. margin-top: 10px;
  405. background: #fff;
  406. .van-cell {
  407. padding: 10px 0;
  408. border-bottom: 1px solid #ccc;
  409. }
  410. .van-field__label {
  411. width: 9em;
  412. }
  413. .sendCode {
  414. border: none !important;
  415. input {
  416. border: 1px solid #f1f1f1;
  417. height: 35px;
  418. }
  419. }
  420. .van-checkbox--horizontal {
  421. margin-bottom: 10px;
  422. width: 100%;
  423. }
  424. .van-radio--horizontal {
  425. margin-bottom: 10px;
  426. }
  427. }
  428. .footer-btn {
  429. display: flex;
  430. justify-content: space-around;
  431. padding: 10px 0;
  432. }
  433. }
  434. </style>