Browse Source

对话前端样式修改
增加手机号输入框

Zhangbw 2 tháng trước cách đây
mục cha
commit
ee1a04f13b
6 tập tin đã thay đổi với 137 bổ sung73 xóa
  1. 2 1
      .claude/settings.local.json
  2. 1 1
      .env.production
  3. 0 0
      dist/assets/index-BUAcQOf0.js
  4. 1 1
      dist/index.html
  5. 132 69
      src/CustomerService.vue
  6. 1 1
      src/config/api.js

+ 2 - 1
.claude/settings.local.json

@@ -9,7 +9,8 @@
       "Read(//d/program/**)",
       "Bash(tree:*)",
       "Bash(git checkout:*)",
-      "Bash(curl:*)"
+      "Bash(curl:*)",
+      "Bash(test:*)"
     ],
     "additionalDirectories": [
       "d:\\program\\AI-TALK\\ruoyi-modules\\yp-talk",

+ 1 - 1
.env.production

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

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
dist/assets/index-BUAcQOf0.js


+ 1 - 1
dist/index.html

@@ -9,7 +9,7 @@
     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>
+  <script type="module" crossorigin src="/assets/index-BUAcQOf0.js"></script>
   <link rel="stylesheet" crossorigin href="/assets/index-Bmqqad_0.css">
 </head>
 <body>

+ 132 - 69
src/CustomerService.vue

@@ -110,20 +110,21 @@
                   <div class="agent-name">{{ agent.name }}</div>
                 </div>
               </div>
-              <div class="pagination-dots" v-if="totalPages > 1">
-                <span
-                  v-for="page in totalPages"
-                  :key="page"
-                  class="dot"
-                  :class="{ active: currentPage === page - 1 }"
-                  @click="currentPage = page - 1"
-                ></span>
-              </div>
             </div>
             <div class="agents-footer">
-              <el-button type="primary" round size="large" class="start-btn" @click="startChat">
-                开始对话
-              </el-button>
+              <div class="footer-input">
+                <el-input
+                  v-model="customerPhone"
+                  placeholder="请输入客户电话号码(可选)"
+                  class="customer-phone-input"
+                  clearable
+                />
+              </div>
+              <div class="footer-actions">
+                <el-button type="primary" round size="large" class="start-btn" @click="startChat">
+                  开始对话
+                </el-button>
+              </div>
             </div>
           </main>
 
@@ -214,6 +215,7 @@ const basicExpanded = ref(true)
 const otherExpanded = ref(false)
 const currentPage = ref(0)
 const chatContent = ref(null)
+const customerPhone = ref('')
 
 // 语音识别
 const { isRecording, currentTranscription, tempTranscription, startRecording, stopRecording } = useVoiceRecognition()
@@ -595,44 +597,47 @@ const fetchTtsVcnList = async () => {
 // 获取客服列表
 const fetchAgents = async (silent = false) => {
   try {
-    const response = await fetch(API_ENDPOINTS.agentList, {
+    const response = await fetch(API_ENDPOINTS.agentMy, {
       headers: getHeaders()
     })
     const result = await response.json()
-    if (result.code === 200 && result.rows) {
+    if (result.code === 200 && result.data) {
+      const agent = result.data
       // 只显示状态为0(空闲中)或2(工作中)的客服
-      const previousSelectedAgent = selectedAgent.value
-      agents.value = result.rows
-        .filter(agent => agent.status === '0' || agent.status === '2')
-        .map(agent => ({
-        id: agent.id,
-        name: agent.name,
-        gender: agent.gender === '0' ? 'male' : 'female',
-        avatarUrl: agent.avatarUrl,
-        greetingMessage: agent.greetingMessage,
-        ttsVcn: agent.ttsVcn,
-        ttsSpeed: agent.ttsSpeed,
-        ttsPitch: agent.ttsPitch,
-        ttsVolume: agent.ttsVolume,
-        ttsBgs: agent.ttsBgs,
-        status: agent.status
-      }))
-
-      // 如果之前选中的客服不在列表中,清除选择
-      if (previousSelectedAgent && !agents.value.find(a => a.id === previousSelectedAgent)) {
+      if (agent.status === '0' || agent.status === '2') {
+        agents.value = [{
+          id: agent.id,
+          name: agent.name,
+          gender: agent.gender === '0' ? 'male' : 'female',
+          avatarUrl: agent.avatarUrl,
+          greetingMessage: agent.greetingMessage,
+          ttsVcn: agent.ttsVcn,
+          ttsSpeed: agent.ttsSpeed,
+          ttsPitch: agent.ttsPitch,
+          ttsVolume: agent.ttsVolume,
+          ttsBgs: agent.ttsBgs,
+          status: agent.status
+        }]
+        selectedAgent.value = agent.id
+        console.log('自动匹配到当前用户的客服:', agent.name)
+      } else {
+        agents.value = []
         selectedAgent.value = null
+        if (!silent) {
+          ElMessage.warning('您的客服当前不可用')
+        }
       }
-
-      // 如果没有选中客服且列表不为空,选择第一个可用的客服
-      if (!selectedAgent.value && agents.value.length > 0) {
-        const availableAgent = agents.value.find(a => a.status === '0')
-        selectedAgent.value = availableAgent ? availableAgent.id : agents.value[0].id
+    } else {
+      agents.value = []
+      selectedAgent.value = null
+      if (!silent) {
+        ElMessage.warning('未找到对应的客服')
       }
     }
   } catch (error) {
-    console.error('获取客服列表失败:', error)
+    console.error('获取客服失败:', error)
     if (!silent) {
-      ElMessage.error('获取客服列表失败')
+      ElMessage.error('获取客服失败')
     }
   }
 }
@@ -726,7 +731,10 @@ const startChat = async () => {
     // 调用对话前端的开始对话接口(带并发控制)
     const response = await fetch(API_ENDPOINTS.agentStart(selectedAgent.value), {
       method: 'POST',
-      headers: getHeaders()
+      headers: getHeaders(),
+      body: JSON.stringify({
+        customerPhone: customerPhone.value
+      })
     })
 
     const result = await response.json()
@@ -994,7 +1002,7 @@ const handleWheel = (e) => {
   flex-direction: column;
   align-items: stretch;
   justify-content: flex-start;
-  padding: 0;
+  padding: 20px;
   background: #f9fafb;
   border-radius: 8px;
   height: 100%;
@@ -1016,8 +1024,8 @@ const handleWheel = (e) => {
   display: flex;
   flex-direction: column;
   align-items: center;
-  padding-top: 36px;
-  padding-bottom: 0;
+  justify-content: flex-start;
+  padding: 72px 40px 28px;
   overflow: visible;
   min-height: 0;
   position: relative;
@@ -1035,32 +1043,46 @@ const handleWheel = (e) => {
   display: flex;
   flex-direction: column;
   align-items: center;
-  padding: 0;
+  width: 100%;
+  max-width: 520px;
+  margin-left: auto;
+  margin-right: auto;
+  gap: 14px;
   flex-shrink: 0;
-  position: absolute;
-  left: 50%;
-  transform: translateX(-50%);
-  top: calc(36px + 220px + 16px + 220px + 24px + 40px);
+  margin-top: 0;
+}
+
+.footer-input {
+  width: 100%;
+  padding: 0;
+  background: transparent;
+  border: none;
+  border-radius: 0;
+  box-shadow: none;
+}
+
+.footer-actions {
+  width: 100%;
+  display: flex;
+  justify-content: center;
 }
 
 .agents-list {
-  display: grid;
-  grid-template-columns: repeat(3, 220px);
-  gap: 16px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
   width: 100%;
   max-width: 100%;
-  padding: 0 12px;
-  margin-top: 0;
-  margin-bottom: 0;
-  justify-content: center;
+  padding: 0 20px;
+  margin-bottom: 28px;
 }
 
 .agent-card {
-  width: 220px;
-  height: 220px;
-  padding: 10px;
+  width: 280px;
+  height: 280px;
+  padding: 20px;
   border: 2px solid #e5e7eb;
-  border-radius: 12px;
+  border-radius: 16px;
   text-align: center;
   cursor: pointer;
   position: relative;
@@ -1171,18 +1193,18 @@ const handleWheel = (e) => {
 }
 
 .avatar {
-  width: 120px;
-  height: 120px;
+  width: 150px;
+  height: 150px;
   border-radius: 50%;
-  margin: 20px auto 12px;
+  margin: 20px auto 16px;
   border: 3px solid #e5e7eb;
 }
 
 .avatar-img {
-  width: 120px;
-  height: 120px;
+  width: 150px;
+  height: 150px;
   border-radius: 50%;
-  margin: 20px auto 12px;
+  margin: 20px auto 16px;
   object-fit: cover;
   border: 3px solid #e5e7eb;
   background: #f9fafb;
@@ -1249,17 +1271,58 @@ const handleWheel = (e) => {
 }
 
 .agent-name {
-  font-size: 14px;
+  font-size: 18px;
   color: #1f2937;
   font-weight: 600;
   margin-top: 8px;
 }
 
 .start-btn {
+  width: 100%;
+  height: 44px;
   font-size: 16px;
-  padding: 12px 48px;
+  font-weight: 600;
+  padding: 0 18px;
   align-self: center;
-  margin: 0;
+  border: none;
+  background: linear-gradient(135deg, #3b82f6, #2563eb);
+  box-shadow: 0 10px 18px rgba(37, 99, 235, 0.25);
+  transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
+}
+
+.start-btn:hover {
+  filter: brightness(1.02);
+  transform: translateY(-1px);
+  box-shadow: 0 14px 24px rgba(37, 99, 235, 0.32);
+}
+
+.start-btn:active {
+  transform: translateY(0);
+  box-shadow: 0 10px 18px rgba(37, 99, 235, 0.25);
+}
+
+.customer-phone-input {
+  width: 100%;
+  max-width: 100%;
+}
+
+.customer-phone-input :deep(.el-input__wrapper) {
+  height: 44px;
+  border-radius: 9999px;
+  padding: 0 16px;
+  border: 1px solid rgba(229, 231, 235, 1);
+  background: rgba(255, 255, 255, 0.98);
+  box-shadow: 0 6px 16px rgba(15, 23, 42, 0.06);
+  transition: box-shadow 0.15s ease, border-color 0.15s ease;
+}
+
+.customer-phone-input :deep(.el-input__inner) {
+  font-size: 14px;
+}
+
+.customer-phone-input :deep(.el-input__wrapper.is-focus) {
+  border-color: rgba(59, 130, 246, 0.9);
+  box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.16), 0 10px 20px rgba(37, 99, 235, 0.10);
 }
 
 .pagination-dots {

+ 1 - 1
src/config/api.js

@@ -9,7 +9,7 @@ export const API_ENDPOINTS = {
   userInfo: `${API_BASE_URL}/talk/auth/userInfo`,
 
   // 客服相关
-  agentList: `${API_BASE_URL}/talk/agent/list`,
+  agentMy: `${API_BASE_URL}/talk/agent/my`,
   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`,

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác