login.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. <template>
  2. <view class="head-image">
  3. <image src="/static/image/logo1.png" mode="heightFix" />
  4. </view>
  5. <view class="input-box">
  6. <view class="content">
  7. <picker class="picker" mode="selector" :range="countryCodes" range-key="name" :value="countryCode"
  8. @change="changeCountryCode">
  9. {{ countryCode }}
  10. </picker>
  11. <input type="number" :value="phonenumber" :focus="focused == 'phonenumber'"
  12. @input="onInput($event, 'phonenumber')" placeholder="请输入手机号" class="input" />
  13. </view>
  14. </view>
  15. <view class="input-box" style="margin-top:70rpx;">
  16. <view class="content">
  17. <input type="number" :value="password" :focus="focused == 'password'" @input="onInput($event, 'password')"
  18. placeholder="请输入验证码" class="input" />
  19. <view class="auth-code" @click="getAuthCode">
  20. {{ downTime == 0 ? '获取验证码' : downTime + "S" }}
  21. </view>
  22. </view>
  23. </view>
  24. <My-button :customStyle="customStyle" class="my-but" :loading="loading" :disabled="disabled" text="登录"
  25. :onClick="logIn" />
  26. <view class="agreement-box">
  27. <up-checkbox label="已阅读并同意" name="agree" usedAlone v-model:checked="isAgreement" />
  28. <view @click="checkTheAgreement" style="color: #3874F6;">
  29. 《隐私协议》
  30. </view>
  31. </view>
  32. <up-modal asyncClose :show="showModal" confirmColor="#052E5D" showCancelButton confirmText="阅读并获取"
  33. @confirm="onConfirm1" @cancel="showModal = false">
  34. <view class="modal-u">请阅读并同意<text style="color: #3874F6;" @click="checkTheAgreement">《隐私协议》</text></view>
  35. </up-modal>
  36. <!-- 正式无需使用 -->
  37. <up-picker title="选择站点" :show="account_list.length != 0" :columns="account_list" keyName="sitename"
  38. @cancel="onCancel" @confirm='onConfirm' />
  39. </template>
  40. <script setup>
  41. import { ref, reactive, getCurrentInstance, computed } from 'vue'
  42. import { onLoad } from '@dcloudio/uni-app';
  43. const { $Http } = getCurrentInstance().proxy;
  44. onLoad(() => {
  45. const storedPhone = uni.getStorageSync('phonenumber');
  46. if (storedPhone) {
  47. phonenumber.value = storedPhone;
  48. isAgreement.value = true;
  49. }
  50. if (wx.getStorageSync('userMsg').token) {
  51. $Http.basic({
  52. "classname": "common.adspace.adspace",
  53. "method": "query_adspacelist", //查询轮播图
  54. content: {
  55. nocache: true
  56. }
  57. }).then(res => {
  58. if (res.code !== 0) {
  59. uni.removeStorageSync('banner')
  60. uni.setStorageSync('banner', res.data);
  61. uni.redirectTo({
  62. url: '/pages/index/index',
  63. });
  64. }
  65. })
  66. }
  67. });
  68. // 登陆按钮相关
  69. const loading = ref(false);
  70. const disabled = computed(() => {
  71. return !(phonenumber.value.length > 0 && password.value.length >= 4);
  72. });
  73. const customStyle = ref({
  74. width: '380rpx',
  75. margin: '120rpx auto 0',
  76. });
  77. // 表单相关
  78. const focused = ref('');
  79. const countryCode = ref('+86');
  80. const phonenumber = ref('');
  81. const password = ref('');
  82. const countryCodes = reactive([
  83. { code: '+86', name: '中国 +86', regex: /^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$/ }, // 中国手机号验证规则
  84. { code: '+1', name: '美国 +1', regex: /^[2-9]\d{2}[2-9](?!11)\d{6}$/ }, // 美国手机号验证规则
  85. { code: '+44', name: '英国 +44', regex: /^7\d{9}$/ }, // 英国手机号验证规则
  86. ]);
  87. function onInput(e, name) {
  88. if (name == 'phonenumber') {
  89. phonenumber.value = e.detail.value;
  90. } else if (name == 'password') {
  91. password.value = e.detail.value;
  92. }
  93. }
  94. function validatephonenumber() {
  95. const selectedCountry = countryCodes.find(country => country.code === countryCode.value);
  96. if (!selectedCountry || !selectedCountry.regex.test(phonenumber.value)) {
  97. uni.showToast({
  98. title: `请输入有效的${selectedCountry ? selectedCountry.name.split(" ")[0] + '号码' : '手机号'}`,
  99. icon: 'none',
  100. });
  101. focused.value = 'phonenumber'; // 聚焦输入框
  102. return false;
  103. }
  104. return true;
  105. }
  106. function changeCountryCode(e) {
  107. countryCode.value = countryCodes[e.detail.value].code;
  108. if (phonenumber.value) validatephonenumber();
  109. }
  110. // 验证码相关
  111. let countDown = null;
  112. const downTime = ref(0); // 倒计时初始值
  113. function getAuthCode() {
  114. console
  115. if (downTime.value > 0) return;
  116. if (!validatephonenumber()) return;
  117. $Http.getpassword({ "phonenumber": phonenumber.value, "systemclient": "wechatsaletool" }).then(res => {
  118. console.log('获取验证码结果:', res);
  119. if (res.code == 1) {
  120. downTime.value = 60;
  121. countDown = setInterval(() => {
  122. downTime.value--;
  123. if (downTime.value <= 0) {
  124. clearInterval(countDown);
  125. downTime.value = 0;
  126. }
  127. }, 1000);
  128. const code = res.msg.split('手机验证码为:');
  129. if (code[1]) {
  130. password.value = code[1].trim(); // 自动填充验证码
  131. } else {
  132. focused.value = 'password'; // 聚焦输入框
  133. }
  134. }
  135. uni.showToast({
  136. title: res.msg,
  137. icon: 'none',
  138. });
  139. })
  140. }
  141. // 登录相关
  142. let account_list = reactive([]);
  143. function logIn() {
  144. if (!validatephonenumber()) return;
  145. if (isAgreement.value == false) return showModal.value = true;
  146. loading.value = true;
  147. $Http.plogin({ "phonenumber": phonenumber.value, "password": hexMD5(password.value), "systemclient": "wechatsaletool" }).then(res => {
  148. if (res.code == 1) {
  149. if (res.account_list.length == 1) {
  150. handleLogin(res.account_list[0]);
  151. } else {
  152. account_list = reactive([res.account_list]);
  153. }
  154. } else {
  155. loading.value = false;
  156. uni.showToast({
  157. title: res.msg,
  158. icon: 'none',
  159. });
  160. }
  161. })
  162. }
  163. function onCancel() {
  164. account_list = reactive([]);
  165. }
  166. function onConfirm(e) {
  167. handleLogin(e.value[0]);
  168. account_list = reactive([]);
  169. }
  170. function handleLogin(data) {
  171. $Http.base({
  172. "id": 2025072809441203,
  173. "content": {
  174. "customerphone": phonenumber.value,
  175. siteid: data.siteid
  176. }
  177. }).then(res => {
  178. console.log("登录结果:", res);
  179. loading.value = false;
  180. if (res.code == 1) {
  181. uni.removeStorageSync('userMsg');
  182. uni.setStorageSync('userMsg', data);
  183. uni.removeStorageSync('phonenumber');
  184. uni.setStorageSync('phonenumber', phonenumber.value);
  185. uni.redirectTo({
  186. url: '/pages/index/index',
  187. });
  188. } else {
  189. uni.showToast({
  190. title: res.msg,
  191. icon: 'none',
  192. });
  193. }
  194. })
  195. }
  196. //隐私协议相关
  197. const isAgreement = ref(false);
  198. const showModal = ref(false);
  199. function checkTheAgreement() {
  200. console.log(122222222222222222)
  201. uni.showLoading({
  202. title: "加载中...",
  203. });
  204. uni.downloadFile({
  205. url: "https://yossys22170.obs.cn-east-2.myhuaweicloud.com:443/202309261695715892017B6ef5bd76.docx",
  206. success: (res) => {
  207. uni.openDocument({
  208. filePath: res.tempFilePath,
  209. fileType: "docx",
  210. success: (s) => {
  211. uni.hideLoading();
  212. },
  213. fail: (err) => {
  214. console.log("openDocument", err);
  215. uni.hideLoading();
  216. uni.showToast({
  217. title: "读取失败,请稍后再试",
  218. icon: "none",
  219. });
  220. },
  221. });
  222. },
  223. fail: (err) => {
  224. console.log("downloadFile", err);
  225. uni.hideLoading();
  226. uni.showToast({
  227. title: "读取失败,请稍后再试",
  228. icon: "none",
  229. });
  230. },
  231. });
  232. }
  233. function onConfirm1() {
  234. showModal.value = false;
  235. isAgreement.value = true;
  236. logIn();
  237. }
  238. /* 以下为MD5加密 */
  239. function hexMD5(str) {
  240. return binl2hex(coreMD5(str2binl(str)))
  241. }
  242. function safe_add(x, y) {
  243. var lsw = (x & 0xFFFF) + (y & 0xFFFF)
  244. var msw = (x >> 16) + (y >> 16) + (lsw >> 16)
  245. return (msw << 16) | (lsw & 0xFFFF)
  246. }
  247. function rol(num, cnt) {
  248. return (num << cnt) | (num >>> (32 - cnt))
  249. }
  250. function cmn(q, a, b, x, s, t) {
  251. return safe_add(rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b)
  252. }
  253. function ff(a, b, c, d, x, s, t) {
  254. return cmn((b & c) | ((~b) & d), a, b, x, s, t)
  255. }
  256. function gg(a, b, c, d, x, s, t) {
  257. return cmn((b & d) | (c & (~d)), a, b, x, s, t)
  258. }
  259. function hh(a, b, c, d, x, s, t) {
  260. return cmn(b ^ c ^ d, a, b, x, s, t)
  261. }
  262. function ii(a, b, c, d, x, s, t) {
  263. return cmn(c ^ (b | (~d)), a, b, x, s, t)
  264. }
  265. function coreMD5(x) {
  266. var a = 1732584193
  267. var b = -271733879
  268. var c = -1732584194
  269. var d = 271733878
  270. for (var i = 0; i < x.length; i += 16) {
  271. var olda = a
  272. var oldb = b
  273. var oldc = c
  274. var oldd = d
  275. a = ff(a, b, c, d, x[i + 0], 7, -680876936)
  276. d = ff(d, a, b, c, x[i + 1], 12, -389564586)
  277. c = ff(c, d, a, b, x[i + 2], 17, 606105819)
  278. b = ff(b, c, d, a, x[i + 3], 22, -1044525330)
  279. a = ff(a, b, c, d, x[i + 4], 7, -176418897)
  280. d = ff(d, a, b, c, x[i + 5], 12, 1200080426)
  281. c = ff(c, d, a, b, x[i + 6], 17, -1473231341)
  282. b = ff(b, c, d, a, x[i + 7], 22, -45705983)
  283. a = ff(a, b, c, d, x[i + 8], 7, 1770035416)
  284. d = ff(d, a, b, c, x[i + 9], 12, -1958414417)
  285. c = ff(c, d, a, b, x[i + 10], 17, -42063)
  286. b = ff(b, c, d, a, x[i + 11], 22, -1990404162)
  287. a = ff(a, b, c, d, x[i + 12], 7, 1804603682)
  288. d = ff(d, a, b, c, x[i + 13], 12, -40341101)
  289. c = ff(c, d, a, b, x[i + 14], 17, -1502002290)
  290. b = ff(b, c, d, a, x[i + 15], 22, 1236535329)
  291. a = gg(a, b, c, d, x[i + 1], 5, -165796510)
  292. d = gg(d, a, b, c, x[i + 6], 9, -1069501632)
  293. c = gg(c, d, a, b, x[i + 11], 14, 643717713)
  294. b = gg(b, c, d, a, x[i + 0], 20, -373897302)
  295. a = gg(a, b, c, d, x[i + 5], 5, -701558691)
  296. d = gg(d, a, b, c, x[i + 10], 9, 38016083)
  297. c = gg(c, d, a, b, x[i + 15], 14, -660478335)
  298. b = gg(b, c, d, a, x[i + 4], 20, -405537848)
  299. a = gg(a, b, c, d, x[i + 9], 5, 568446438)
  300. d = gg(d, a, b, c, x[i + 14], 9, -1019803690)
  301. c = gg(c, d, a, b, x[i + 3], 14, -187363961)
  302. b = gg(b, c, d, a, x[i + 8], 20, 1163531501)
  303. a = gg(a, b, c, d, x[i + 13], 5, -1444681467)
  304. d = gg(d, a, b, c, x[i + 2], 9, -51403784)
  305. c = gg(c, d, a, b, x[i + 7], 14, 1735328473)
  306. b = gg(b, c, d, a, x[i + 12], 20, -1926607734)
  307. a = hh(a, b, c, d, x[i + 5], 4, -378558)
  308. d = hh(d, a, b, c, x[i + 8], 11, -2022574463)
  309. c = hh(c, d, a, b, x[i + 11], 16, 1839030562)
  310. b = hh(b, c, d, a, x[i + 14], 23, -35309556)
  311. a = hh(a, b, c, d, x[i + 1], 4, -1530992060)
  312. d = hh(d, a, b, c, x[i + 4], 11, 1272893353)
  313. c = hh(c, d, a, b, x[i + 7], 16, -155497632)
  314. b = hh(b, c, d, a, x[i + 10], 23, -1094730640)
  315. a = hh(a, b, c, d, x[i + 13], 4, 681279174)
  316. d = hh(d, a, b, c, x[i + 0], 11, -358537222)
  317. c = hh(c, d, a, b, x[i + 3], 16, -722521979)
  318. b = hh(b, c, d, a, x[i + 6], 23, 76029189)
  319. a = hh(a, b, c, d, x[i + 9], 4, -640364487)
  320. d = hh(d, a, b, c, x[i + 12], 11, -421815835)
  321. c = hh(c, d, a, b, x[i + 15], 16, 530742520)
  322. b = hh(b, c, d, a, x[i + 2], 23, -995338651)
  323. a = ii(a, b, c, d, x[i + 0], 6, -198630844)
  324. d = ii(d, a, b, c, x[i + 7], 10, 1126891415)
  325. c = ii(c, d, a, b, x[i + 14], 15, -1416354905)
  326. b = ii(b, c, d, a, x[i + 5], 21, -57434055)
  327. a = ii(a, b, c, d, x[i + 12], 6, 1700485571)
  328. d = ii(d, a, b, c, x[i + 3], 10, -1894986606)
  329. c = ii(c, d, a, b, x[i + 10], 15, -1051523)
  330. b = ii(b, c, d, a, x[i + 1], 21, -2054922799)
  331. a = ii(a, b, c, d, x[i + 8], 6, 1873313359)
  332. d = ii(d, a, b, c, x[i + 15], 10, -30611744)
  333. c = ii(c, d, a, b, x[i + 6], 15, -1560198380)
  334. b = ii(b, c, d, a, x[i + 13], 21, 1309151649)
  335. a = ii(a, b, c, d, x[i + 4], 6, -145523070)
  336. d = ii(d, a, b, c, x[i + 11], 10, -1120210379)
  337. c = ii(c, d, a, b, x[i + 2], 15, 718787259)
  338. b = ii(b, c, d, a, x[i + 9], 21, -343485551)
  339. a = safe_add(a, olda)
  340. b = safe_add(b, oldb)
  341. c = safe_add(c, oldc)
  342. d = safe_add(d, oldd)
  343. }
  344. return [a, b, c, d]
  345. }
  346. function binl2hex(binarray) {
  347. var hex_tab = "0123456789abcdef"
  348. var str = ""
  349. for (var i = 0; i < binarray.length * 4; i++) {
  350. str += hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xF) +
  351. hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xF)
  352. }
  353. return str
  354. }
  355. function str2binl(str) {
  356. var nblk = ((str.length + 8) >> 6) + 1 // number of 16-word blocks
  357. var blks = new Array(nblk * 16)
  358. for (var i = 0; i < nblk * 16; i++) blks[i] = 0
  359. for (var i = 0; i < str.length; i++)
  360. blks[i >> 2] |= (str.charCodeAt(i) & 0xFF) << ((i % 4) * 8)
  361. blks[i >> 2] |= 0x80 << ((i % 4) * 8)
  362. blks[nblk * 16 - 2] = str.length * 8
  363. return blks
  364. }
  365. </script>
  366. <style lang="scss" scoped>
  367. .head-image {
  368. display: flex;
  369. justify-content: center;
  370. height: 148rpx;
  371. margin-top: 120rpx;
  372. margin-bottom: 120rpx;
  373. image {
  374. height: 100%;
  375. }
  376. }
  377. .input-box {
  378. width: 630rpx;
  379. padding-bottom: 20rpx;
  380. margin: 0 auto;
  381. border-bottom: 1px solid #dcdcdc;
  382. box-sizing: border-box;
  383. .content {
  384. display: flex;
  385. justify-content: space-between;
  386. align-items: center;
  387. height: 48rpx;
  388. width: 100%;
  389. .picker {
  390. font-family: Microsoft YaHei, Microsoft YaHei;
  391. font-weight: bold;
  392. font-size: 32rpx;
  393. color: #333333;
  394. margin-right: 20rpx;
  395. }
  396. .input {
  397. flex: 1;
  398. }
  399. .auth-code {
  400. margin-left: 20rpx;
  401. font-family: Microsoft YaHei, Microsoft YaHei;
  402. font-weight: bold;
  403. font-size: 28rpx;
  404. color: #3874F6;
  405. }
  406. }
  407. }
  408. .my-but {
  409. width: 380rpx;
  410. }
  411. .agreement-box {
  412. position: fixed;
  413. bottom: 80rpx;
  414. width: 100%;
  415. display: flex;
  416. justify-content: center;
  417. align-items: center;
  418. up-checkbox {
  419. font-family: Microsoft YaHei, Microsoft YaHei;
  420. font-weight: bold;
  421. font-size: 28rpx;
  422. color: #333333;
  423. }
  424. }
  425. </style>