机器人回复补调用编码;集拼报价条带字段写到下一行,业务员落中文名。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -3,6 +3,7 @@ import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
export const columns: BasicColumn[] = [
|
||||
{ title: '分类', dataIndex: 'categoryTitle', width: 100 },
|
||||
{ title: '分类码', dataIndex: 'categoryCode', width: 120 },
|
||||
{ title: '调用编码', dataIndex: 'replyCode', width: 180 },
|
||||
{ title: '触发场景', dataIndex: 'triggerScene', width: 220 },
|
||||
{ title: '回复正文', dataIndex: 'replyText', align: 'left' },
|
||||
{
|
||||
@@ -28,6 +29,9 @@ export const searchFormSchema: FormSchema[] = [
|
||||
{ label: '协商中', value: 'negotiating' },
|
||||
{ label: '未成交', value: 'lost' },
|
||||
{ label: '已关闭', value: 'closed' },
|
||||
{ label: '事件异常', value: 'event-ex' },
|
||||
{ label: '系统异常', value: 'sys-ex' },
|
||||
{ label: '转人工', value: 'transfer' },
|
||||
],
|
||||
},
|
||||
},
|
||||
@@ -48,10 +52,19 @@ export const formSchema: FormSchema[] = [
|
||||
{ label: '协商中 negotiating', value: 'negotiating' },
|
||||
{ label: '未成交 lost', value: 'lost' },
|
||||
{ label: '已关闭 closed', value: 'closed' },
|
||||
{ label: '事件异常 event-ex', value: 'event-ex' },
|
||||
{ label: '系统异常 sys-ex', value: 'sys-ex' },
|
||||
{ label: '转人工 transfer', value: 'transfer' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{ field: 'categoryTitle', label: '分类标题', component: 'Input', required: true },
|
||||
{
|
||||
field: 'replyCode',
|
||||
label: '调用编码',
|
||||
component: 'Input',
|
||||
componentProps: { placeholder: '如 lost.ask_reason,已有编码不可改' },
|
||||
},
|
||||
{ field: 'triggerScene', label: '触发场景', component: 'Input', required: true },
|
||||
{
|
||||
field: 'replyText',
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
export type ReplyItem = {
|
||||
id: string;
|
||||
/** 智能体日后按此码取文案;空表示未接入。 */
|
||||
replyCode?: string;
|
||||
trigger: string;
|
||||
text: string;
|
||||
enabled: boolean;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
/**
|
||||
* 机器人回复语:完整照搬原型 admin-bot-replies.html(V1.0.24)。
|
||||
* 共 9 类 37 条;与 deploy/sql/inquiry_bot_reply_proto_seed_v1.sql 同源。
|
||||
* 机器人回复语 mock:与现网整理表、migration_inq_bot_reply_replace_v1.sql 同源。
|
||||
* 正式页走主账 /inquiry/botReply;本文件仅对照,共 51 条。
|
||||
*/
|
||||
|
||||
export type ReplyItem = {
|
||||
id: string;
|
||||
replyCode?: string;
|
||||
trigger: string;
|
||||
text: string;
|
||||
enabled: boolean;
|
||||
@@ -26,47 +27,229 @@ export const mockReplyCategories: ReplyCategory[] = [
|
||||
tagClass: "tag-blue",
|
||||
items: [
|
||||
{
|
||||
id: "r1",
|
||||
id: "brv10000000000000000000000000001",
|
||||
replyCode: "inquiring.first_chat",
|
||||
trigger: "销售首次单聊机器人",
|
||||
text: "你好,我是询价机器人。请直接描述客户需求,例如「上海到洛杉矶空运,3 件 180kg,下周三前到」,我会解析需求并查询 TMS 标准报价。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r2",
|
||||
trigger: "销售上传 Excel / 图片附件",
|
||||
text: "已收到附件,正在识别路线、货量、品名和时效要求,原始文件将存为工单需求附件。工单 {{ticket_no}} 状态:询价中。",
|
||||
id: "brv10000000000000000000000000002",
|
||||
replyCode: "inquiring.ask_transport",
|
||||
trigger: "未识别运输方式",
|
||||
text: "请回复数字或文字,告知我询价的运输方式:\n1.陆运\n2.海运\n3.空运",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r3",
|
||||
trigger: "AI 解析成功 → 创建工单",
|
||||
text: "已识别:{{biz_type}} · {{origin}} → {{destination}} · {{cargo_desc}}。工单 {{ticket_no}} 已创建,正在查询 TMS 标准报价…",
|
||||
id: "brv10000000000000000000000000003",
|
||||
replyCode: "inquiring.continue_need_wo",
|
||||
trigger: "续办但未提供工单号",
|
||||
text: "请告诉我要继续的工单号,例如 WO202609140034。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r4",
|
||||
trigger: "AI 解析失败 → 要求补充参数",
|
||||
text: "未能完全理解需求,请补充或确认:起运地?目的地?件数?毛重?体积?如有品名和时效要求,也请一并补充。",
|
||||
id: "brv10000000000000000000000000004",
|
||||
replyCode: "inquiring.continue_not_found",
|
||||
trigger: "续办找不到工单",
|
||||
text: "找不到工单 {{ticket_no}},请核对工单号后再试。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r5",
|
||||
trigger: "TMS 命中标准价 → 询问是否内部协同",
|
||||
text: "TMS 标准报价合计 {{system_quote}},预计时效 {{eta}}。价格明细:空运价、操作费、文件费、报关费、提货费、目的地杂费、其他附加费。{{history_hint}}是否需要咨询内部{{internal_role_label}}人员,或直接生成报价单?",
|
||||
id: "brv10000000000000000000000000005",
|
||||
replyCode: "inquiring.image_recognizing",
|
||||
trigger: "销售发送图片",
|
||||
text: "正在识别图片",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r6",
|
||||
trigger: "销售确认创建内部协同群",
|
||||
text: "正在创建内部协同群「{{group_name}}」,并拉入销售 {{sales_name}}、{{internal_staff}} 及询价机器人。工单 {{ticket_no}} 保持「询价中」,等待内部反馈。",
|
||||
id: "brv10000000000000000000000000006",
|
||||
replyCode: "inquiring.image_tech_fail",
|
||||
trigger: "图片识别失败",
|
||||
text: "图片暂时没认出来,请再发一张或直接打字。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r7",
|
||||
trigger: "内部人员回复手工报价",
|
||||
text: "收到 {{staff_name}}({{staff_role}})的手工报价,已结构化处理。报价 {{manual_quote}},附件 {{quote_attachment}} 已存入工单,正在整理报价方案…",
|
||||
id: "brv10000000000000000000000000007",
|
||||
replyCode: "inquiring.attach_recognizing",
|
||||
trigger: "销售发送附件",
|
||||
text: "正在识别附件",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000008",
|
||||
replyCode: "inquiring.attach_tech_fail",
|
||||
trigger: "附件识别失败",
|
||||
text: "附件暂时没认出来,请再传一次或直接打字。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000009",
|
||||
replyCode: "inquiring.attach_h5_expired",
|
||||
trigger: "H5 上传链接过期",
|
||||
text: "已过期,请回企微重新说附件询价。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000010",
|
||||
replyCode: "inquiring.attach_h5_ok",
|
||||
trigger: "H5 上传成功",
|
||||
text: "已收到,请回企微查看识别结果。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000011",
|
||||
replyCode: "inquiring.pull_group_manual",
|
||||
trigger: "请手动拉人进群并发送工单号",
|
||||
text: "请手动拉相关人员和智能体到原有群,并在群聊发送工单编号{{ticket_no}}",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000012",
|
||||
replyCode: "inquiring.skip_collab_ack",
|
||||
trigger: "销售跳过内部协同",
|
||||
text: "好的,已跳过内部协同。正在按 TMS 标准报价生成报价单草稿…",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000013",
|
||||
replyCode: "inquiring.group_created",
|
||||
trigger: "协同群创建成功",
|
||||
text: "协同群已创建,群名与工单号一致:{{ticket_no}}。已邀请:销售{{sales_name}}、产品{{product_names}}。请在群聊中继续确认报价。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000014",
|
||||
replyCode: "inquiring.group_exists",
|
||||
trigger: "协同群已存在",
|
||||
text: "协同群已在,群名与工单号一致:{{ticket_no}}。请到该群继续确认报价。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000015",
|
||||
replyCode: "inquiring.sea_no_staff",
|
||||
trigger: "海运没有可拉的产品人员",
|
||||
text: "没有可拉的产品人员。请先在后台「员工管理」维护本线路的海运产品岗后再试。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000016",
|
||||
replyCode: "inquiring.land_no_staff",
|
||||
trigger: "陆运没有可拉的产品人员",
|
||||
text: "没有可拉的产品人员。请先在后台「员工管理」维护本线路的陆运产品岗后再试。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000017",
|
||||
replyCode: "inquiring.group_create_fail",
|
||||
trigger: "建群失败",
|
||||
text: "建群失败,请稍后重试。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000018",
|
||||
replyCode: "inquiring.quote_generating",
|
||||
trigger: "报价单生成中",
|
||||
text: "报价单正在生成,请稍候。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000019",
|
||||
replyCode: "inquiring.air_ticket_not_found",
|
||||
trigger: "空运群找不到工单",
|
||||
text: "找不到工单{{ticket_no}},请核对工单号后再试。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000020",
|
||||
replyCode: "inquiring.air_ticket_not_air",
|
||||
trigger: "工单不是空运单",
|
||||
text: "工单{{ticket_no}}不是空运单,不能在空运群里跟。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000021",
|
||||
replyCode: "inquiring.air_ticket_occupied",
|
||||
trigger: "空运工单已在另一个群",
|
||||
text: "工单{{ticket_no}}已经在另一个群跟了,请到那个群继续。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000022",
|
||||
replyCode: "inquiring.group_only_product",
|
||||
trigger: "非产品人员在群里报价",
|
||||
text: "只有产品能报价格,请产品在群里发价格或 Excel/PDF",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000023",
|
||||
replyCode: "inquiring.group_file_saved",
|
||||
trigger: "群附件已保存",
|
||||
text: "附件已保存后台",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000024",
|
||||
replyCode: "inquiring.air_lock_need_wo",
|
||||
trigger: "空运锁舱/释放未带工单号",
|
||||
text: "锁舱或释放舱位请带上工单号,例如 WO202609160001锁舱。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000025",
|
||||
replyCode: "inquiring.air_lock_need_quote",
|
||||
trigger: "没有报价不能锁舱",
|
||||
text: "工单{{ticket_no}}还没有报价,不能锁舱。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000026",
|
||||
replyCode: "inquiring.air_airline_only_cabin",
|
||||
trigger: "只有航线能锁舱或释放",
|
||||
text: "只有岗位为「航线·空运」的人能锁舱或释放舱位。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000027",
|
||||
replyCode: "inquiring.air_lock_ok",
|
||||
trigger: "空运锁舱成功",
|
||||
text: "工单{{ticket_no}} 已通知TMS执行空运锁舱,执行成功。\n操作人:{{operator}}\n舱位选项:{{option_no}}\n执行编号:{{exec_no}}\n报价编号:{{quote_no}}",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000028",
|
||||
replyCode: "inquiring.air_lock_fail",
|
||||
trigger: "空运锁舱失败",
|
||||
text: "工单{{ticket_no}} 空运锁舱失败。\n操作人:{{operator}}\n锁舱失败的原因:{{reason}}\n已通知IT运维排查,请稍等。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000029",
|
||||
replyCode: "inquiring.air_release_ok",
|
||||
trigger: "空运释放成功",
|
||||
text: "工单{{ticket_no}} 已通知TMS执行空运释放舱位成功\n操作人:{{operator}}\n舱位选项:{{option_no}}\n执行编号:{{exec_no}}\n报价编号:{{quote_no}}",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000030",
|
||||
replyCode: "inquiring.air_release_fail",
|
||||
trigger: "空运释放失败",
|
||||
text: "工单{{ticket_no}} 空运释放舱位失败。\n操作人:{{operator}}\n释放舱位失败的原因:{{reason}}\n已通知IT运维排查,请稍等。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000031",
|
||||
replyCode: "inquiring.air_release_deal_blocked",
|
||||
trigger: "已成交不能释放舱位",
|
||||
text: "释放舱位失败,工单{{ticket_no}}已成交。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000032",
|
||||
replyCode: "inquiring.air_release_need_lock",
|
||||
trigger: "没有有效锁舱不能释放",
|
||||
text: "工单{{ticket_no}}还没有有效锁舱,不能释放。",
|
||||
enabled: true,
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -76,41 +259,40 @@ export const mockReplyCategories: ReplyCategory[] = [
|
||||
tagClass: "tag-blue",
|
||||
items: [
|
||||
{
|
||||
id: "r8",
|
||||
trigger: "报价方案整理完成 → 询问是否采用",
|
||||
text: "工单 {{ticket_no}} 状态已更新为「已报价」。整理后的报价方案:{{route_summary}} · {{quote_amount}} · {{eta}}。请确认是否采用:(采用,生成 Excel 报价单 / 采用,生成 PDF 报价单 / 不采用)",
|
||||
id: "brv10000000000000000000000000033",
|
||||
replyCode: "quoted.reject_ack",
|
||||
trigger: "销售选择「不采用」",
|
||||
text: "请问如何调整报价单,以满足您的需求?请说明要调哪一项费用,例如「提货费加 10%」。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r9",
|
||||
trigger: "销售确认采用 → 生成最终报价单",
|
||||
text: "已确认采用该方案,正在生成 {{quote_format}} 最终报价单…工单保持「已报价」,完成后可直接转发给客户。",
|
||||
id: "brv10000000000000000000000000034",
|
||||
replyCode: "quoted.adopt_excel",
|
||||
trigger: "销售确认采用 → 生成 Excel",
|
||||
text: "已确认采用该方案,正在生成 Excel 最终报价单…",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r10",
|
||||
id: "brv10000000000000000000000000035",
|
||||
replyCode: "quoted.adopt_pdf",
|
||||
trigger: "销售确认采用 → 生成 PDF",
|
||||
text: "已确认采用该方案,正在生成PDF最终报价单…",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000036",
|
||||
replyCode: "quoted.template_missing",
|
||||
trigger: "后台未维护报价模板",
|
||||
text: "生成报价单失败,请联系IT运维维护后台报价模板。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000037",
|
||||
replyCode: "quoted.file_ready",
|
||||
trigger: "最终报价单生成完成",
|
||||
text: "最终报价单已生成:{{quote_file}}({{quote_amount}} · {{route_summary}})。工单 {{ticket_no}} 保持「已报价」,报价单已归档。",
|
||||
text: "已生成{{kind}}最终报价单:{{filename}}(工单 {{ticket_no}})",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r11",
|
||||
trigger: "销售发送比例调价指令",
|
||||
text: "已识别调价指令:在当前报价基础上{{adjust_direction}}{{adjust_percent}}%。原报价 {{original_quote}} → 新报价 {{new_quote}}。正在刷新报价并重新生成报价单,工单保持「已报价」。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r12",
|
||||
trigger: "二次询价 · 关联历史工单",
|
||||
text: "识别为二次询价,已关联历史工单 {{history_ticket_no}}。TMS 标准报价 {{system_quote}};上次报价 {{history_quote}},历史报价文档已引用至当前会话。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r13",
|
||||
trigger: "报价单出具满*小时 → 发起成交跟进",
|
||||
text: "工单 {{ticket_no}} 已于 {{quote_time}} 出具报价({{route_summary}} · {{quote_amount}})。请确认当前与客户的成交状态:(成交 / 未成交 / 协商中)",
|
||||
enabled: true,
|
||||
},
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -120,17 +302,12 @@ export const mockReplyCategories: ReplyCategory[] = [
|
||||
tagClass: "tag-green",
|
||||
items: [
|
||||
{
|
||||
id: "r14",
|
||||
trigger: "销售在成交跟进中选择「成交」",
|
||||
text: "已记录为「已成交」。工单 {{ticket_no}} 状态已更新,成交确认时间 {{deal_time}} 已写入后台。已推送成交通知至 {{manager_name}}({{manager_role}})。",
|
||||
id: "brv10000000000000000000000000038",
|
||||
replyCode: "deal.recorded_won",
|
||||
trigger: "销售选择「成交」",
|
||||
text: "已记录为「已成交」。工单 {{ticket_no}} 已关闭智能体跟进。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r15",
|
||||
trigger: "成交确认 → 企微推送负责人",
|
||||
text: "【成交通知】工单 {{ticket_no}} 已成交。销售:{{sales_name}} · 业务:{{biz_type}} · 路线:{{route_summary}}报价:{{quote_amount}} · 确认时间:{{deal_time}}推送对象:{{manager_name}}({{manager_role}})。请知悉并安排后续履约跟进。",
|
||||
enabled: true,
|
||||
},
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -140,29 +317,12 @@ export const mockReplyCategories: ReplyCategory[] = [
|
||||
tagClass: "tag-amber",
|
||||
items: [
|
||||
{
|
||||
id: "r16",
|
||||
trigger: "销售选择「不采用」当前报价方案",
|
||||
text: "工单 {{ticket_no}} 状态已更新为「协商中」。请问希望如何调整?可说明调价幅度、换舱/时效要求,或是否需要重新拉内部{{internal_role_label}}协同。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r17",
|
||||
id: "brv10000000000000000000000000039",
|
||||
replyCode: "negotiating.recorded",
|
||||
trigger: "成交跟进中选择「协商中」",
|
||||
text: "已记录为「协商中」。工单跟进周期已顺延 {{negotiate_extend_days}}个工作日,将于 {{next_followup_time}} 再次向您发起成交状态询问。",
|
||||
text: "已记录为「协商中」。已顺延三个工作日,{{followup_when}}的9:00再次发起成交状态询问。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r18",
|
||||
trigger: "协商跟进周期到期 → 再次询问",
|
||||
text: "工单 {{ticket_no}} 协商跟进周期已到({{route_summary}} · {{quote_amount}})。请再次确认当前成交状态:(成交 / 未成交 / 协商中)",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r19",
|
||||
trigger: "调价或重新协同完成 → 出具新方案",
|
||||
text: "协商调整已完成,新报价方案:{{route_summary}} · {{quote_amount}} · {{eta}}。工单状态更新为「已报价」,请确认是否采用。",
|
||||
enabled: true,
|
||||
},
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -172,23 +332,19 @@ export const mockReplyCategories: ReplyCategory[] = [
|
||||
tagClass: "tag-rose",
|
||||
items: [
|
||||
{
|
||||
id: "r20",
|
||||
trigger: "成交跟进中选择「未成交」",
|
||||
text: "请告知{{ticket_no}}「未成交」的原因(必填)。回复后系统将记录至工单 {{ticket_no}},并推送未成交通知至对应负责人。",
|
||||
id: "brv10000000000000000000000000040",
|
||||
replyCode: "lost.ask_reason",
|
||||
trigger: "成交跟进中选择「未成交」且未写原因",
|
||||
text: "已记录为「未成交」。请补充未成交原因。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r21",
|
||||
trigger: "销售回复未成交原因 → 关单并通知负责人",
|
||||
text: "已记录为「未成交」。原因:{{reject_reason}}。登记时间 {{reject_time}},已推送未成交通知至 {{manager_name}}({{manager_role}})。工单 {{ticket_no}} 已归档。",
|
||||
id: "brv10000000000000000000000000041",
|
||||
replyCode: "lost.reason_ack",
|
||||
trigger: "销售回复未成交原因",
|
||||
text: "已记下未成交原因:{{lost_reason}}。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r22",
|
||||
trigger: "未成交确认 → 企微推送负责人",
|
||||
text: "【未成交通知】工单 {{ticket_no}} 未成交。销售:{{sales_name}} · 业务:{{biz_type}} · 路线:{{route_summary}}未成交原因:{{reject_reason}}登记时间:{{reject_time}} · 推送对象:{{manager_name}}({{manager_role}})。请知悉本单未成单情况。",
|
||||
enabled: true,
|
||||
},
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -198,17 +354,12 @@ export const mockReplyCategories: ReplyCategory[] = [
|
||||
tagClass: "tag-rose",
|
||||
items: [
|
||||
{
|
||||
id: "r23",
|
||||
trigger: "达到配置超时时间 → 系统自动关闭",
|
||||
text: "工单 {{ticket_no}} 因「{{close_reason}}」已达关闭条件,系统已自动关闭。关闭时间:{{close_time}}。本单不再发起成交跟进,亦不触发成交/未成交通知。",
|
||||
id: "brv10000000000000000000000000042",
|
||||
replyCode: "closed.air_cannot_activate",
|
||||
trigger: "空运工单已是终态仍要激活",
|
||||
text: "工单{{ticket_no}}已是「{{status}}」,不能再激活。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r24",
|
||||
trigger: "销售/客服手动关闭工单",
|
||||
text: "工单 {{ticket_no}} 已由 {{operator_name}} 手动关闭。关闭原因:{{close_reason}}。如需重新询价,请发起新的询价对话。",
|
||||
enabled: true,
|
||||
},
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -217,24 +368,7 @@ export const mockReplyCategories: ReplyCategory[] = [
|
||||
desc: "业务流程中参与方响应超时等业务侧异常,写入工单「事件异常」字段,需人工跟进。",
|
||||
tagClass: "tag-amber",
|
||||
items: [
|
||||
{
|
||||
id: "r25",
|
||||
trigger: "内部协同*小时无响应 → 群内提醒",
|
||||
text: "@{{staff_name}} @{{sales_name}} 工单 {{ticket_no}} 已超过 {{timeout_hours}} 小时未收到内部协同回复,请尽快确认。事件异常:{{event_exception_type}}。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r26",
|
||||
trigger: "内部协同超时达告警阈值 → 生成告警工单",
|
||||
text: "工单 {{ticket_no}} 内部协同已超过 {{alert_hours}} 小时未响应,已生成「{{event_exception_type}}」告警,请管理员跟进。未响应人员:{{staff_name}}({{staff_role}})。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r27",
|
||||
trigger: "成交跟进多次无响应 → 标记销售响应超时",
|
||||
text: "工单 {{ticket_no}} 成交跟进已发起 {{followup_count}} 次,销售仍未回复。事件异常:销售响应超时。如继续无响应,系统将按配置自动关闭工单。",
|
||||
enabled: true,
|
||||
},
|
||||
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -244,29 +378,54 @@ export const mockReplyCategories: ReplyCategory[] = [
|
||||
tagClass: "tag-rose",
|
||||
items: [
|
||||
{
|
||||
id: "r28",
|
||||
trigger: "大模型调用失败",
|
||||
text: "AI 解析暂时不可用({{system_error_detail}})。工单 {{ticket_no}} 已标记系统异常:大模型异常。请稍后重试,或回复「人工报价」转人工处理。",
|
||||
id: "brv10000000000000000000000000043",
|
||||
replyCode: "sys.llm_fail",
|
||||
trigger: "大模型调用失败(销售侧)",
|
||||
text: "大模型服务异常,IT排查中...",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r29",
|
||||
trigger: "TMS 接口调用失败",
|
||||
text: "TMS 标准价库查询失败({{system_error_detail}})。工单已标记系统异常:TMS异常。可稍后重试,或选择转人工由内部人员报价。",
|
||||
id: "brv10000000000000000000000000044",
|
||||
replyCode: "sys.tms_fail",
|
||||
trigger: "TMS 接口失败(销售侧)",
|
||||
text: "TMS接口异常,IT运维排查中...",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r30",
|
||||
trigger: "企微建群 / 添加成员失败",
|
||||
text: "创建协同群失败,无法添加 {{staff_name}}({{staff_wechat_id}})。系统异常:建群异常 · {{system_error_detail}}。已在后台生成异常工单,请联系管理员检查人员配置。",
|
||||
id: "brv10000000000000000000000000045",
|
||||
replyCode: "sys.group_add_fail",
|
||||
trigger: "企微添加成员失败",
|
||||
text: "无法添加 {{staff_name}} 同事,请联系管理员检查企业微信配置。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r31",
|
||||
trigger: "系统异常处理完成",
|
||||
text: "工单 {{ticket_no}} 系统异常「{{system_exception_type}}」已处理完毕,工单状态恢复为「{{restored_status}}」。处理记录:{{handle_note}}",
|
||||
id: "brv10000000000000000000000000046",
|
||||
replyCode: "sys.tms_recovery",
|
||||
trigger: "TMS 已恢复",
|
||||
text: "TMS已恢复正常使用,感谢您的耐心等待。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000047",
|
||||
replyCode: "sys.llm_recovery",
|
||||
trigger: "大模型已恢复",
|
||||
text: "大模型已恢复正常使用,感谢您的耐心等待。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000048",
|
||||
replyCode: "sys.cabin_recovery",
|
||||
trigger: "空运舱位接口已恢复",
|
||||
text: "空运舱位接口已恢复正常使用,感谢您的耐心等待。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "brv10000000000000000000000000049",
|
||||
replyCode: "sys.group_recovery",
|
||||
trigger: "建群已恢复",
|
||||
text: "建群已恢复正常,感谢您的耐心等待。",
|
||||
enabled: true,
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -276,41 +435,19 @@ export const mockReplyCategories: ReplyCategory[] = [
|
||||
tagClass: "tag-violet",
|
||||
items: [
|
||||
{
|
||||
id: "r32",
|
||||
trigger: "TMS 暂无报价",
|
||||
text: "暂无 TMS 标准报价。触发转人工:{{transfer_reason}}。是否拉{{internal_role_label}}进群协同?(是 / 否)",
|
||||
id: "brv10000000000000000000000000050",
|
||||
replyCode: "transfer.already_collab",
|
||||
trigger: "该工单已拉过产品进群",
|
||||
text: "该工单已拉产品进群协同。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r33",
|
||||
trigger: "意图识别失败",
|
||||
text: "已尝试 {{intent_retry}} 次澄清,仍无法识别询价意图。触发转人工:意图识别失败。是否拉{{internal_role_label}}进群协同?(是 / 否)",
|
||||
id: "brv10000000000000000000000000051",
|
||||
replyCode: "transfer.air_hint",
|
||||
trigger: "空运转人工(不自动建群)",
|
||||
text: "触发转人工,请手动把航线和智能体拉进原有空运群,并发送工单号 {{ticket_no}}。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r34",
|
||||
trigger: "参数提取不全",
|
||||
text: "已连续 {{param_retry}} 次反问补充询价参数仍未完整。触发转人工:参数提取不全。是否拉{{internal_role_label}}进群协同?(是 / 否)",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r35",
|
||||
trigger: "报价解析失败",
|
||||
text: "触发转人工:{{transfer_reason}}(已连续失败 {{fail_count}} 次)。是否拉{{internal_role_label}}进群协同?(是 / 否)",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r36",
|
||||
trigger: "空运锁舱/释放舱位失败",
|
||||
text: "触发转人工:{{transfer_reason}}(已连续失败 {{fail_count}} 次)。请航线人员在 TMS 侧手工处理,或手动拉相关人员协助。请务必在群聊发送工单编号 {{ticket_no}}。",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "r37",
|
||||
trigger: "销售发送「人工报价」",
|
||||
text: "已识别转人工指令。{{confirm_pull_group}}正在创建内部协同群,拉入销售 {{sales_name}}、{{internal_staff}} 及询价机器人…工单 {{ticket_no}} 进入「询价中」。",
|
||||
enabled: true,
|
||||
},
|
||||
}
|
||||
],
|
||||
},
|
||||
}
|
||||
];
|
||||
|
||||
@@ -1399,3 +1399,19 @@ html {
|
||||
font-size: 11px !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* 弹窗多行正文:必须压过上面 .field 的 height:34px。
|
||||
* AdminModal 会 Teleport 到 body,页面 scoped 样式经常盖不住这条全局规则。
|
||||
*/
|
||||
textarea.field.field-tall {
|
||||
height: 240px !important;
|
||||
min-height: 240px !important;
|
||||
padding: 8px 10px !important;
|
||||
line-height: 1.5 !important;
|
||||
resize: vertical !important;
|
||||
}
|
||||
|
||||
.form-row.form-row-tall {
|
||||
align-items: start !important;
|
||||
}
|
||||
|
||||
|
||||
@@ -1680,6 +1680,11 @@ textarea:focus-visible {
|
||||
line-height: 1.45;
|
||||
}
|
||||
|
||||
.admin-modal-body textarea.field.field-tall {
|
||||
height: 240px;
|
||||
min-height: 240px;
|
||||
}
|
||||
|
||||
.admin-modal-body .perm-tree-box {
|
||||
max-height: none;
|
||||
border: 1px solid var(--line);
|
||||
|
||||
Reference in New Issue
Block a user