机器人回复补调用编码;集拼报价条带字段写到下一行,业务员落中文名。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
/**
|
||||
* 机器人回复语:对接主账 /inquiry/botReply。
|
||||
* 分类壳用本地元数据;条目内容全部来自库。
|
||||
* 调用编码仅展示/预置,本期不向智能体下发。
|
||||
*/
|
||||
import { onMounted, reactive, ref } from "vue";
|
||||
import { message } from "ant-design-vue";
|
||||
@@ -21,12 +22,14 @@ import AdminModal from "/@/views/inquiry/components/AdminModal.vue";
|
||||
|
||||
const categories = ref<ReplyCategory[]>(emptyCategories());
|
||||
const loading = ref(false);
|
||||
const totalCount = ref(0);
|
||||
const modalOpen = ref(false);
|
||||
const editing = ref<{ categoryId: string; item: ReplyItem | null }>({
|
||||
categoryId: "",
|
||||
item: null,
|
||||
});
|
||||
const form = reactive({
|
||||
replyCode: "",
|
||||
trigger: "",
|
||||
text: "",
|
||||
enabled: true,
|
||||
@@ -52,6 +55,7 @@ function groupByCategory(list: any[]) {
|
||||
if (row.categoryTitle) cat.title = row.categoryTitle;
|
||||
cat.items.push({
|
||||
id: String(row.id),
|
||||
replyCode: row.replyCode || "",
|
||||
trigger: row.triggerScene || "",
|
||||
text: row.replyText || "",
|
||||
enabled: row.enabled === 1 || row.enabled === true,
|
||||
@@ -64,7 +68,14 @@ async function loadList() {
|
||||
loading.value = true;
|
||||
try {
|
||||
const res: any = await getReplyListAll();
|
||||
const list = Array.isArray(res) ? res : res?.result || res?.records || [];
|
||||
const list = Array.isArray(res)
|
||||
? res
|
||||
: Array.isArray(res?.result)
|
||||
? res.result
|
||||
: Array.isArray(res?.records)
|
||||
? res.records
|
||||
: [];
|
||||
totalCount.value = list.length;
|
||||
categories.value = groupByCategory(list as any[]);
|
||||
} catch (e: any) {
|
||||
message.error(e?.message || "加载回复语失败");
|
||||
@@ -93,13 +104,14 @@ async function toggle(item: ReplyItem) {
|
||||
|
||||
function openCreate(categoryId?: string) {
|
||||
editing.value = { categoryId: categoryId || categories.value[0]?.id || "inquiring", item: null };
|
||||
Object.assign(form, { trigger: "", text: "", enabled: true });
|
||||
Object.assign(form, { replyCode: "", trigger: "", text: "", enabled: true });
|
||||
modalOpen.value = true;
|
||||
}
|
||||
|
||||
function openEdit(categoryId: string, item: ReplyItem) {
|
||||
editing.value = { categoryId, item };
|
||||
Object.assign(form, {
|
||||
replyCode: item.replyCode || "",
|
||||
trigger: item.trigger,
|
||||
text: item.text,
|
||||
enabled: item.enabled,
|
||||
@@ -114,7 +126,7 @@ async function save() {
|
||||
}
|
||||
const cat = categories.value.find((c) => c.id === editing.value.categoryId);
|
||||
if (!cat) return;
|
||||
const body = {
|
||||
const body: Record<string, any> = {
|
||||
id: editing.value.item?.id,
|
||||
categoryCode: cat.id,
|
||||
categoryTitle: cat.title,
|
||||
@@ -122,6 +134,11 @@ async function save() {
|
||||
replyText: form.text.trim(),
|
||||
enabled: form.enabled ? 1 : 0,
|
||||
};
|
||||
if (editing.value.item?.replyCode) {
|
||||
body.replyCode = editing.value.item.replyCode;
|
||||
} else if (form.replyCode.trim()) {
|
||||
body.replyCode = form.replyCode.trim();
|
||||
}
|
||||
try {
|
||||
await saveReply(body, Boolean(editing.value.item));
|
||||
message.success(editing.value.item ? "话术已更新" : "话术已添加");
|
||||
@@ -141,6 +158,7 @@ async function save() {
|
||||
</Teleport>
|
||||
|
||||
<div v-if="loading" style="padding: 24px; color: #94a3b8">加载中…</div>
|
||||
<p v-else class="reply-total">共 {{ totalCount }} 条(按现网整理表应为 51 条;事件异常本期无条目)</p>
|
||||
|
||||
<article v-for="cat in categories" :key="cat.id" class="reply-category">
|
||||
<div style="display: flex; align-items: center; justify-content: space-between">
|
||||
@@ -154,6 +172,7 @@ async function save() {
|
||||
<div v-for="item in cat.items" :key="item.id" class="reply-item">
|
||||
<div style="min-width: 0">
|
||||
<div class="reply-meta">触发:{{ item.trigger }}</div>
|
||||
<div v-if="item.replyCode" class="reply-meta">调用编码:{{ item.replyCode }}</div>
|
||||
<div class="reply-text">{{ item.text }}</div>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; gap: 8px; flex-shrink: 0">
|
||||
@@ -172,7 +191,7 @@ async function save() {
|
||||
<AdminModal
|
||||
v-model:open="modalOpen"
|
||||
:title="editing.item ? '编辑话术' : '添加话术'"
|
||||
size="md"
|
||||
size="lg"
|
||||
ok-text="保存"
|
||||
@ok="save"
|
||||
>
|
||||
@@ -182,13 +201,28 @@ async function save() {
|
||||
<option v-for="c in categories" :key="c.id" :value="c.id">{{ c.title }}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label class="lbl">调用编码</label>
|
||||
<input
|
||||
v-model="form.replyCode"
|
||||
class="field"
|
||||
type="text"
|
||||
:disabled="Boolean(editing.item?.replyCode)"
|
||||
placeholder="如 lost.ask_reason;已有编码不可改"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label class="lbl">触发条件 <span class="req">*</span></label>
|
||||
<input v-model="form.trigger" class="field" type="text" />
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-row form-row-tall">
|
||||
<label class="lbl">回复正文 <span class="req">*</span></label>
|
||||
<textarea v-model="form.text" class="field" rows="5" placeholder="支持 {{ticket_no}} 等变量" />
|
||||
<textarea
|
||||
v-model="form.text"
|
||||
class="field field-tall"
|
||||
rows="12"
|
||||
placeholder="支持 {{ticket_no}} 等变量"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label class="lbl">状态</label>
|
||||
@@ -201,6 +235,22 @@ async function save() {
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.reply-total {
|
||||
margin: 0;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
color: #667085;
|
||||
}
|
||||
.form-row-tall {
|
||||
align-items: start;
|
||||
}
|
||||
textarea.field-tall {
|
||||
height: 240px !important;
|
||||
min-height: 240px !important;
|
||||
padding: 8px 10px !important;
|
||||
line-height: 1.5 !important;
|
||||
resize: vertical;
|
||||
}
|
||||
.check-line {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
||||
Reference in New Issue
Block a user