Kaynağa Gözat

登录验证

Zhangbw 2 ay önce
ebeveyn
işleme
9303ef3d71

+ 3 - 0
.env.development

@@ -0,0 +1,3 @@
+# 开发环境配置
+VITE_APP_PORT=3000
+VITE_API_BASE_URL=/api

+ 3 - 0
.env.production

@@ -0,0 +1,3 @@
+# 生产环境配置
+# 部署时修改为实际的服务器地址
+VITE_API_BASE_URL=http://yp1.yingpaipay.com:9014/api

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
dist/assets/index-Bmqqad_0.css


Dosya farkı çok büyük olduğundan ihmal edildi
+ 4 - 0
dist/assets/index-DcDdCnYV.js


+ 18 - 0
dist/index.html

@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>智能客服</title>
+  <style>
+    * { margin: 0; padding: 0; box-sizing: border-box; }
+    html, body { width: 100%; height: 100%; overflow: hidden; }
+    body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; }
+  </style>
+  <script type="module" crossorigin src="/assets/index-DcDdCnYV.js"></script>
+  <link rel="stylesheet" crossorigin href="/assets/index-Bmqqad_0.css">
+</head>
+<body>
+  <div id="app"></div>
+</body>
+</html>

+ 3 - 2
package.json

@@ -3,8 +3,9 @@
   "version": "1.0.0",
   "type": "module",
   "scripts": {
-    "dev": "vite",
-    "build": "vite build"
+    "dev": "vite --mode development",
+    "prod": "vite --mode production",
+    "build": "vite build --mode production"
   },
   "dependencies": {
     "@element-plus/icons-vue": "^2.3.2",

+ 28 - 2
src/App.vue

@@ -7,14 +7,40 @@
 import { ref, onMounted } from 'vue'
 import Login from './Login.vue'
 import CustomerService from './CustomerService.vue'
+import { API_ENDPOINTS } from './config/api'
 
 const isLoggedIn = ref(false)
 
-onMounted(() => {
+onMounted(async () => {
   // 检查是否已登录
   const token = localStorage.getItem('talk_token')
   if (token) {
-    isLoggedIn.value = true
+    // 验证 token 是否有效
+    try {
+      const response = await fetch(API_ENDPOINTS.userInfo, {
+        headers: {
+          'Authorization': `Bearer ${token}`,
+          'clientid': '812b745b34558590c92e6f13fe8b716b'
+        }
+      })
+
+      if (response.ok) {
+        // Token 有效,显示对话界面
+        isLoggedIn.value = true
+      } else {
+        // Token 无效,清除并显示登录页
+        console.log('Token 已过期,请重新登录')
+        localStorage.removeItem('talk_token')
+        localStorage.removeItem('talk_user')
+        isLoggedIn.value = false
+      }
+    } catch (error) {
+      // 网络错误或其他异常,清除 token 并显示登录页
+      console.error('验证 token 失败:', error)
+      localStorage.removeItem('talk_token')
+      localStorage.removeItem('talk_user')
+      isLoggedIn.value = false
+    }
   }
 })
 

+ 8 - 7
src/CustomerService.vue

@@ -194,6 +194,7 @@ import { ArrowUp, ArrowDown, Microphone, PhoneFilled, ChatDotRound, Mute } from
 import { useVoiceRecognition } from './composables/useVoiceRecognition.js'
 import { useStreamChat } from './composables/useStreamChat.js'
 import { ElMessage } from 'element-plus'
+import { API_ENDPOINTS } from './config/api.js'
 
 // 获取请求头(包含token)
 const getHeaders = () => {
@@ -453,7 +454,7 @@ watch(showChat, async (newVal) => {
     if (selectedAgent.value && currentConversationId.value) {
       try {
         const sessionId = currentConversationId.value
-        await fetch(`http://localhost:8080/talk/agent/${selectedAgent.value}/hangup`, {
+        await fetch(API_ENDPOINTS.agentHangup(selectedAgent.value), {
           method: 'POST',
           headers: getHeaders(),
           body: JSON.stringify({
@@ -581,7 +582,7 @@ const selectedAgent = ref(null)
 // 获取发言人字典列表
 const fetchTtsVcnList = async () => {
   try {
-    const response = await fetch('http://localhost:8080/talk/dict/ttsVcn', {
+    const response = await fetch(API_ENDPOINTS.ttsVcn, {
       headers: getHeaders()
     })
     const data = await response.json()
@@ -594,7 +595,7 @@ const fetchTtsVcnList = async () => {
 // 获取客服列表
 const fetchAgents = async (silent = false) => {
   try {
-    const response = await fetch('http://localhost:8080/talk/agent/list', {
+    const response = await fetch(API_ENDPOINTS.agentList, {
       headers: getHeaders()
     })
     const result = await response.json()
@@ -657,7 +658,7 @@ const stopAgentRefresh = () => {
 const handleLogout = async () => {
   try {
     // 调用后端退出登录接口
-    await fetch('http://localhost:8080/talk/auth/logout', {
+    await fetch(API_ENDPOINTS.logout, {
       method: 'POST',
       headers: getHeaders()
     })
@@ -695,7 +696,7 @@ const getAvatarUrl = (avatarUrl) => {
   if (avatarUrl.startsWith('http://') || avatarUrl.startsWith('https://')) {
     return avatarUrl
   }
-  return 'http://localhost:8080' + avatarUrl
+  return API_ENDPOINTS.avatar(avatarUrl)
 }
 
 // 开始对话
@@ -723,7 +724,7 @@ const startChat = async () => {
 
   try {
     // 调用对话前端的开始对话接口(带并发控制)
-    const response = await fetch(`http://localhost:8080/talk/agent/${selectedAgent.value}/start`, {
+    const response = await fetch(API_ENDPOINTS.agentStart(selectedAgent.value), {
       method: 'POST',
       headers: getHeaders()
     })
@@ -747,7 +748,7 @@ const startChat = async () => {
     }
 
     // 更新客服的TTS配置
-    await fetch(`http://localhost:8080/talk/agent/${selectedAgent.value}`, {
+    await fetch(API_ENDPOINTS.agentUpdate(selectedAgent.value), {
       method: 'PUT',
       headers: getHeaders(),
       body: JSON.stringify({

+ 2 - 1
src/Login.vue

@@ -32,6 +32,7 @@
 
 <script setup>
 import { ref } from 'vue'
+import { API_ENDPOINTS } from './config/api'
 
 const emit = defineEmits(['login-success'])
 
@@ -48,7 +49,7 @@ const handleLogin = async () => {
   errorMessage.value = ''
 
   try {
-    const response = await fetch('http://localhost:8080/talk/auth/login', {
+    const response = await fetch(API_ENDPOINTS.login, {
       method: 'POST',
       headers: {
         'Content-Type': 'application/json',

+ 2 - 1
src/composables/useStreamChat.js

@@ -1,4 +1,5 @@
 import { ref } from 'vue'
+import { API_ENDPOINTS } from '../config/api.js'
 
 export function useStreamChat() {
   const displayText = ref('')
@@ -107,7 +108,7 @@ export function useStreamChat() {
         requestId: thisRequestId  // 发送requestId到后端
       }
 
-      fetch('http://localhost:8080/talk/message/stream', {
+      fetch(API_ENDPOINTS.messageStream, {
         method: 'POST',
         headers: {
           'Content-Type': 'application/json',

+ 2 - 1
src/composables/useVoiceRecognition.js

@@ -1,5 +1,6 @@
 import { ref, onUnmounted } from 'vue'
 import CryptoJS from 'crypto-js'
+import { API_ENDPOINTS } from '../config/api.js'
 
 // 科大讯飞配置(从后端获取)
 let XFYUN_CONFIG = {
@@ -13,7 +14,7 @@ let XFYUN_CONFIG = {
 const loadConfig = async () => {
   try {
     const token = localStorage.getItem('talk_token')
-    const response = await fetch('http://localhost:8080/talk/config/xunfei', {
+    const response = await fetch(API_ENDPOINTS.xunfeiConfig, {
       headers: {
         'Authorization': token ? `Bearer ${token}` : '',
         'clientid': 'talk-web'

+ 28 - 0
src/config/api.js

@@ -0,0 +1,28 @@
+// API 基础地址配置
+const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8080'
+
+// API 端点
+export const API_ENDPOINTS = {
+  // 认证相关
+  login: `${API_BASE_URL}/talk/auth/login`,
+  logout: `${API_BASE_URL}/talk/auth/logout`,
+  userInfo: `${API_BASE_URL}/talk/auth/userInfo`,
+
+  // 客服相关
+  agentList: `${API_BASE_URL}/talk/agent/list`,
+  agentUpdate: (id) => `${API_BASE_URL}/talk/agent/${id}`,
+  agentStart: (id) => `${API_BASE_URL}/talk/agent/${id}/start`,
+  agentHangup: (id) => `${API_BASE_URL}/talk/agent/${id}/hangup`,
+
+  // 对话相关
+  messageStream: `${API_BASE_URL}/talk/message/stream`,
+
+  // 字典相关
+  ttsVcn: `${API_BASE_URL}/talk/dict/ttsVcn`,
+
+  // 配置相关
+  xunfeiConfig: `${API_BASE_URL}/talk/config/xunfei`,
+
+  // 头像地址
+  avatar: (url) => `${API_BASE_URL}${url}`
+}

+ 20 - 3
vite.config.js

@@ -1,6 +1,23 @@
-import { defineConfig } from 'vite'
+import { defineConfig, loadEnv } from 'vite'
 import vue from '@vitejs/plugin-vue'
 
-export default defineConfig({
-  plugins: [vue()]
+export default defineConfig(({ mode }) => {
+  const env = loadEnv(mode, process.cwd())
+
+  return {
+    plugins: [vue()],
+    server: {
+      host: '0.0.0.0',
+      port: Number(env.VITE_APP_PORT) || 3000,
+      open: true,
+      proxy: {
+        '/api': {
+          target: 'http://localhost:8080',
+          changeOrigin: true,
+          ws: true,
+          rewrite: (path) => path.replace(/^\/api/, '')
+        }
+      }
+    }
+  }
 })

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor