index.vue 12 KB

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