login.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. <template>
  2. <div class="login">
  3. <a-row type="flex" justify="center" align="middle">
  4. <a-col>
  5. <div class="login-background" id="img">
  6. <!-- <div id="img"> -->
  7. <!-- <img src="./logo.png"
  8. alt="" />-->
  9. <!-- </div> -->
  10. </div>
  11. <div class="login-content">
  12. <p>账号登录</p>
  13. <a-form ref="formDom" :model="form" :rules="rules">
  14. <a-form-item name="account">
  15. <a-input placeholder="用户名/账号/手机号" v-model:value="form.account">
  16. <template #prefix>
  17. <img src="@/assets/images/user.png" />
  18. </template>
  19. </a-input>
  20. </a-form-item>
  21. <a-form-item name="password" class="mb20">
  22. <a-input @keyup.enter="loginAction" placeholder="请输入您的登录密码" type="password" v-model:value="form.password">
  23. <template #prefix>
  24. <img src="@/assets/images/password.png" />
  25. </template>
  26. </a-input>
  27. </a-form-item>
  28. <a-form-item>
  29. <div class="login-remember-password">
  30. <a-checkbox v-model:checked="form.isRemember">记住账号</a-checkbox>
  31. <!-- <router-link to="/resetPassword">忘记密码?</router-link> -->
  32. </div>
  33. </a-form-item>
  34. <!-- <a-form-item>
  35. <div style="text-align:left">
  36. <a-checkbox v-model:checked="form.isRead">
  37. 我已阅读并同意
  38. </a-checkbox>
  39. <router-link to="/resetPassword">《用户协议》</router-link>
  40. </div>
  41. </a-form-item>-->
  42. <a-form-item class="mt20" name="isRead">
  43. <a-button @click="loginAction" :loading="loading" :disabled="goHomeloading">登录</a-button>‚
  44. <div class="agreement agreement-header">
  45. <a-checkbox v-model:checked="isReadAgreement">已阅读并同意</a-checkbox>
  46. </div>
  47. <div class="agreement">
  48. <a v-for="item in agreementList" @click="showModal(item)" :key="item.agreementid">《{{ item.agreementname }}》</a>
  49. </div>
  50. <div class="register" v-if="isOpenUrl">
  51. 还没有账号,
  52. <span @click="register">立即注册</span>
  53. </div>
  54. </a-form-item>
  55. </a-form>
  56. </div>
  57. </a-col>
  58. </a-row>
  59. <a-modal class="commonModal" v-if="visible" :title="selectedAgreement?.agreementname" v-model:visible="visible" centered @cancel="closeModel" :footer="null" width="890px">
  60. <div class="agreement-content" v-html="formateWord(selectedAgreement.agreementcontent)"></div>
  61. </a-modal>
  62. </div>
  63. </template>
  64. <script lang="ts">
  65. import { initData, setLoadComplete } from '@/common/methods';
  66. import { globalDataRefresh } from '@/services/bus/index';
  67. import { login } from '@/services/bus/login';
  68. import { queryUserNodeCfgAndStatus } from '@/services/go/QhjSys';
  69. import { QueryUserNodeCfgAndStatusRsp } from '@/services/go/QhjSys/interface';
  70. import { isOpenUrl, serviceURL } from '@/services/request/serviceURL';
  71. import eventBus from '@/utils/eventBus/index';
  72. import { localStorageUtil } from '@/utils/storage/index';
  73. import { message } from 'ant-design-vue';
  74. import { defineComponent, onMounted, reactive, ref, toRaw } from 'vue';
  75. import { useRouter } from 'vue-router';
  76. import { qtAction } from './qt';
  77. interface Form {
  78. account: string;
  79. password: string;
  80. isRemember: boolean;
  81. isRead: boolean;
  82. }
  83. const initForm: Form = {
  84. account: '',
  85. password: '',
  86. isRemember: false,
  87. isRead: false,
  88. };
  89. function setRememberAccount(): void {
  90. const account: string = localStorageUtil.getItem('loginAccount');
  91. if (account) {
  92. Object.assign(initForm, { account, isRemember: true });
  93. }
  94. }
  95. function setLogo() {
  96. const img = document.querySelector('#logo_img') || document.createElement('img');
  97. const obj = {
  98. id: 'logo_img',
  99. src: './logo.png',
  100. style: 'margin-bottom: 180px',
  101. };
  102. Object.assign(img, obj);
  103. document.querySelector('#img')?.appendChild(img);
  104. }
  105. // 协议
  106. function useAgreement() {
  107. // 协议
  108. const agreementList = ref<QueryUserNodeCfgAndStatusRsp[]>([])
  109. const selectedAgreement = ref<QueryUserNodeCfgAndStatusRsp | null>(null)
  110. const visible = ref<boolean>(false);
  111. const showModal = (item: QueryUserNodeCfgAndStatusRsp) => {
  112. selectedAgreement.value = item
  113. visible.value = true;
  114. };
  115. const closeModel = () => {
  116. visible.value = false
  117. }
  118. const formateWord = (val: string) => {
  119. return val.replace(/\n/g, '<br>')
  120. }
  121. initData(() => {
  122. queryUserNodeCfgAndStatus({ nodetype: '2', agreementtype: 2 }).then(res => {
  123. if (Array.isArray(res)) {
  124. agreementList.value = res
  125. }
  126. })
  127. })
  128. return { agreementList, showModal, selectedAgreement, visible, closeModel, formateWord }
  129. }
  130. export default defineComponent({
  131. name: 'login',
  132. components: {},
  133. setup() {
  134. const isReaad = localStorageUtil.getItem('readAgreement') ? true : false
  135. const isReadAgreement = ref<boolean>(isReaad)
  136. onMounted(() => {
  137. setLogo();
  138. });
  139. const loading = ref<boolean>(false);
  140. const form = reactive(initForm);
  141. const rules = {
  142. account: [{ required: true, message: '请输入手机号!', trigger: 'change', type: 'string' }],
  143. password: [{ required: true, message: '请输入密码!', trigger: 'change', type: 'string' }],
  144. };
  145. const formDom: any = ref(null);
  146. const router = useRouter();
  147. form.password = '';
  148. // setRememberAccount();
  149. // qt
  150. const { getQtInfo } = qtAction();
  151. function loginAction() {
  152. formDom.value.validate().then(() => {
  153. if (!isReadAgreement.value) {
  154. message.error('请阅读并同意协议')
  155. return
  156. }
  157. localStorageUtil.setItem('readAgreement', true)
  158. loading.value = true;
  159. const { account, password } = toRaw(form);
  160. setLoadComplete(false);
  161. getQtInfo().then((arr) => {
  162. login(account, password, arr)
  163. .then((value: any) => {
  164. setLoadComplete(true);
  165. const { account, isRemember } = toRaw(form);
  166. if (isRemember) {
  167. localStorageUtil.setItem('loginAccount', account); // 缓存登录账号
  168. }
  169. eventBus.$emit('loginSuccess', true);
  170. router.push({ name: 'home' });
  171. loading.value = false;
  172. })
  173. .catch((err: any) => {
  174. loading.value = false;
  175. err && message.error(err);
  176. });
  177. });
  178. });
  179. }
  180. // 直接前往首页
  181. const goHomeloading = ref<boolean>(false);
  182. const goHome = () => {
  183. goHomeloading.value = true;
  184. setLoadComplete(false);
  185. globalDataRefresh()
  186. .then((res) => {
  187. setLoadComplete(true);
  188. goHomeloading.value = false;
  189. router.push({ name: 'home' });
  190. })
  191. .catch((err) => {
  192. console.error(err);
  193. goHomeloading.value = false;
  194. });
  195. };
  196. function register() {
  197. window.open(serviceURL.openApiUrl, '_blank');
  198. }
  199. return { form, loginAction, isReadAgreement, rules, formDom, loading, goHomeloading, goHome, register, isOpenUrl, ...useAgreement() };
  200. },
  201. });
  202. </script>
  203. <style lang="less" scoped>
  204. .agreement-header {
  205. margin-top: -30px;
  206. }
  207. .agreement {
  208. height: 30px;
  209. line-height: 30px;
  210. }
  211. .register {
  212. cursor: pointer;
  213. }
  214. .login {
  215. width: 100%;
  216. height: 100%;
  217. background: url(../../assets/images/loginBackground.png) no-repeat scroll 0 0;
  218. background-size: 100% 100%;
  219. }
  220. .ant-row {
  221. height: 100%;
  222. }
  223. .ant-col {
  224. width: 800px;
  225. height: 450px;
  226. background: @m-white0;
  227. border-radius: 5px;
  228. box-shadow: 0px 5px 10px 0px rgba(18, 22, 24, 0.18);
  229. .flex();
  230. }
  231. .agreement-content {
  232. font-size: 14px;
  233. color: @m-grey25;
  234. }
  235. .login-background {
  236. width: 275px;
  237. background: url('../../assets/images/logoBackground.png') no-repeat scroll 0 0;
  238. background-size: cover;
  239. display: flex;
  240. align-items: center;
  241. justify-content: center;
  242. div {
  243. // margin-top: 120px;
  244. // margin-left: 69.5px; // 企业风管logo
  245. // margin-left: 33px; // 云融
  246. width: 136px;
  247. height: 136px;
  248. min-width: 136px;
  249. min-height: 136px;
  250. position: relative;
  251. // img {
  252. // max-width: 100%;
  253. // max-height: 100%;
  254. // .position(absolute, 0%, auto, auto, 50%);
  255. // z-index: 10;
  256. // transform: translate(-50%, -50%);
  257. // }
  258. }
  259. // .ant-btn {
  260. // background: @cyan-color2;
  261. // border-color: @cyan-color2;
  262. // border-radius: 10px;
  263. // font-size: 14px;
  264. // color: @white;
  265. // margin-top: 90px;
  266. // margin-left: -60px;
  267. // }
  268. }
  269. .login-content {
  270. flex: 1;
  271. padding-left: 53px;
  272. padding-right: 53px;
  273. min-width: 405px;
  274. ::v-deep(.ant-form) {
  275. margin-top: 20px;
  276. .ant-form-item-control-wrapper {
  277. width: 100%;
  278. }
  279. .ant-form-item-control.has-error {
  280. .ant-form-item-children {
  281. .ant-input-affix-wrapper {
  282. .ant-input {
  283. background: transparent !important;
  284. }
  285. }
  286. }
  287. .ant-form-explain {
  288. text-align: left;
  289. padding-left: 24px;
  290. }
  291. }
  292. .ant-input {
  293. border: 0;
  294. border-radius: 0;
  295. width: 154px;
  296. height: 40px;
  297. font-size: 16px;
  298. font-family: Adobe Heiti Std;
  299. }
  300. .ant-input-affix-wrapper {
  301. box-shadow: none;
  302. border: none;
  303. border-radius: 0;
  304. border-bottom: 1px solid @m-grey3;
  305. padding: 0;
  306. }
  307. .ant-input-affix-wrapper:hover {
  308. border-bottom: 1px solid @m-blue1;
  309. }
  310. }
  311. .mt20 {
  312. margin-top: 20px;
  313. }
  314. .mb20 {
  315. margin-bottom: 20px;
  316. }
  317. .ant-form-item,
  318. .ant-form label {
  319. font-size: 16px;
  320. }
  321. .ant-form-item {
  322. margin-bottom: 10px;
  323. }
  324. p {
  325. font-size: 26px;
  326. text-align: left;
  327. font-family: Adobe Heiti Std;
  328. font-weight: normal;
  329. color: @m-grey4;
  330. margin-top: 40px;
  331. margin-bottom: 10px;
  332. }
  333. img {
  334. width: 19px;
  335. height: 21px;
  336. }
  337. .login-remember-password {
  338. .flex();
  339. justify-content: space-between;
  340. a {
  341. color: @m-grey4;
  342. }
  343. }
  344. .ant-btn {
  345. width: 100%;
  346. font-size: 16px;
  347. background: @m-blue1;
  348. border-radius: 3px;
  349. color: @m-white0;
  350. height: 50px;
  351. font-weight: 500;
  352. line-height: 43px;
  353. }
  354. }
  355. </style>