|
|
@@ -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>
|