Login.vue 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. <template>
  2. <div id="app" class="bgImg w-full h-full flex bg-black">
  3. <div class=" w-8/12 h-full hidden md:flex justify-center items-center p-10 bg-blue-400 relative bg-map">
  4. <div class="w-full h-full bgImg absolute"></div>
  5. <div class="w-full h-4/5 bottom-0 absolute flex items-center justify-center relative">
  6. <div class="lbx absolute">
  7. <img src="/image/big/lbx.png" alt="lbx">
  8. </div>
  9. <div class="jt absolute ">
  10. <img src="/image/big/jt.png" alt="背景图片">
  11. </div>
  12. <div class="map absolute ">
  13. <img src="/image/big/map.png" alt="地球">
  14. </div>
  15. <div class="rounded-img absolute ">
  16. <img src="/image/big/rounded.png" alt="地球">
  17. </div>
  18. <div class="w-auto relative bottom-1/5">
  19. <h1 class="text-7xl text-white">合方圆管理平台</h1>
  20. <h2 class="text-2xl mt-3 text-gray-200">合天地方圆·尽在掌握</h2>
  21. <h2 class="mt-0.5 text-gray-500">HFY·<a href="/hfy">深圳合方圆</a></h2>
  22. </div>
  23. </div>
  24. </div>
  25. <!-- 登陆框逻辑-->
  26. <div class="w-full md:w-3/12 h-full flex justify-center md:justify-start items-center relative">
  27. <div class="blur w-full h-full absolute bg-blue-300 opacity-50 bgImg"></div>
  28. <div class="login-box w-80 h-auto rounded px-0.5 text-gray-200 relative">
  29. <h2 class="pt-2 text-xl">欢迎您,请登陆</h2>
  30. <div class="w-full px-1.5 flex">
  31. <div class="w-4/12 flex items-center u px-1"><p class="w-full text-justify">用户名</p> </div>
  32. <div class="w-8/12">
  33. <a-input placeholder="用户名" v-model="form.owner.val" @focus="form.owner.msg=''" @blur="checkFormItem('owner')"></a-input>
  34. <div class="w-full text-red-600" v-show="form.owner.msg" >
  35. {{form.owner.msg}}
  36. </div>
  37. </div>
  38. </div>
  39. <div class="w-full px-1.5 mt-3.5 flex">
  40. <div class="w-4/12 flex items-center u px-1 "><p class="w-full text-justify">登陆密码</p> </div>
  41. <div class="w-8/12">
  42. <a-input-password placeholder="登陆密码" v-model="form.password.val" @focus="form.password.msg=''" @blur="checkFormItem('password')"></a-input-password>
  43. <div class="w-full text-red-600" v-show="form.password.msg" >
  44. {{form.password.msg}}
  45. </div>
  46. </div>
  47. </div>
  48. <div class="w-full px-1.5 mt-3.5 flex">
  49. <div class="w-4/12 u px-1 pt-1.5"><p class="w-full text-justify">验证码</p> </div>
  50. <div class="w-8/12">
  51. <a-input
  52. class="w-full"
  53. placeholder="验证码,忽略大小写"
  54. @keydown.enter="submitHandle"
  55. v-model="form.captcha.val"
  56. @focus="form.captcha.msg=''"
  57. @blur="checkFormItem('captcha')"
  58. />
  59. <div class="w-full text-red-600" v-show="form.captcha.msg" >
  60. {{form.captcha.msg}}
  61. </div>
  62. <captcha class="w-full h-24 overflow-hidden mt-1.5 rounded" ref="captchaImg" captcha-url="/api/captcha/"></captcha>
  63. </div>
  64. </div>
  65. <div class="w-full">
  66. <div class="px-2">
  67. <light-button @click.native="submitHandle" >登陆</light-button>
  68. </div>
  69. </div>
  70. <div class="border-t px-2 ">
  71. <span class="mr-4 text-blue-300" >
  72. <a href="/">备案号</a>
  73. </span>
  74. <a href="/">首页</a>
  75. </div>
  76. </div>
  77. </div>
  78. <div class="w-1/12 h-full hidden md:flex bg-gray-800 opacity-30"></div>
  79. </div>
  80. </template>
  81. <script>
  82. import Vue from 'vue'
  83. // 引用ant-design-vue的input组件
  84. import antInput from 'ant-design-vue/lib/input';
  85. import 'ant-design-vue/dist/antd.css'
  86. // import apis from '@/apis/apis'
  87. import handle from "~/until/handle";
  88. import business from "~/until/business";
  89. import fieldIsAllow from "~/until/fieldIsAllow"
  90. import userData from "~/until/saves/users";
  91. import Captcha from "~/components/public/captcha";
  92. import LightButton from "~/components/public/lightButton";
  93. import {login_types} from "../../store/login";
  94. Vue.use(antInput);
  95. export default {
  96. name: 'App',
  97. components: {
  98. LightButton,
  99. Captcha,
  100. },
  101. async asyncData(ctx) {
  102. },
  103. beforeCreate() {
  104. // 修改页面title nuxt
  105. // this.$store.commit('setPageTitle', '合方圆管理平台');
  106. },
  107. data(){
  108. return {
  109. test: 'test',
  110. // 是否为固定
  111. labelCol: { span: 4 },
  112. wrapperCol: { span: 16 },
  113. form: {
  114. owner: {
  115. val:'',
  116. msg: '',
  117. state: 0,
  118. },
  119. password: {
  120. val:'',
  121. msg: '',
  122. state: 0,
  123. },
  124. captcha: {
  125. val:'',
  126. msg: '',
  127. state: 0,
  128. },
  129. },
  130. // 要切换的url地址
  131. jumpUrl: '/',
  132. }
  133. },
  134. computed:{
  135. captcha () {
  136. return this.$store.state.login.captcha
  137. }
  138. },
  139. beforeMount(){
  140. },
  141. mounted(){
  142. let url = window.sessionStorage.getItem('lastUrl');
  143. if(url){
  144. this.jumpUrl = url;
  145. }
  146. },
  147. methods:{
  148. setCaptcha(captcha){
  149. // this.$store..commit(login_types.mutations.SET_CAPTCHA, captcha);
  150. this.$store.commit('login/'+login_types.mutations.SET_CAPTCHA, captcha);
  151. },
  152. resetForm(){
  153. this.form.owner = '';
  154. this.form.password = '';
  155. this.form.captcha = '';
  156. },
  157. checkFormItem(field){
  158. console.log(field);
  159. this.setCaptcha(this.form[field].val);
  160. if (field){
  161. this.form[field].msg = fieldIsAllow({
  162. [field]:this.form[field].val,
  163. })
  164. }else{
  165. let r = true;
  166. for (const fieldKey in this.form) {
  167. this.form[fieldKey].msg = fieldIsAllow({
  168. [fieldKey]:this.form[fieldKey].val,
  169. })
  170. if (this.form[fieldKey].msg){
  171. r = false;
  172. }
  173. }
  174. return r
  175. }
  176. },
  177. async submitHandle(e){
  178. if(!this.checkFormItem()){
  179. return this.$message.warn("请检查登陆参数");
  180. }
  181. let owner = this.form.owner.val;
  182. let passwd = this.form.password.val;
  183. let captcha = this.form.captcha.val;
  184. // apis.user.login(owner,passwd,captcha)
  185. let [err,response] = await handle(this.$axios.post('/api/user/login',{
  186. owner,
  187. passwd,
  188. captcha,
  189. }));
  190. let rcodeMean = business.checkResponseRcode(response,err);
  191. if(rcodeMean.ok){
  192. let res = rcodeMean.res;
  193. // 登陆成功
  194. this.$message.success(`登陆成功,稍后进行页面跳转`);
  195. console.log(res);
  196. userData.setUser(res.data)
  197. this.countDown();
  198. }else{
  199. // 登陆失败
  200. this.$message[rcodeMean.type](rcodeMean.msg);
  201. // 更新验证码
  202. this.$refs.captchaImg.refreshCaptcha();
  203. this.form.captcha.val = '';
  204. }
  205. },
  206. // 登陆成功
  207. countDown() {
  208. let secondsToGo = 5,that=this;
  209. const modal = this.$success({
  210. title: '登陆成功',
  211. content: `将在${secondsToGo} 秒后自动跳转页面.`,
  212. okText:'立即跳转',
  213. onOk() {
  214. window.location.href=that.jumpUrl;
  215. },
  216. });
  217. const interval = setInterval(() => {
  218. secondsToGo -= 1;
  219. modal.update({
  220. content: `将在${secondsToGo} 秒后自动跳转页面.`,
  221. });
  222. }, 1000);
  223. setTimeout(() => {
  224. window.location.href=that.jumpUrl;
  225. }, 1+(secondsToGo * 1000));
  226. },
  227. }
  228. }
  229. </script>
  230. <style>
  231. html,body{
  232. margin: 0;
  233. padding: 0;
  234. height: 100vh;
  235. font-family: sans-serif;
  236. }
  237. .bgImg{
  238. background: url("/image/big/bg.png") center no-repeat;
  239. }
  240. #app {
  241. font-family: Avenir, Helvetica, Arial, sans-serif;
  242. -webkit-font-smoothing: antialiased;
  243. -moz-osx-font-smoothing: grayscale;
  244. text-align: center;
  245. color: #2c3e50;
  246. width: 100vw;
  247. height: 100vh;
  248. }
  249. .login-box{
  250. transform: translate(-50%, -0%);
  251. background: rgba(0,0,0,.4);
  252. box-sizing: border-box;
  253. box-shadow: 0 15px 25px rgba(0,0,0,.6);
  254. border-radius: 10px;
  255. /*filter: blur(5px);*/
  256. transition: all .7s;
  257. }
  258. .blur{
  259. filter: blur(5px);
  260. box-shadow: 0 15px 25px rgba(0,0,0,.6);
  261. }
  262. .login-box h2 {
  263. margin: 0 0 30px;
  264. padding: 0;
  265. color: #fff;
  266. text-align: center;
  267. }
  268. .u{
  269. text-align: justify;
  270. text-align-last:justify;
  271. }
  272. .lbx{
  273. animation: rounded-anim1 15s linear infinite;
  274. }
  275. .map{
  276. animation: rounded-anim1 60s linear infinite;
  277. }
  278. .jt{
  279. animation: rounded-anim1 15s reverse infinite ;
  280. }
  281. .rounded-img{
  282. animation: rounded-anim1 5s reverse infinite ;
  283. }
  284. @keyframes rounded-anim1 {
  285. 0% {
  286. transform:rotate(0deg);
  287. }
  288. 100% {
  289. transform:rotate(360deg);
  290. }
  291. }
  292. </style>