index.vue 12 KB

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