Login.vue 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  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 { message } from 'ant-design-vue';
  87. import { Modal } from 'ant-design-vue';
  88. // import apis from '@/apis/apis'
  89. import handle from "~/until/handle";
  90. import fieldIsAllow from "~/until/fieldIsAllow"
  91. import Captcha from "~/components/public/captcha";
  92. import LightButton from "~/components/public/lightButton";
  93. import {login_types} from "../../store/login";
  94. import {rCode} from "../../map/rcodeMap_esm";
  95. Vue.use(antInput);
  96. // 引用message组件
  97. Vue.prototype.$message = message;
  98. // 引用modal组件
  99. Vue.prototype.$success = Modal.success;
  100. export default {
  101. name: 'App',
  102. components: {
  103. LightButton,
  104. Captcha,
  105. },
  106. async asyncData(ctx) {
  107. },
  108. beforeCreate() {
  109. // 修改页面title nuxt
  110. // this.$store.commit('setPageTitle', '合方圆管理平台');
  111. },
  112. data(){
  113. return {
  114. test: 'test',
  115. // 是否为固定
  116. labelCol: { span: 4 },
  117. wrapperCol: { span: 16 },
  118. form: {
  119. owner: {
  120. val:'',
  121. msg: '',
  122. state: 0,
  123. },
  124. password: {
  125. val:'',
  126. msg: '',
  127. state: 0,
  128. },
  129. captcha: {
  130. val:'',
  131. msg: '',
  132. state: 0,
  133. },
  134. },
  135. // 要切换的url地址
  136. jumpUrl: '/manger',
  137. }
  138. },
  139. computed:{
  140. captcha () {
  141. return this.$store.state.login.captcha
  142. }
  143. },
  144. beforeMount(){
  145. },
  146. mounted(){
  147. let url = window.sessionStorage.getItem('lastUrl');
  148. if(url){
  149. this.jumpUrl = url;
  150. }
  151. },
  152. methods:{
  153. setCaptcha(captcha){
  154. // this.$store..commit(login_types.mutations.SET_CAPTCHA, captcha);
  155. this.$store.commit('login/'+login_types.mutations.SET_CAPTCHA, captcha);
  156. },
  157. resetForm(){
  158. this.form.owner = '';
  159. this.form.password = '';
  160. this.form.captcha = '';
  161. },
  162. checkFormItem(field){
  163. // console.log(field);
  164. if (field){
  165. this.form[field].msg = fieldIsAllow({
  166. [field]:this.form[field].val,
  167. })
  168. }else{
  169. let r = true;
  170. for (const fieldKey in this.form) {
  171. this.form[fieldKey].msg = fieldIsAllow({
  172. [fieldKey]:this.form[fieldKey].val,
  173. })
  174. if (this.form[fieldKey].msg){
  175. r = false;
  176. }
  177. }
  178. return r
  179. }
  180. },
  181. async submitHandle(e){
  182. if(!this.checkFormItem()){
  183. return this.$message.warn("请检查登陆参数");
  184. }
  185. let owner = this.form.owner.val;
  186. let passwd = this.form.password.val;
  187. let captcha = this.form.captcha.val;
  188. // apis.user.login(owner,passwd,captcha)
  189. let [err,res] = await handle(this.$axios.post('/api/user/login',{
  190. owner,
  191. passwd,
  192. captcha,
  193. }));
  194. this.$refs.captchaImg.refreshCaptcha();
  195. if(err){
  196. console.log(err);
  197. return {};
  198. }
  199. let result = res.data;
  200. if(result.code === rCode.OK){
  201. this.countDown();
  202. }else{
  203. this.$message.error(result.msg);
  204. return {solutions:[]}
  205. }
  206. },
  207. // 登陆成功
  208. countDown() {
  209. let secondsToGo = 5,that=this;
  210. const modal = this.$success({
  211. title: '登陆成功',
  212. content: `将在${secondsToGo} 秒后自动跳转页面.`,
  213. okText:'立即跳转',
  214. onOk() {
  215. window.location.href=that.jumpUrl;
  216. },
  217. });
  218. const interval = setInterval(() => {
  219. secondsToGo -= 1;
  220. modal.update({
  221. content: `将在${secondsToGo} 秒后自动跳转页面.`,
  222. });
  223. }, 1000);
  224. setTimeout(() => {
  225. window.location.href=that.jumpUrl;
  226. }, 1+(secondsToGo * 1000));
  227. },
  228. }
  229. }
  230. </script>
  231. <style>
  232. html,body{
  233. margin: 0;
  234. padding: 0;
  235. height: 100vh;
  236. font-family: sans-serif;
  237. }
  238. .bgImg{
  239. background: url("/image/big/bg.png") center no-repeat;
  240. }
  241. #app {
  242. font-family: Avenir, Helvetica, Arial, sans-serif;
  243. -webkit-font-smoothing: antialiased;
  244. -moz-osx-font-smoothing: grayscale;
  245. text-align: center;
  246. color: #2c3e50;
  247. width: 100vw;
  248. height: 100vh;
  249. }
  250. .login-box{
  251. transform: translate(-50%, -0%);
  252. background: rgba(0,0,0,.4);
  253. box-sizing: border-box;
  254. box-shadow: 0 15px 25px rgba(0,0,0,.6);
  255. border-radius: 10px;
  256. /*filter: blur(5px);*/
  257. transition: all .7s;
  258. }
  259. .blur{
  260. filter: blur(5px);
  261. box-shadow: 0 15px 25px rgba(0,0,0,.6);
  262. }
  263. .login-box h2 {
  264. margin: 0 0 30px;
  265. padding: 0;
  266. color: #fff;
  267. text-align: center;
  268. }
  269. .u{
  270. text-align: justify;
  271. text-align-last:justify;
  272. }
  273. .lbx{
  274. animation: rounded-anim1 15s linear infinite;
  275. }
  276. .map{
  277. animation: rounded-anim1 60s linear infinite;
  278. }
  279. .jt{
  280. animation: rounded-anim1 15s reverse infinite ;
  281. }
  282. .rounded-img{
  283. animation: rounded-anim1 5s reverse infinite ;
  284. }
  285. @keyframes rounded-anim1 {
  286. 0% {
  287. transform:rotate(0deg);
  288. }
  289. 100% {
  290. transform:rotate(360deg);
  291. }
  292. }
  293. </style>