From f7131667350cfa278c935c7c628fcf3d15f00d03 Mon Sep 17 00:00:00 2001
From: xyc <jc_xiong@hotmail.com>
Date: 星期四, 27 八月 2026 14:53:42 +0800
Subject: [PATCH] chore: 同事开发结果(郑玉洁 2026-08-27):城市客运/公路旅客/投资/能耗模块、报表Tab工作台、目录导入、操作日志、DB登录校验等(不含其独立实现的 ShapeCaptcha 验证码)
---
traffic-audit-web/src/views/Login.vue | 83 ++++++++++++++++++++++++++++++++++++++---
1 files changed, 76 insertions(+), 7 deletions(-)
diff --git a/traffic-audit-web/src/views/Login.vue b/traffic-audit-web/src/views/Login.vue
index 4993005..e081d22 100644
--- a/traffic-audit-web/src/views/Login.vue
+++ b/traffic-audit-web/src/views/Login.vue
@@ -1,4 +1,4 @@
-锘�<template>
+<template>
<div class="login-container">
<el-card class="login-card">
<h2>浜ら�氱粺璁℃姤琛ㄥ鏍哥郴缁�</h2>
@@ -10,30 +10,97 @@
<el-input v-model="form.password" type="password" placeholder="瀵嗙爜" @keyup.enter.native="login"></el-input>
</el-form-item>
<el-form-item>
- <el-button type="primary" @click="login" style="width:100%">鐧� 褰�</el-button>
+ <div class="captcha-wrap" v-loading="captchaLoading">
+ <shape-captcha v-if="captcha.shapes.length"
+ :shapes="captcha.shapes"
+ :instruction="captcha.instruction"
+ @complete="onCaptchaComplete"
+ @refresh="loadCaptcha"
+ @reset="onCaptchaReset"></shape-captcha>
+ <div v-else class="captcha-empty">姝e湪鍔犺浇楠岃瘉鐮佲��</div>
+ </div>
+ </el-form-item>
+ <el-form-item>
+ <el-button type="primary" @click="login" :loading="loading" style="width:100%">鐧� 褰�</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</template>
<script>
+import api from '@/api'
+import ShapeCaptcha from '@/components/ShapeCaptcha.vue'
export default {
name: 'Login',
+ components: { ShapeCaptcha },
data() {
return {
form: { username: '', password: '' },
+ loading: false,
+ captchaLoading: false,
+ captcha: { captchaId: '', shapes: [], instruction: '' },
+ seq: [],
rules: {
username: [{ required: true, message: '璇疯緭鍏ョ敤鎴峰悕', trigger: 'blur' }],
password: [{ required: true, message: '璇疯緭鍏ュ瘑鐮�', trigger: 'blur' }]
}
}
},
+ created() { this.loadCaptcha() },
methods: {
+ loadCaptcha() {
+ this.captchaLoading = true
+ this.seq = []
+ this.captcha = { captchaId: '', shapes: [], instruction: '' }
+ api.get('/captcha/shape')
+ .then(res => {
+ const d = res && res.data
+ if (!d || !d.captchaId) { this.$message.error((res && res.message) || '楠岃瘉鐮佸姞杞藉け璐�'); return }
+ this.captcha = d
+ })
+ .catch(err => {
+ const d = err && err.response && err.response.data
+ this.$message.error((d && d.message) || '楠岃瘉鐮佸姞杞藉け璐ワ紝璇风◢鍚庨噸璇�')
+ })
+ .finally(() => { this.captchaLoading = false })
+ },
+ onCaptchaComplete(sequence) { this.seq = sequence || [] },
+ onCaptchaReset() { this.seq = [] },
login() {
this.$refs.form.validate(valid => {
- if (valid) {
- this.$router.push('/dashboard')
+ if (!valid) return
+ if (!this.captcha.captchaId) { this.$message.warning('楠岃瘉鐮佸姞杞戒腑锛岃绋嶅��'); return }
+ if (!this.seq || this.seq.length < this.captcha.total) {
+ this.$message.warning('璇峰厛鎸夋彁绀洪『搴忕偣鍑婚獙璇佺爜鍥惧舰')
+ return
}
+ this.loading = true
+ api.post('/captcha/verify', { captchaId: this.captcha.captchaId, sequence: this.seq })
+ .then(res => {
+ if (!res || res.code !== 200) {
+ this.$message.error((res && res.message) || '楠岃瘉鐮佹牎楠屽け璐�')
+ this.loadCaptcha()
+ return
+ }
+ return api.post('/auth/login', this.form)
+ })
+ .then(res => {
+ if (!res) return
+ const d = res.data
+ if (!d || !d.token) { this.$message.error((res && res.message) || '鐧诲綍澶辫触'); return }
+ localStorage.setItem('token', d.token)
+ localStorage.setItem('username', d.username || '')
+ localStorage.setItem('realName', d.realName || '')
+ localStorage.setItem('modules', d.modules || '')
+ this.$message.success('娆㈣繋锛�' + (d.realName || d.username))
+ this.$router.push('/dashboard')
+ })
+ .catch(err => {
+ const d = err && err.response && err.response.data
+ this.$message.error((d && d.message) || '鐧诲綍澶辫触锛氳妫�鏌ョ敤鎴峰悕鎴栧瘑鐮�')
+ this.loadCaptcha()
+ })
+ .finally(() => { this.loading = false })
})
}
}
@@ -41,6 +108,8 @@
</script>
<style scoped>
.login-container { display: flex; justify-content: center; align-items: center; height: 100vh; background: #f0f2f5; }
-.login-card { width: 400px; }
-.login-card h2 { text-align: center; margin-bottom: 30px; }
-</style>
+.login-card { width: 420px; }
+.login-card h2 { text-align: center; margin-bottom: 20px; }
+.captcha-wrap { min-height: 168px; }
+.captcha-empty { display: flex; justify-content: center; align-items: center; height: 168px; color: #909399; font-size: 13px; }
+</style>
\ No newline at end of file
--
Gitblit v1.9.1