index.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. <script setup>
  2. import { ref, onMounted, computed } from 'vue'
  3. import QrCode from '@/components/QrCode.vue'
  4. import { post } from '@/utils/request'
  5. import { userToken } from '@/composables/config'
  6. import { userApi } from '@/api/user'
  7. import { ucardApi } from '@/api/ucard'
  8. import { customApi } from '@/service/custom'
  9. import useGlobalStore from '@/stores/use-global-store'
  10. import useUserStore from '@/stores/use-user-store'
  11. import useRouter from '@/hooks/useRouter'
  12. import { useI18n } from 'vue-i18n'
  13. import companyLogo from '@/static/images/logo4.png'
  14. const router = useRouter()
  15. const { t } = useI18n()
  16. const userStore = useUserStore()
  17. const globalStore = useGlobalStore()
  18. const modeStore = computed(() => globalStore.mode)
  19. // 响应式表单数据
  20. const form = ref({
  21. loginName: '',
  22. password: '',
  23. })
  24. function submit() {
  25. if (!form.value.loginName) {
  26. uni.$u.toast(t('signin.form.email'))
  27. return
  28. }
  29. if (!form.value.password) {
  30. uni.$u.toast(t('signin.form.password'))
  31. return
  32. }
  33. handleLogin()
  34. }
  35. const customStyle = {
  36. height: '44px',
  37. 'border-radius': '8px',
  38. background: '#f7f8fa',
  39. padding: '0 20px !important',
  40. position: 'relative',
  41. }
  42. const remenber = ref([])
  43. const checkboxChange = (e) => {
  44. remenber.value = e
  45. }
  46. const fetchUserList = (params) => post('/Login/AcctLogin', params)
  47. async function handleLogin() {
  48. try {
  49. const res = await userApi.login({
  50. loginName: form.value.loginName,
  51. password: form.value.password,
  52. })
  53. if (res.code === 200) {
  54. userToken.value = res.data
  55. uni.$u.toast(t('login.msg0_1'))
  56. getCustomLoginInfo()
  57. // getCardUserInfo();
  58. reasonsRefusalList()
  59. if (remenber.value.length) {
  60. userStore.saveAccountInfo({
  61. loginName: form.value.loginName,
  62. password: form.value.password,
  63. rememberPassword: true,
  64. })
  65. } else {
  66. userStore.saveAccountInfo({
  67. loginName: '',
  68. password: '',
  69. rememberPassword: false,
  70. })
  71. }
  72. // console.log(1111);
  73. } else {
  74. uni.showToast({ title: res.msg })
  75. // console.log(12112);
  76. }
  77. } catch (error) {
  78. // console.log(error, 19089);
  79. }
  80. }
  81. async function getCustomLoginInfo() {
  82. try {
  83. const res = await userApi.getUserInfo()
  84. userStore.saveUserInfo(res.data)
  85. if (res.code === 200) {
  86. router.reLaunch(modeStore.value === 'customer' ? '/pages/customer/index' : '/pages/ib/index')
  87. } else {
  88. uni.$u.toast(res.msg || t('login.msg0'))
  89. }
  90. } catch (error) {
  91. // console.log(error, 111);
  92. }
  93. }
  94. async function getCardUserInfo() {
  95. try {
  96. const res = await ucardApi.getSingle()
  97. userStore.saveUserInfo(res.data)
  98. if (res.code === 200) {
  99. if (!res.data || res.data.approveStatus != 2) {
  100. router.push('/pages/mine/improve')
  101. } else {
  102. router.push('/pages/card/index')
  103. }
  104. } else {
  105. uni.$u.toast(res.msg || t('login.msg0'))
  106. }
  107. } catch (error) {
  108. // console.log(error, 111);
  109. }
  110. }
  111. async function reasonsRefusalList() {
  112. try {
  113. const res = await customApi.reasonsRefusalList()
  114. if (res.code === 200) {
  115. pickFields(res.data)
  116. } else {
  117. uni.$u.toast(res.msg || t('login.msg0'))
  118. }
  119. } catch (error) {
  120. // console.log(error, 111);
  121. }
  122. }
  123. function pickFields(source, fields = ['content', 'enContent']) {
  124. const result = {}
  125. Object.entries(source).forEach(([key, value]) => {
  126. result[key] = fields.reduce((acc, f) => {
  127. acc[f] = value[f] ?? null
  128. return acc
  129. }, {})
  130. })
  131. userStore.saveReasonsOptions(result)
  132. }
  133. onMounted(() => {
  134. const hostParts = window.location.host.split('.')
  135. ho.value = hostParts.length > 1 ? hostParts[1] : ''
  136. const accountInfo = userStore.accountInfo
  137. if (accountInfo?.rememberPassword) {
  138. form.value.loginName = accountInfo?.loginName || ''
  139. form.value.password = accountInfo?.password || ''
  140. remenber.value = ['记住我']
  141. } else {
  142. form.value.loginName = ''
  143. form.value.password = ''
  144. remenber.value = []
  145. }
  146. })
  147. const inputType = ref('password')
  148. const ho = ref('')
  149. </script>
  150. <template>
  151. <view class="login-page" :isHeaderFixed="true" :isLoginPage="true">
  152. <uni-row class="demo-uni-row">
  153. <cwg-match-media :min-width="991">
  154. <uni-col :xs="24" :sm="24" :md="12" :lg="14" :xl="16">
  155. <view class="left-bg">
  156. <view class="left-box">
  157. <view class="inner">
  158. <view class="section-title">
  159. <text class="bg-secondary-opacity subtitle w-40" v-t="'newLoop.item11'"></text>
  160. </view>
  161. <view class="title w-700">
  162. <text v-t="'newLoop.item12'"></text>
  163. <text>&nbsp;</text>
  164. <text class="color-white" v-t="'newLoop.item13'"></text>
  165. </view>
  166. <view class="text-white" v-t="'newLoop.item14'"></view>
  167. </view>
  168. <image src="/static/images/trust-pilot.png" class="img-fluid mt--10" mode="widthFix"></image>
  169. <view class="left-content">
  170. <view class="des text-white">
  171. <text v-html="t('newSignin.item12')"></text>
  172. <br />
  173. <text v-html="t('newSignin.item12_1')"></text>
  174. <br />
  175. <text v-html="t('newSignin.item10')"></text>
  176. <br />
  177. <text v-html="t('newSignin.item11')"></text>
  178. <br />
  179. <text v-t="'newSignin.item13'"></text>
  180. <a
  181. :href="`https://www.${ho}.com/doc/Risk-Disclosures-and-Acknowledgements-2020-08.pdf`"
  182. target="_blank"
  183. v-t="'newSignin.item13_1'"
  184. class="doc-link"
  185. ></a>
  186. <text v-t="'newSignin.item13_2'"></text>
  187. <!-- <view v-t="'newSignin.item13_3'"></view>
  188. <text v-t="'newSignin.item13_4'"></text> -->
  189. </view>
  190. </view>
  191. </view>
  192. </view>
  193. </uni-col>
  194. </cwg-match-media>
  195. <uni-col :xs="24" :sm="24" :md="12" :lg="10" :xl="8" class="right-f">
  196. <view class="account">
  197. <cwg-match-media :max-width="991">
  198. <view class="company u-flex-y u-flex-y-center">
  199. <image src="/static/images/logo.png" class="company-icon" mode="widthFix"></image>
  200. </view>
  201. </cwg-match-media>
  202. <view class="title">
  203. <view class="tit1">{{ t('newSignin.item1') }}</view>
  204. <view class="tit2">{{ t('newSignin.item2') }}</view>
  205. </view>
  206. <view>
  207. <up-form :model="form" ref="uFormRef">
  208. <up-form-item label="" prop="loginName">
  209. <up-input :customStyle="customStyle" v-model="form.loginName" border="none"
  210. :placeholder="t('signin.form.email')">
  211. <template #prefix>
  212. <cwg-icon name="email-outline" :size="20" color="#000" />
  213. </template>
  214. </up-input>
  215. </up-form-item>
  216. <up-form-item label="" prop="password">
  217. <up-input :customStyle="customStyle" v-model="form.password" :type="inputType" border="none"
  218. :placeholder="t('signin.form.password')">
  219. <template #prefix>
  220. <cwg-icon name="lock-outline" :size="20" color="#000" />
  221. </template>
  222. </up-input>
  223. </up-form-item>
  224. </up-form>
  225. </view>
  226. <view class="u-flex u-flex-between u-flex-y-center mb1">
  227. <view class="check-box">
  228. <up-checkbox-group v-model="remenber" @change="checkboxChange">
  229. <up-checkbox size="14" labelSize="14" labelColor="#666666" activeColor="#ea002a"
  230. :label="t('newSignin.item5')" name="记住我" class="wcg-checkbox"></up-checkbox>
  231. </up-checkbox-group>
  232. </view>
  233. <navigator url="/pages/login/reset" class="account-tip">
  234. <text>{{ t('signin.forget') }}</text>
  235. </navigator>
  236. </view>
  237. <view class="cwg-button">
  238. <u-button type="primary" class="" @click="submit">
  239. {{ t('signin.login') }}
  240. </u-button>
  241. </view>
  242. <navigator url="/pages/login/regist" class="account-tip">
  243. {{ t('signin.words') }}
  244. <text>{{ t('signin.signup') }}</text>
  245. </navigator>
  246. <cwg-match-media :min-width="791">
  247. <view class="qr-container">
  248. <view class="qr-title">
  249. <view class="line"></view>
  250. <view class="qr-tit2">{{ t('newSignin.item2') }}</view>
  251. <view class="line"></view>
  252. </view>
  253. <QrCode width="200" height="200" text="cardGuide" :logo="logoImage"></QrCode>
  254. </view>
  255. </cwg-match-media>
  256. </view>
  257. </uni-col>
  258. </uni-row>
  259. </view>
  260. </template>
  261. <style lang="scss" scoped>
  262. @import "@/uni.scss";
  263. :deep(uni-content) {
  264. padding-left: 0 !important;
  265. }
  266. .login-page {
  267. height: 100vh;
  268. border: none;
  269. padding: 0;
  270. }
  271. .demo-uni-row {
  272. margin: 0 !important;
  273. .left-bg {
  274. height: 100%;
  275. min-height: 100vh;
  276. background-image: url(/static/images/login-bg.gif);
  277. background-repeat: no-repeat;
  278. background-size: cover;
  279. background-position: center center;
  280. display: flex;
  281. flex-direction: column;
  282. align-items: center;
  283. .left-box {
  284. display: flex;
  285. flex-direction: column;
  286. justify-content: center;
  287. align-items: flex-start;
  288. width: 60%;
  289. margin-top: px2rpx(20);
  290. .inner {
  291. width: 100%;
  292. text-align: start;
  293. margin-bottom: px2rpx(20);
  294. .section-title {
  295. margin-top: px2rpx(30);
  296. margin-bottom: px2rpx(10);
  297. }
  298. .title {
  299. font-size: px2rpx(60);
  300. line-height: 1.3;
  301. color: #fff;
  302. font-weight: 700;
  303. }
  304. .w-700 {
  305. font-weight: 700;
  306. }
  307. .subtitle {
  308. width: 45%;
  309. font-size: px2rpx(18);
  310. letter-spacing: px2rpx(1);
  311. display: block;
  312. margin-bottom: px2rpx(24);
  313. color: #ffffff;
  314. line-height: px2rpx(15);
  315. font-weight: 500;
  316. padding: px2rpx(10) px2rpx(20);
  317. border-radius: px2rpx(100);
  318. text-transform: uppercase;
  319. background-color: #e61f1e;
  320. text-align: center;
  321. }
  322. .w-40 {
  323. max-width: 40%;
  324. }
  325. .text-white {
  326. margin-top: px2rpx(10);
  327. font-size: px2rpx(14);
  328. line-height: 1.6;
  329. color: #fff;
  330. }
  331. }
  332. .img-fluid {
  333. width: 100%;
  334. max-width: px2rpx(240);
  335. }
  336. .mt--10 {
  337. margin-top: px2rpx(10);
  338. }
  339. .h1 {
  340. // text-align: center;
  341. color: #fff;
  342. font-size: 30px;
  343. margin-top: 30px;
  344. line-height: 1.5;
  345. }
  346. .h6 {
  347. text-align: start;
  348. line-height: 20px;
  349. color: #fff;
  350. font-size: 14px;
  351. margin-top: 10px;
  352. }
  353. .company {
  354. padding: px2rpx(10) 0 px2rpx(10) 0;
  355. position: relative;
  356. align-items: flex-start !important;
  357. width: 100%;
  358. }
  359. }
  360. .left-content {
  361. width: 100%;
  362. .des {
  363. text-align: start;
  364. line-height: 24px;
  365. color: #fff;
  366. font-size: 14px;
  367. margin-top: px2rpx(20);
  368. :nth-child(n) {
  369. display: inline;
  370. word-break: break-all;
  371. word-wrap: break-word;
  372. }
  373. .doc-link {
  374. color: var(--color-error);
  375. text-decoration: underline;
  376. margin: 0 px2rpx(4);
  377. }
  378. }
  379. }
  380. }
  381. .right-f {
  382. background-color: var(--color-white);
  383. padding: 0 px2rpx(24);
  384. box-sizing: border-box;
  385. .account {
  386. background-color: var(--color-white);
  387. position: relative;
  388. height: calc(100vh - 60px);
  389. display: flex;
  390. flex-direction: column;
  391. justify-content: center;
  392. padding: 0 10%;
  393. .company {
  394. padding: px2rpx(50) 0 px2rpx(20) 0;
  395. position: relative;
  396. align-items: center !important;
  397. }
  398. .company-icon {
  399. width: px2rpx(234);
  400. }
  401. }
  402. }
  403. }
  404. .bottom-box {
  405. width: 100%;
  406. height: 60px;
  407. background-color: var(--color-white);
  408. display: flex;
  409. justify-content: center;
  410. align-items: center;
  411. color: #000;
  412. .bottom-title {
  413. text-align: center;
  414. font-size: px2rpx(14);
  415. font-weight: 500;
  416. line-height: 1.5;
  417. color: #666666;
  418. }
  419. .ellipsis {
  420. width: px2rpx(200);
  421. white-space: nowrap;
  422. overflow: hidden;
  423. text-overflow: ellipsis;
  424. }
  425. .cwg-button {
  426. width: 120px !important;
  427. padding: px2rpx(4) 0 !important;
  428. }
  429. }
  430. button {
  431. background-color: #ea002a;
  432. font-size: px2rpx(14);
  433. font-weight: normal;
  434. height: px2rpx(44);
  435. line-height: px2rpx(44);
  436. }
  437. .right-f .account .company {
  438. padding: px2rpx(50) 0 px2rpx(200) 0;
  439. position: relative;
  440. align-items: flex-start !important;
  441. }
  442. .logo {
  443. margin-left: px2rpx(48);
  444. }
  445. .left-bg .company-icon {
  446. width: px2rpx(234);
  447. }
  448. .left-bg .left-content {
  449. position: relative;
  450. z-index: 1;
  451. }
  452. .title {
  453. margin: px2rpx(32) 0;
  454. font-size: px2rpx(24);
  455. font-weight: bolder;
  456. color: #e4e4e4;
  457. text-align: center;
  458. i {
  459. margin-right: px2rpx(10);
  460. }
  461. .tit1 {
  462. font-size: px2rpx(34);
  463. line-height: 1.5;
  464. font-weight: bold;
  465. color: #000000;
  466. }
  467. .tit2 {
  468. font-size: px2rpx(16);
  469. line-height: 1.5;
  470. color: #cecece;
  471. font-weight: 500;
  472. }
  473. }
  474. .qr-title {
  475. font-size: px2rpx(16);
  476. line-height: 1.5;
  477. color: #cecece;
  478. font-weight: 500;
  479. text-align: center;
  480. margin: px2rpx(40) 0;
  481. display: flex;
  482. align-items: center;
  483. justify-content: center;
  484. .line {
  485. flex: 1;
  486. height: 1px;
  487. background-color: #e4e4e4;
  488. }
  489. .qr-tit2 {
  490. margin: 0 px2rpx(12);
  491. }
  492. }
  493. .input {
  494. height: px2rpx(44);
  495. border-radius: px2rpx(8);
  496. background: #f7f8fa;
  497. padding: 0 px2rpx(20) !important;
  498. position: relative;
  499. }
  500. .account-icon {
  501. width: px2rpx(12);
  502. height: px2rpx(14) !important;
  503. margin-right: px2rpx(5);
  504. }
  505. :deep(.u-input__content__prefix-icon) {
  506. height: px2rpx(20);
  507. }
  508. .regiset-btn {
  509. margin: px2rpx(20) 0;
  510. }
  511. .account-tip {
  512. color: #666666;
  513. font-size: px2rpx(14);
  514. text-align: center;
  515. text {
  516. color: #ea002a;
  517. }
  518. }
  519. :deep(.u-form-item__body) {
  520. padding: 0 !important;
  521. padding-bottom: px2rpx(24) !important;
  522. }
  523. :deep(.wcg-checkbox) {
  524. padding: 0 !important;
  525. }
  526. .cwg-button {
  527. padding: px2rpx(34) 0 !important;
  528. }
  529. </style>