login.vue 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. <template>
  2. <div class='full-screen flex flex-center bg'>
  3. <div class='login white-bg radius '>
  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="height: 560px;object-fit: contain;border-bottom-left-radius: 10px;border-top-left-radius: 10px"/>
  9. </div>
  10. <div class='right white-bg flex flex-col flex-child-average'>
  11. <div class='flex flex-justify-end full-height'
  12. style="margin-top: -20px;margin-right: 4px">
  13. <div>
  14. <img v-if="qrCodeLogin" src='../assets/img/com.png' style='width: 80px'
  15. @click='qrCodeLogin = !qrCodeLogin'/>
  16. <img v-else src='../assets/img/code.png' style='width: 80px'
  17. @click='qrCodeLogin = !qrCodeLogin'/>
  18. </div>
  19. </div>
  20. <div v-if='qrCodeLogin' class='flex flex-center flex-col mt-20'>
  21. <span class='font-24 black bold '>欢迎来到梧桐树云平台👏</span>
  22. <div class='flex flex-col flex-center mt-10' style='height: 360px;width: 360px'>
  23. <vue-qr :currentLevel='3' :logoCornerRadius='4' :logoScale='0.25' :logoSrc='logoSrc' :text='qrCodeText'
  24. size='340'/>
  25. </div>
  26. <span class='mt-10 bold main-color font-16'>打开微信扫描二维码登陆梧桐树云平台</span>
  27. </div>
  28. <div v-else class='padding-20 flex flex-col flex-center mt-20'>
  29. <span class='font-24 black bold '>欢迎来到梧桐树云平台👏</span>
  30. <div class="flex flex-col flex-center" style="width: 450px;height: 360px">
  31. <el-form ref='loginForm' :model="form" :rules="rules">
  32. <el-form-item prop='name'>
  33. <el-input
  34. v-model='form.name'
  35. placeholder="手机号码"
  36. prefix-icon="Avatar"
  37. size='large'
  38. />
  39. </el-form-item>
  40. <el-form-item prop='pass'>
  41. <el-input
  42. v-model='form.pass'
  43. :type='flag ? "text" : "password"'
  44. placeholder="密码"
  45. prefix-icon="WalletFilled"
  46. size='large'>
  47. <template v-slot:suffix>
  48. <div class='pointer' @click='flag=!flag'>
  49. <el-icon v-if='!flag'>
  50. <Hide/>
  51. </el-icon>
  52. <el-icon v-else>
  53. <View/>
  54. </el-icon>
  55. </div>
  56. </template>
  57. </el-input>
  58. </el-form-item>
  59. <el-form-item prop='code'>
  60. <el-input
  61. v-model='form.code'
  62. class='append'
  63. placeholder="验证码"
  64. prefix-icon="Refresh"
  65. size='large'
  66. >
  67. <template v-slot:append>
  68. <img :src='code' class='pic'
  69. style='height: 40px;background-color: red;background-blend-mode: lighten;'/>
  70. </template>
  71. </el-input>
  72. </el-form-item>
  73. <el-form-item>
  74. <div class='flex flex-align-center flex-justify-between full-width'>
  75. <div></div>
  76. <el-link :underline='false' class='font-12' type='primary'>忘记密码?</el-link>
  77. </div>
  78. </el-form-item>
  79. </el-form>
  80. <el-button size='large' style="width: 78%" type='primary' @click='submint'>登录</el-button>
  81. <div class='flex flex-col mt-10'>
  82. <span class='grey-6'>由梧桐经济院提供技术支持</span>
  83. <div>
  84. <el-button class='mt-10' plain size='small' type='primary' @click='loginAdmin'>admin</el-button>
  85. </div>
  86. </div>
  87. </div>
  88. </div>
  89. </div>
  90. </div>
  91. </div>
  92. </div>
  93. </template>
  94. <route>
  95. {
  96. meta: {
  97. layout: 'empty',
  98. },
  99. }
  100. </route>
  101. <script>
  102. import md5 from 'js-md5'
  103. import {useStore} from '@/store/user.js'
  104. import {removeToken, setToken} from '../utils/auth.js'
  105. import permissionStore from '@/store/permission.js'
  106. import VueQr from 'vue-qr/src/packages/vue-qr.vue'
  107. export default {
  108. name: 'login',
  109. components: {VueQr},
  110. watch: {
  111. qrCodeLogin: {
  112. handler(val) {
  113. if (val) {
  114. this.qrCode()
  115. this.checkLogin()
  116. }
  117. },
  118. immediate: true
  119. }
  120. },
  121. setup() {
  122. const user = useStore()
  123. const permission = permissionStore()
  124. return {user, permission}
  125. },
  126. data() {
  127. return {
  128. flag: false,
  129. form: {
  130. name: '',
  131. pass: ''
  132. },
  133. rules: {
  134. name: [
  135. {required: true, message: '请输入手机号码', trigger: 'blur'},
  136. {min: 11, max: 11, message: '请输入11位手机号', trigger: 'blur'}
  137. ],
  138. pass: [
  139. {required: true, message: '请输入密码', trigger: 'blur'},
  140. {min: 3, max: 12, message: '长度在 3 到 12 个字符', trigger: 'blur'}
  141. ],
  142. code: [
  143. {required: true, message: '请输入验证码', trigger: 'blur'},
  144. {min: 5, max: 5, message: '验证码不正确', trigger: 'blur'}
  145. ]
  146. },
  147. code: '',
  148. header: '',
  149. qrCodeLogin: true,
  150. time: null,
  151. qrCodeText: '',
  152. sessionId: '',
  153. logoSrc: new URL('../assets/img/logo.png', import.meta.url).href
  154. }
  155. },
  156. created() {
  157. this.permission.cleanPermission()
  158. removeToken()
  159. this.init()
  160. },
  161. unmounted() {
  162. clearInterval(this.time)
  163. },
  164. methods: {
  165. init() {
  166. this.$api.login.captcha().then(res => {
  167. this.code = res.image
  168. this.header = res.key
  169. })
  170. },
  171. submint() {
  172. this.$refs.loginForm.validate((res) => {
  173. if (res) {
  174. const params = {
  175. tenantId: '000000',
  176. username: this.form.name,
  177. password: md5(this.form.pass),
  178. grant_type: 'captcha',
  179. scope: 'all',
  180. type: 'account'
  181. }
  182. const header = {captchaKey: this.header, captchaCode: this.form.code}
  183. this.$api.login.login(params, header).then(res => {
  184. if (res.error_description) {
  185. this.$message.error(res.error_description)
  186. this.init()
  187. } else {
  188. setToken(res.access_token)
  189. this.getInfo()
  190. this.$router.replace('/')
  191. }
  192. })
  193. } else {
  194. return false
  195. }
  196. })
  197. },
  198. loginAdmin() {
  199. this.form.name = 'admin'
  200. this.form.pass = 'admin'
  201. },
  202. getInfo() {
  203. this.getPermission()
  204. this.$api.login.getUserInfo().then(res => {
  205. if (res.code === 200) {
  206. // 保存信息
  207. if (res.data.type === 3) {
  208. res.data.typeName = '机构'
  209. } else {
  210. res.data.typeName = '服务商'
  211. }
  212. this.user.setUserInfo(res.data)
  213. }
  214. })
  215. },
  216. getPermission() {
  217. this.$api.login.getPermission().then(res => {
  218. if (res.code === 200) {
  219. this.permission.addPermission(res.data)
  220. }
  221. })
  222. },
  223. checkLogin() {
  224. let count = 0
  225. this.time = setInterval(() => {
  226. count = count + 1
  227. if (this.qrCodeLogin === false) {
  228. clearInterval(this.time)
  229. }
  230. if (count === 60) {
  231. this.qrCode()
  232. count = 0
  233. }
  234. if (this.sessionId) {
  235. this.codeLogin()
  236. } else {
  237. this.codeLogin()
  238. }
  239. }, 1000)
  240. },
  241. qrCode() {
  242. this.$api.login.qrCode().then(res => {
  243. if (res.code === 200) {
  244. this.sessionId = res.data
  245. this.qrCodeText = 'https://dev.wutongresearch.club/login?id=' + this.sessionId
  246. }
  247. })
  248. },
  249. codeLogin() {
  250. this.$api.login.qrCodeLogin({sessionId: this.sessionId}).then(res => {
  251. if (res.code === 200) {
  252. const tmp = res.data
  253. console.log(Object.prototype.hasOwnProperty.call(tmp, 'phone'))
  254. if (Object.prototype.hasOwnProperty.call(tmp, 'phone')) {
  255. const params = {
  256. tenantId: '000000',
  257. phone: res.data.phone,
  258. openId: res.data.openId,
  259. grant_type: 'qrcode',
  260. scope: 'all',
  261. type: 'account'
  262. }
  263. this.$api.login.loginByCode(params).then(res => {
  264. if (res.error_description) {
  265. this.$message.error(res.error_description)
  266. } else {
  267. setToken(res.access_token)
  268. this.getInfo()
  269. this.$router.replace('/')
  270. }
  271. })
  272. }
  273. }
  274. })
  275. }
  276. }
  277. }
  278. </script>
  279. <style lang='scss' scoped>
  280. .bg {
  281. background-image: url("https://wutong-1302848345.cos.ap-chengdu.myqcloud.com/wtzx/7667edec62f44063a50c66e8654eaa87.png");
  282. }
  283. .login {
  284. .left {
  285. height: auto;
  286. width: 560;
  287. .logo-main {
  288. width: 80%;
  289. }
  290. }
  291. .right {
  292. width: 560px;
  293. height: auto;
  294. .form {
  295. }
  296. }
  297. }
  298. .append {
  299. :deep(.el-input-group__append) {
  300. background-color: white;
  301. }
  302. .pic {
  303. border-top: #DDDFE5 1px solid;
  304. border-bottom: #DDDFE5 1px solid;
  305. }
  306. }
  307. </style>