login.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. <template>
  2. <div class="full-screen flex flex-center bg">
  3. <div class="login white-bg radius" v-loading="loading">
  4. <div class="flex flex-center flex-child-average">
  5. <div class="flex left">
  6. <img
  7. src="https://wutong-1302848345.cos.ap-chengdu.myqcloud.com/wtzx/373e3ccd35be4ba2a72376050027612e.png"
  8. style="
  9. height: 560px;
  10. object-fit: contain;
  11. border-bottom-left-radius: 10px;
  12. border-top-left-radius: 10px;
  13. "
  14. />
  15. </div>
  16. <div class="right flex flex-col flex-child-average">
  17. <div class="flex flex-col flex-justify-between" style="height: 560px">
  18. <div
  19. class="flex flex-justify-end"
  20. style="margin-right: 3px; margin-top: 3px"
  21. >
  22. <div>
  23. <img
  24. v-if="qrCodeLogin"
  25. src="../assets/img/com.png"
  26. style="width: 80px"
  27. @click="qrCodeLogin = !qrCodeLogin"
  28. />
  29. <img
  30. v-else
  31. src="../assets/img/code.png"
  32. style="width: 80px"
  33. @click="qrCodeLogin = !qrCodeLogin"
  34. />
  35. </div>
  36. </div>
  37. <div
  38. v-if="qrCodeLogin"
  39. class="flex flex-center flex-col"
  40. style="height: 500px; margin-top: -20px"
  41. >
  42. <span class="font-24 black bold">欢迎来到梧桐树云平台👏</span>
  43. <div
  44. class="flex flex-col flex-center"
  45. style="height: 360px; width: 360px; margin-top: -20px"
  46. >
  47. <vue-qr
  48. :currentLevel="3"
  49. :logoCornerRadius="4"
  50. :logoScale="0.25"
  51. :logoSrc="logoSrc"
  52. :text="qrCodeText"
  53. size="260"
  54. />
  55. </div>
  56. <span
  57. class="mt-10 bold main-color font-16"
  58. style="margin-top: -20px"
  59. >打开微信扫描二维码登陆梧桐树云平台</span
  60. >
  61. </div>
  62. <div v-else class="flex flex-col flex-center" style="height: 500px">
  63. <span class="font-24 black bold">欢迎来到梧桐树云平台👏</span>
  64. <div
  65. class="flex flex-col flex-center mt-5"
  66. style="width: 450px; height: 400px"
  67. >
  68. <el-form ref="loginForm" :model="form" :rules="rules">
  69. <el-form-item prop="name">
  70. <el-input
  71. v-model="form.name"
  72. placeholder="用户帐号"
  73. prefix-icon="Avatar"
  74. size="large"
  75. />
  76. </el-form-item>
  77. <el-form-item prop="pass">
  78. <el-input
  79. v-model="form.pass"
  80. :type="flag ? 'text' : 'password'"
  81. placeholder="密码"
  82. prefix-icon="WalletFilled"
  83. size="large"
  84. >
  85. <template v-slot:suffix>
  86. <div class="pointer" @click="flag = !flag">
  87. <el-icon v-if="!flag">
  88. <Hide />
  89. </el-icon>
  90. <el-icon v-else>
  91. <View />
  92. </el-icon>
  93. </div>
  94. </template>
  95. </el-input>
  96. </el-form-item>
  97. <el-form-item prop="code">
  98. <el-input
  99. v-model="form.code"
  100. class="append"
  101. placeholder="验证码"
  102. prefix-icon="Refresh"
  103. size="large"
  104. @keyup.enter="submint"
  105. >
  106. <template v-slot:append>
  107. <img
  108. :src="code"
  109. class="pic"
  110. @click="init"
  111. style="
  112. height: 40px;
  113. background-color: red;
  114. background-blend-mode: lighten;
  115. "
  116. alt="code"
  117. />
  118. </template>
  119. </el-input>
  120. </el-form-item>
  121. <el-form-item>
  122. <div
  123. class="flex flex-align-center flex-justify-between full-width"
  124. >
  125. <div></div>
  126. <el-link :underline="false" class="font-12" type="primary"
  127. >忘记密码?</el-link
  128. >
  129. </div>
  130. </el-form-item>
  131. </el-form>
  132. <el-button
  133. size="large"
  134. style="width: 78%"
  135. type="primary"
  136. @click="submint"
  137. >登录</el-button
  138. >
  139. <div class="flex flex-col mt-10 flex-center">
  140. <span class="grey-6">由梧桐研究院提供技术支持</span>
  141. <span class="grey-6 mt-5">使用问题请咨询:13908866200</span>
  142. <el-button
  143. color="#558FF1"
  144. @click="
  145. download(
  146. 'https://wutong-1302848345.cos.ap-chengdu.myqcloud.com/wtzx/a53cc056c3914ae9884992dafe7a9679.pdf'
  147. )
  148. "
  149. style="width: 160px"
  150. plain
  151. class="mt-10 blockss"
  152. >
  153. 点击下载用户指南
  154. </el-button>
  155. <span class="grey-6 mt-5 font-12 mt-20"
  156. >为了获得最佳体验,您可以<span
  157. class="blue pointer"
  158. @click="
  159. download('https://www.google.cn/intl/zh-CN/chrome/')
  160. "
  161. >点击此处</span
  162. >获取Chrome 浏览器</span
  163. >
  164. </div>
  165. </div>
  166. </div>
  167. </div>
  168. </div>
  169. </div>
  170. </div>
  171. </div>
  172. </template>
  173. <route>
  174. {
  175. meta: {
  176. layout: 'empty',
  177. },
  178. }
  179. </route>
  180. <script>
  181. import md5 from 'js-md5'
  182. import { useStore } from '@/store/user.js'
  183. import { removeToken, setToken } from '../utils/auth.js'
  184. import permissionStore from '@/store/permission.js'
  185. import VueQr from 'vue-qr/src/packages/vue-qr.vue'
  186. export default {
  187. name: 'login',
  188. components: { VueQr },
  189. watch: {
  190. qrCodeLogin: {
  191. handler(val) {
  192. if (val) {
  193. this.qrCode()
  194. this.checkLogin()
  195. }
  196. },
  197. immediate: true
  198. }
  199. },
  200. setup() {
  201. const user = useStore()
  202. const permission = permissionStore()
  203. return { user, permission }
  204. },
  205. data() {
  206. return {
  207. flag: false,
  208. form: {
  209. name: '',
  210. pass: ''
  211. },
  212. rules: {
  213. name: [
  214. { required: true, message: '请输入用户帐号', trigger: 'blur' }
  215. // { min: 11, max: 11, message: '请输入11位手机号', trigger: 'blur' }
  216. ],
  217. pass: [
  218. { required: true, message: '请输入密码', trigger: 'blur' },
  219. { min: 3, max: 12, message: '长度在 3 到 12 个字符', trigger: 'blur' }
  220. ],
  221. code: [
  222. { required: true, message: '请输入验证码', trigger: 'blur' },
  223. { min: 5, max: 5, message: '验证码不正确', trigger: 'blur' }
  224. ]
  225. },
  226. code: '',
  227. header: '',
  228. qrCodeLogin: false,
  229. time: null,
  230. qrCodeText: '',
  231. sessionId: '',
  232. logoSrc: new URL('../assets/img/logo.png', import.meta.url).href,
  233. dev: true,
  234. loading: false
  235. }
  236. },
  237. created() {
  238. this.permission.cleanPermission()
  239. // fixme prod 环境暂时开启账号登录功能
  240. // this.dev = window.location.href.indexOf('localhost') > -1 || window.location.href.indexOf('https://dev.wutongshucloud.com/') > -1 || window.location.href.indexOf('192.168.31') > -1
  241. this.dev =
  242. window.location.href.indexOf('localhost') > -1 ||
  243. window.location.href.indexOf('192.168.31') > -1
  244. removeToken()
  245. this.init()
  246. },
  247. unmounted() {
  248. clearInterval(this.time)
  249. },
  250. methods: {
  251. init() {
  252. const dev =
  253. window.location.href.indexOf('dash.wutongshucloud.com') > -1 ||
  254. window.location.href.indexOf('localhost') > -1
  255. sessionStorage.setItem('dev', dev)
  256. this.$api.login.captcha().then(res => {
  257. this.code = res.image
  258. this.header = res.key
  259. })
  260. },
  261. submint() {
  262. this.$refs.loginForm.validate(res => {
  263. if (res) {
  264. const params = {
  265. tenantId: '000000',
  266. username: this.form.name,
  267. password: md5(this.form.pass),
  268. grant_type: 'captcha',
  269. scope: 'all',
  270. type: 'account'
  271. }
  272. const header = {
  273. captchaKey: this.header,
  274. captchaCode: this.form.code
  275. }
  276. this.loading = true
  277. this.$api.login.login(params, header).then(res => {
  278. this.loading = false
  279. if (res.error_description) {
  280. this.$message.error(res.error_description)
  281. this.init()
  282. } else {
  283. setToken(res.access_token)
  284. this.user.setUserInfo({ name: res.real_name })
  285. this.getInfo()
  286. }
  287. })
  288. } else {
  289. return false
  290. }
  291. })
  292. },
  293. download(url) {
  294. window.open(
  295. url,
  296. '_blank' // <- This is what makes it open in a new window.
  297. )
  298. },
  299. loginAdmin() {
  300. this.form.name = '15587166921'
  301. this.form.pass = 'wtkj@123'
  302. },
  303. loginOther() {
  304. this.form.name = '15587160283'
  305. this.form.pass = 'wtkj@123'
  306. },
  307. getInfo() {
  308. this.$api.login.getUserInfo().then(res => {
  309. if (res.code === 200) {
  310. // 保存信息
  311. if (res.data.type === 3) {
  312. res.data.typeName = '机构'
  313. } else {
  314. res.data.typeName = '服务商'
  315. }
  316. this.user.setUserInfo(res.data)
  317. this.$router.replace('/')
  318. }
  319. })
  320. },
  321. checkLogin() {
  322. let count = 0
  323. this.time = setInterval(() => {
  324. count = count + 1
  325. if (this.qrCodeLogin === false) {
  326. clearInterval(this.time)
  327. }
  328. if (count === 60) {
  329. this.qrCode()
  330. count = 0
  331. }
  332. if (this.sessionId) {
  333. this.codeLogin()
  334. } else {
  335. this.codeLogin()
  336. }
  337. }, 1000)
  338. },
  339. qrCode() {
  340. this.$api.login.qrCode().then(res => {
  341. if (res.code === 200) {
  342. this.sessionId = res.data
  343. this.qrCodeText =
  344. 'https://dev.wutongresearch.club/login?id=' + this.sessionId
  345. }
  346. })
  347. },
  348. codeLogin() {
  349. this.$api.login.qrCodeLogin({ sessionId: this.sessionId }).then(res => {
  350. if (res.code === 200) {
  351. const tmp = res.data
  352. if (Object.prototype.hasOwnProperty.call(tmp, 'phone')) {
  353. const params = {
  354. tenantId: '000000',
  355. phone: res.data.phone,
  356. openId: res.data.openId,
  357. grant_type: 'qrcode',
  358. scope: 'all',
  359. type: 'account'
  360. }
  361. this.$api.login.loginByCode(params).then(res => {
  362. if (res.error_description) {
  363. this.$message.error(res.error_description)
  364. } else {
  365. clearInterval(this.time)
  366. setToken(res.access_token)
  367. this.getInfo()
  368. this.$router.replace('/')
  369. }
  370. })
  371. }
  372. }
  373. })
  374. }
  375. }
  376. }
  377. </script>
  378. <style lang="scss" scoped>
  379. //noinspection ALL
  380. .bg {
  381. background-image: url('https://wutong-1302848345.cos.ap-chengdu.myqcloud.com/wtzx/7667edec62f44063a50c66e8654eaa87.png');
  382. }
  383. .login {
  384. box-shadow: 5px 10px 10px 5px rgba(0, 0, 0, 0.28);
  385. .left {
  386. height: auto;
  387. .logo-main {
  388. width: 80%;
  389. }
  390. }
  391. .right {
  392. width: 560px;
  393. height: auto;
  394. .form {
  395. }
  396. }
  397. }
  398. .append {
  399. :deep(.el-input-group__append) {
  400. background-color: white;
  401. }
  402. .pic {
  403. border-top: #dddfe5 1px solid;
  404. border-bottom: #dddfe5 1px solid;
  405. }
  406. }
  407. </style>