瀏覽代碼

龙虾模拟对话

lk 1 周之前
父節點
當前提交
bb695b2525
共有 2 個文件被更改,包括 225 次插入3 次删除
  1. 8 0
      src/api/company/workflowLobster.js
  2. 217 3
      src/views/company/workflowLobster/index.vue

+ 8 - 0
src/api/company/workflowLobster.js

@@ -81,3 +81,11 @@ export function confirmGenerateResultEdited(recordId, data) {
     data
   })
 }
+
+export function simulateWorkflow(data) {
+  return request({
+    url: '/workflow/simulate',
+    method: 'post',
+    data
+  })
+}

+ 217 - 3
src/views/company/workflowLobster/index.vue

@@ -58,11 +58,12 @@
         <el-table-column prop="industryType" label="行业类型" width="110" />
         <el-table-column prop="status" label="状态" width="80" />
         <el-table-column prop="createTime" label="创建时间" width="160" />
-        <el-table-column label="操作" width="220" fixed="right">
+        <el-table-column label="操作" width="280" fixed="right">
           <template slot-scope="scope">
             <el-button type="text" @click="handlePreview(scope.row)">预览</el-button>
             <el-button type="text" @click="handleEditTemplate(scope.row)">编辑</el-button>
             <el-button type="text" @click="handleVisual(scope.row)">流程图</el-button>
+            <el-button type="text" @click="handleSimulate(scope.row)">模拟</el-button>
             <el-button type="text" style="color:#f56c6c" @click="handleDeleteTemplate(scope.row)">删除</el-button>
           </template>
         </el-table-column>
@@ -92,6 +93,53 @@
         <el-button v-if="templateDialogMode === 'edit'" type="primary" :loading="templateSaving" @click="submitTemplateEdit">保存修改</el-button>
       </div>
     </el-dialog>
+
+    <el-dialog title="模拟对话" :visible.sync="simulateDialogVisible" width="700px" :close-on-click-modal="false" @closed="handleSimulateDialogClosed">
+      <div class="simulate-chat-container">
+        <div class="simulate-chat-messages" ref="simulateChatMessages">
+          <div v-if="simulateMessages.length === 0" class="simulate-chat-empty">
+            <i class="el-icon-chat-dot-round" style="font-size: 48px; color: #c0c4cc;" />
+            <p>开始模拟对话,输入内容后点击发送</p>
+          </div>
+          <div
+            v-for="(msg, index) in simulateMessages"
+            :key="index"
+            :class="['simulate-chat-message', msg.role === 'user' ? 'simulate-chat-user' : 'simulate-chat-ai']"
+          >
+            <div class="simulate-chat-avatar">
+              <i v-if="msg.role === 'user'" class="el-icon-user-solid" />
+              <i v-else class="el-icon-s-platform" />
+            </div>
+            <div class="simulate-chat-bubble">
+              <div class="simulate-chat-role">{{ msg.role === 'user' ? '我' : 'AI助手' }}</div>
+              <div class="simulate-chat-content">{{ msg.content }}</div>
+            </div>
+          </div>
+        </div>
+        <div class="simulate-chat-date">
+          <span class="simulate-chat-date-label">模拟日期</span>
+          <el-date-picker
+            v-model="simulateDate"
+            type="date"
+            placeholder="选择日期"
+            value-format="yyyy-MM-dd"
+            style="width: 200px;"
+            size="small"
+            :picker-options="simulateDatePickerOptions"
+          />
+        </div>
+        <div class="simulate-chat-input-area">
+          <el-input
+            v-model="simulateInput"
+            type="textarea"
+            :rows="2"
+            placeholder="请输入对话内容..."
+            @keydown.native.enter.exact="handleSimulateSend"
+          />
+          <el-button type="primary" :loading="simulateSending" @click="handleSimulateSend" class="simulate-send-btn">发送</el-button>
+        </div>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
@@ -105,7 +153,8 @@ import {
   deleteWorkflowTemplate,
   aiGenerateWorkflow,
   getGenerateResultDetail,
-  confirmGenerateResultEdited
+  confirmGenerateResultEdited,
+  simulateWorkflow
 } from '@/api/company/workflowLobster'
 
 export default {
@@ -138,7 +187,18 @@ export default {
         variables: [],
         nodes: [],
         templateCode: '',
-      }
+      },
+      simulateDialogVisible: false,
+      simulateSending: false,
+      simulateInput: '',
+      simulateDate: '',
+      simulateDatePickerOptions: {
+        disabledDate(time) {
+          return time.getTime() < Date.now() - 8.64e7
+        }
+      },
+      simulateMessages: [],
+      simulateCurrentTemplateId: null
     }
   },
   created() {
@@ -352,6 +412,53 @@ export default {
           this.$message.error(e.message || '删除失败')
         }
       }
+    },
+    handleSimulate(row) {
+      this.simulateDialogVisible = true
+      this.simulateCurrentTemplateId = row.id
+      this.simulateMessages = []
+      this.simulateInput = ''
+      this.simulateDate = ''
+    },
+    handleSimulateDialogClosed() {
+      this.simulateMessages = []
+      this.simulateInput = ''
+      this.simulateDate = ''
+      this.simulateCurrentTemplateId = null
+    },
+    async handleSimulateSend() {
+      const content = this.simulateInput.trim()
+      if (!content) {
+        return
+      }
+      this.simulateMessages.push({ role: 'user', content })
+      this.simulateInput = ''
+      this.$nextTick(() => {
+        this.scrollSimulateChatToBottom()
+      })
+      this.simulateSending = true
+      try {
+        const res = await simulateWorkflow({
+          templateId: this.simulateCurrentTemplateId,
+          content,
+          simulateDate: this.simulateDate
+        })
+        const reply = typeof res.data === 'string' ? res.data : (res.msg || JSON.stringify(res.data || ''))
+        this.simulateMessages.push({ role: 'ai', content: reply })
+      } catch (e) {
+        this.simulateMessages.push({ role: 'ai', content: '抱歉,模拟对话失败:' + (e.message || '未知错误') })
+      } finally {
+        this.simulateSending = false
+        this.$nextTick(() => {
+          this.scrollSimulateChatToBottom()
+        })
+      }
+    },
+    scrollSimulateChatToBottom() {
+      const el = this.$refs.simulateChatMessages
+      if (el) {
+        el.scrollTop = el.scrollHeight
+      }
     }
   }
 }
@@ -398,4 +505,111 @@ export default {
     justify-content: flex-end;
   }
 }
+.simulate-chat-container {
+  display: flex;
+  flex-direction: column;
+  height: 450px;
+}
+.simulate-chat-messages {
+  flex: 1;
+  overflow-y: auto;
+  padding: 12px 16px;
+  background: #f5f7fa;
+  border-radius: 8px;
+  margin-bottom: 12px;
+}
+.simulate-chat-empty {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  height: 100%;
+  color: #909399;
+  p {
+    margin-top: 12px;
+    font-size: 14px;
+  }
+}
+.simulate-chat-message {
+  display: flex;
+  margin-bottom: 16px;
+  &.simulate-chat-user {
+    flex-direction: row-reverse;
+    .simulate-chat-bubble {
+      background: #ecf5ff;
+      border-color: #b3d8ff;
+      margin-right: 10px;
+      margin-left: 50px;
+      text-align: right;
+    }
+    .simulate-chat-avatar {
+      margin-left: 0;
+      margin-right: 0;
+    }
+  }
+  &.simulate-chat-ai {
+    .simulate-chat-bubble {
+      background: #f0f9eb;
+      border-color: #c2e7b0;
+      margin-left: 10px;
+      margin-right: 50px;
+    }
+  }
+}
+.simulate-chat-avatar {
+  width: 32px;
+  height: 32px;
+  border-radius: 50%;
+  background: #e4e7ed;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-shrink: 0;
+  i {
+    font-size: 16px;
+    color: #606266;
+  }
+}
+.simulate-chat-bubble {
+  background: #fff;
+  border: 1px solid #e4e7ed;
+  border-radius: 8px;
+  padding: 10px 14px;
+  max-width: 100%;
+}
+.simulate-chat-role {
+  font-size: 12px;
+  color: #909399;
+  margin-bottom: 4px;
+}
+.simulate-chat-content {
+  font-size: 14px;
+  color: #303133;
+  line-height: 1.6;
+  white-space: pre-wrap;
+  word-break: break-word;
+}
+.simulate-chat-input-area {
+  display: flex;
+  gap: 10px;
+  align-items: flex-end;
+  ::v-deep .el-textarea__inner {
+    resize: none;
+  }
+}
+.simulate-chat-date {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+  margin-bottom: 10px;
+}
+.simulate-chat-date-label {
+  font-size: 14px;
+  color: #606266;
+  flex-shrink: 0;
+}
+.simulate-send-btn {
+  flex-shrink: 0;
+  height: 40px;
+}
 </style>