/** * A6 报价议价的案例模型 —— **双表示同版本**:CMMN XML(机器面)与案例说明书(叙事面)。 * * 业务出处:`docs/MVP示例工作流.html` §1.4(S1 发报留档 → S2 跟进议价 → S3 定案交接), * 按 A4 同一条形状建模(2026-08-03 重写 @3.0.0): * * 上游(A5 批准的报价草案,A4 `draft` 口的载荷 `{rfqRef, customerCode, items}`)进来 → * 归一成**正式报价函**底表(逐条条款齐备 + 按 P-04 注明有效期)→ **一张执行单** * 交 BD:把报价函发给客户,回音回来后逐条落单(客户表态那一列 AI 一格都不写)→ * 按议价结果 N-01 逐条定案(接受 / 还价 / 不成交)→ **只有还价那几条才叫人拍板** * (决策卡:照客户价成交 / 退回定价重批 / 守住现价)→ 放行,去向由三口的谓词算出来。 * * 上一版(@2.1.0)四处不合现行口径,这一版整个置换: * ① 入参必填 `rfqRef + customerCode + items` —— 而宽进严出是全线口径,归一在活动内做; * ② 三条 L1/L2 判据读的是活动自报的 `missing_field_total` / `validity_days` / * `followup_total` —— 「机检只读基座数得出来的数」违反史第六类; * ③ 台账一个 `required` 都没有 —— 执行卡的闸没牙,人不填也能交卷; * ④ 三个出口没有 `when`:往哪走要模型自己选,而**去向该是算出来的**。 * * 【为什么没有 `listen` 动作】等客户回音这一段落在**执行工单**上,不落 `listen`: * `listen` 在引擎里恒挂起(status: 'awaiting'),要外部事件才唤得醒;而这一单里 * 「客户回了什么」的落单人本来就是 BD(他从自己的邮箱收信,再把结论录进系统)—— * MVP 示例工作流 §1.4 的 S1「生成发出」与 S2「记录反馈」写的也都是**人工任务**。 * 时限那一侧照旧硬约束:`declarations.listeners` 三条静态监听(D+3 催 / D+7 到期 / * 客户回音)由基座在开案那一刻注册,时限必配 —— 「无来源又无时限的等待」一条都没有。 */ export const CMMN_XML = ` update line_total > 0 and quote_negotiate_line_rows = line_total and composed_total >= 0 update replied_total > 0 and quote_negotiate_line_rows > 0 and quote_negotiate_line_missing = 0 update quote_negotiate_line_reply_type_counter > 0 and replied_total > 0 update route_decided_total > 0 and quote_negotiate_line_rows > 0 and quote_negotiate_line_missing = 0 and quote_negotiate_line_deal_status_haggle = 0 and quote_negotiate_line_deal_status_won + quote_negotiate_line_deal_status_haggle + quote_negotiate_line_deal_status_revise + quote_negotiate_line_deal_status_lost = quote_negotiate_line_rows `; /** * 案例说明书 —— **只写整单一以贯之的事**(逐步做法归剧本,两处不重复写同一件事)。 */ export const NARRATIVE = `§0 开案:**一份已批准的报价要发出去,并谈出一个结果**。来路两种,形状都收(宽进): · **流内转来**:任务数据里有 \`items\` 数组 —— A4 的报价草案条目(每条带拟报单价与门禁处置), A5 已经批过;这是最全的一种来路; · **单飞**:只有一段需求文字,说了要给谁发报价、几颗料什么价。 **成品只有一样**:一份**正式报价函** —— 整份条目都在、**每一条都有客户表态**, 而且每一条都定了案:成交 / 退回重批 / 不成交。人签的不是「发出去了」, 是**这一单谈成了什么**。它决定整条流往哪走。 (还价那一档 HAGGLE 是过渡态:**客户还了价、还没拍板**。放行前它必须清零 —— 拍板那一下把它换成成交、退回重批或不成交,三条路都是结论,都算办完。) **能算的不问人,该客户说的不代说**:议价结果 N-01(表态 → 定案)、让步梯度 N-02 (还价幅度 → 处置建议),两支判定表说了算,你不临场拍;而**客户表态那一列是人落的, 你一格都不写** —— 客户回了什么只有收信的人知道,系统不替客户表态。 **四步走**:归一排版报价函 → 交 BD 发出并落回音 → 逐条定案 → 拍板定案放行。 **这一单要经过人一到两次**:BD 在议价工作单上逐条落客户表态(那张单绑着整份报价函, 表态缺一条按不下提交 —— 基座的闸看着,他填的格子直接落账); **只有客户还了价的那几条才另外叫人拍板**(一张决策卡)。每条都叫人,人就成了橡皮图章; 一条都不叫,授权红线就是摆设。最后 BD 放行签字。 **去向是算出来的,不是你选的**:有条目判了退回重批 → 退回定价重批;有成交 → 转订单履约; 全都没成 → 转情报归档。三口各带谓词,放行那一刻基座按序求值,你只要把定案落准。 【这一单只有一个岔路口,它长这样 —— 无论哪一拍都照这个发,别自己另编一张】 客户还了价要人拍板,那张决策卡**三处写死**: · \`"itemId":"T_haggle"\` —— 英文计划项号。**别写中文名「异议拍板」**:中文名不是 id, 写了当场被拒(【目标缺口】那一段摆的就是中文名,别照它抄); · \`"ask":" 条客户还了价,按哪条路办?"\` —— 只把 N 换成条数,**别的字一个都不改**。 换了问法,系统就认不出这是同一张卡:人已经点过的那张会被你再发一遍; · 三个 \`value\`:\`accept-encounter\` 不对,是 \`accept-counter\`(照客户还的价成交)、 \`revise\`(退回成本定价重批)、\`hold\`(守住现价不让)。label 与 consequence 可以按 本单的数改写,**value 不行**。 **REVISE(退回重批)这个码只有拍板那一步写得出来** —— 定案那一步遇到客户还价一律落 HAGGLE,替他写了 REVISE,那张卡就永远不会发,让步梯度成了摆设。 拍板之前**别急着发卡也别绕路** —— 定案那一步先把三档写完、finish; 下一拍引擎会把拍板那一步的做法摊开给你,那时再发。 【一路上要说话】负责人正看着这一单。**每一拍都带一句 say** —— 说业务的话: 报价函排了几条、有效期到哪天、客户回了什么、哪几条要拍板;不说系统词。 到了要找人的那一拍,先说清这一轮办完了什么、为什么现在需要他。 【怎么把一项干完 · 一拍连做】write 和 tool 都不会自动收步 —— 做完用 finish 宣告。 动作排进同一拍的 actions 串一口气给;只有发卡 / 提交(挂起)必须停拍。 **这一单常路 6-8 拍就该收口**。 §Z 结案:BD 在验收单上签字,系统把草稿合并成正式报价函并按定案发出对应那一口的载荷 —— 成交转订单履约,有异议退回成本定价,不成交转情报归档。`; /** * 步骤剧本 —— 一个计划项一条;`doneWhen` 是「成果已存在」的判据,不是「该不该做」。 * * 三处不给 `doneWhen`:`S2_send`(发卡触达真人)、`T_haggle`(要人拍板)、 * `T_release`(签下去触达世界)—— 给了等于给引擎一把替人签字的钥匙。 */ export const NEGOTIATE_STEPS = [ { item: 'S1_compose', intent: '整份归一成正式报价函:逐条抄齐条款、补 SPQ/MOQ/贸易条款、按 P-04 注明有效期', writes: ['quote_negotiate.line', 'quote_negotiate.verdict'], /* 上游载荷数组不声明就会被整表段的截断刀砍掉(砍掉的恰是要归一的行) */ reads: ['items'], view: 'negotiate-worksheet', tools: [], /* * 归一 + 排版走完才算办完:行数两边对上(一边是基座现数), * 且 composed_total 写过(S-FEEL 未绑定的名字参与比较为假,所以「没写过」进不来)。 */ doneWhen: 'line_total > 0 and quote_negotiate_line_rows = line_total and composed_total >= 0', guide: `第一件事:把这一单的**正式报价函**落出来 —— 一拍连做,别拆成两拍。 【条目从哪儿来】 · 流内转来(\`items\` 里的行带 quoted_price / disposition):照抄 —— **报出去的价就是 上游批准的那个价**,一个数字都别改;带 quote_line_total 这类总数的是结论行,不是料, 别落进报价函。 · 单飞:照正文归一,列了几颗落几行;正文里说的批准价就是报出去的价。 **按 pn 归并,一颗料一行**;pn 一个字符不许改(它是主键,改一个字就是新开一行)。 【写 \`quote_negotiate.line\`,一颗料一行】(rows 收数组) rfq_ref(入参有就原样抄;没有从主题认;认不出才自己造一个,**造出来的必须以 \`NEG-\` 开头** (\`NEG-<主题或第一颗料的型号>\`)。两条硬规矩: **① 整单只有一个单号,不是一颗料一个** —— 它是这一单的案号,报价函所有行、verdict 那一行 用的都得是同一个串(实测栽过:两颗料造出两个号,一单裂成两单); **② 只从本单来件取材** —— 台账里躺着的 RFQ-xxxx 是别人的单,借它的号等于把两单的行 混进同一个案卷(实测栽过一轮))、pn、customer_pn、category、brand、eau、lead_time、 remark(客户约束/急料,一个字别丢)、type_tag(照上游现标;认不出按 B)、 **quoted_price**(上游批准的报价,原样抄)。 条款三列**照这个口径补齐**(它们是报价函的必备条款,不是可选项): · spq —— 最小包装量:上游给了就抄;没给按 eau 的量级给一个常规值(千位以下 100, 千到万 1000,万以上 5000)并在 remark 里注明是按常规包装估的; · moq —— 最小起订量:同上,没给就取 spq; · trade_terms —— 贸易条款:统一写 \`EXW 深圳\`,客户来件另有约定的照客户的写。 · valid_until —— 有效期到期日:按**报价有效期 P-04:7 个日历天**从今天算,写成 \`YYYY-MM-DD\`。整单同一个日子,不是一行一个。 【**这三列你一格都不写**:reply_type / counter_price / reply_note】 客户表态、客户还的价、客户原话 —— 这三样只有收信的人知道,**系统不替客户说话**。 它们是 BD 在工作单上落的;deal_status / concession / final_price 三列要等表态回来 才判得了,这一步也别写。 这不是客气话:一条要你分辨「这行能不能替客户填」的规矩会走岔; **「这几列不写」没有分支可走岔。** 【同一拍写 \`quote_negotiate.verdict\`(一行)】 rfq_ref、**quote_no**(报价单号:\`Q-\` 开头 + 本单案号的尾段,整单一个)、 customer_code / customer_name(顶层有就抄)、**line_total** = 报价函行数、 **valid_days** = 7、**composed_total** = 这一拍排版落表的条数(0 也要写)、 summary 一句人话(几条料、报给谁、有效期到哪天)。 写完 finish 这一项。`, }, { item: 'S2_send', intent: '一张执行单交 BD:把报价函发给客户,回音回来后逐条落客户表态', writes: ['quote_negotiate.verdict'], reads: ['quote_negotiate.line'], view: 'negotiate-worksheet', tools: [], /* 不给 doneWhen —— 发卡触达真人(manualActivation),引擎不替人按 */ guide: `报价函排好了,**该 BD 出场了** —— 这是本活动唯一的一张执行单。 触达客户的那一下由人做:他把报价函发出去、按 D+3/D+7 催问、拿回客户的话。 工作区摆的是**议价工作单**:逐颗料一张报价档案卡(条款、报价、客户约束), 让步梯度与议价纪律挂在上面,填回区长在同一屏 —— 他在「客户表态」那一列逐行落。 这一步标了人工激活:发卡就算启动,不必单发 start;引擎也不会替你收 —— 人交回后要你自己 finish。 【照这个骨架发,别少字段】(卡面是纯文本,steps/standard 里别写星号记号) {"kind":"human","itemId":"S2_send","workOrder":"execution","card":{ "title":"报价函发出并跟进:<单号> 共 条待回音", "ask":"报价函已按批准价排好版,条款与有效期都在工作单上。请把它发给客户,按 D+3/D+7 的节奏催问;客户回话之后,在工作单的「客户表态」一列逐行落:接受 / 还价 / 拒绝 / 无回复,还价的把客户报的那个价也填上。", "steps":["发出去之前先核一遍条款:单价、交期、SPQ、MOQ、贸易条款、有效期 —— 报价函一旦发出,这几项就是对客户的承诺", "客户表态每一行都要有 —— 缺一行这张单按不下提交;客户只回了一部分料的,没回的那几行按无回复落,别替客户猜", "客户还价的行:把他报的价填进「客户还价」那一格,再把他的原话记进备注 —— 争的是价格、交期还是 MOQ,后面拍板全看这一句", "D+3 第一轮催问确认收到探态度,D+7 最后一催;催到有效期过仍无回复的,按无回复定案,不要一直挂着"], "standard":"整份报价函每一条都有客户表态,还价的那几条填了客户报的价并记下他的原话 —— 缺一条这张单按不下提交(系统的闸看着)。", "basis":[{"k":"","v":"<报价 · 交期 · 有效期到 YYYY-MM-DD>"}]}} · \`basis\` 逐条列本单的料:PN + 报价与有效期。几颗写几条,别铺全表。 · **卡上不摆表、不摆格子**(执行卡零输入):整份报价函就在工作单那份件上, 客户表态、客户还价、备注三列都能就地改、行能撤 —— **别往卡里塞 \`blocks\` 或 \`fields\`**。 · **这张卡带提交闸**:客户表态(必填列)还空着,他按不下提交 —— 缺几格、缺在哪行, 闸上与件上的红带都写着(与放行门 L1 同一个数同一套算法)。 发完卡这一拍就结束了(发卡挂起)。 【人交回之后 —— 他落的表态基座已经替你写回台账了】这一步你只做两件事,然后 finish: ① 写 verdict:**replied_total** = 已落表态的条数(照报价函行数记); 他在件上撤掉了行的话,**line_total 跟着改成撤后的实数**。 ② finish 这一项。 **别在这一拍判定案** —— 逐条定案是下一步的活(它有自己的一段做法),这里判了也白判。 报价函行你一列都不用重写:他落的值基座已经落进台账了,重写会被「写了等于没写」拒回。 【这张卡一单只发一次】人交回来之后不许再发同一张卡 —— 必填有提交闸兜着, 卡回来时客户表态一定是齐的(或那几行已被他撤掉)。`, }, { item: 'S3_settle', intent: '逐条定案:按客户表态判成交/待拍板/不成交,还价的按让步梯度给处置建议', writes: ['quote_negotiate.line', 'quote_negotiate.verdict'], reads: ['quote_negotiate.line'], view: 'negotiate-worksheet', tools: [], /* * **收步判据与验收判据同源**:四档定案的条数加起来等于行数(两边都是基座现数)—— * 判完了才算办完。`_rows > 0` 那一半不能省:开案时行数是 0,而 0+0+0+0 = 0 * 会让这一步开局即收(未绑定名字的坑之外,还有「全零相等」这一坑)。 */ doneWhen: 'quote_negotiate_line_rows > 0 and quote_negotiate_line_deal_status_haggle = quote_negotiate_line_reply_type_counter and quote_negotiate_line_deal_status_won + quote_negotiate_line_deal_status_haggle + quote_negotiate_line_deal_status_revise + quote_negotiate_line_deal_status_lost = quote_negotiate_line_rows', guide: `客户的话都落回来了,**现在才轮到定案** —— 这一步是纯查表,一拍连做: ① **逐行按客户表态 reply_type 判 deal_status**,按议价结果 N-01, 只许写这四个大写码之一,一个字母不许差: · ACCEPT(客户接受)→ **WON**,同一行 final_price 记 quoted_price(成交价就是报价); · COUNTER(客户还价)→ **HAGGLE**,final_price **留空**(还没谈定,别替客户成交); · REJECT(客户拒绝)→ **LOST**,final_price 留空; · NOREPLY(催到有效期过仍无回复)→ **LOST**,final_price 留空。 **第四个码 REVISE「退回重批」这一步一格都不写** —— 它是人在决策卡上拍出来的, 不是你判出来的。你替他写了,那张卡就永远不会发,让步梯度成了摆设(实测栽过一轮: 一单从头到尾 released 而没有人拍过板)。客户还了价 = 落 **HAGGLE**,句号。 **两个数要对上,都是基座现数,你改不动它们**: · 待拍板条数 quote_negotiate_line_deal_status_haggle **必须等于**客户还价条数 quote_negotiate_line_reply_type_counter —— 对不上这一步收不掉(把写错的那行改回 HAGGLE 就对上了); · 四档定案的条数加起来必须等于 quote_negotiate_line_rows(基座数的行数),一行都不能漏。 现在四档都是 0,就是一行都还没判 —— 这一步没办完,放行门开不了。 ② **还价的那几行(且只有那几行)再算一格 concession**:让步梯度 N-02 看还价幅度 gap =(quoted_price − counter_price)/ quoted_price,只许写这三个大写码之一: · gap ≤ 0.03(三个点以内)→ **ACCEPT_COUNTER**(意思意思的压价,接了拿单); · 0.03 < gap ≤ 0.10(三到十个点)→ **NEGOTIATE**(在授权内回旋一轮,让一半再报回去); · gap > 0.10(超过一成)→ **ESCALATE**(超出授权,退回成本定价重批,不私自破线)。 不是还价的行 concession 给空串 \`""\`,**不许写 0 也不许编一个码** —— 没还价就没有让步幅度这回事。 ③ 看这一拍写完之后的**待拍板条数**(deal_status = HAGGLE 的行): · 一条都没有 → 同一拍把 verdict 写全:**outcome**(全按 N-01 的结果算: 有 WON 就写 \`won\`,一条 WON 都没有就写 \`lost\`)、**route_decided_total 记 1**、 **settled_total** = 定案条数、reason(不成交时写清缘由:客户拒绝还是超时无回复)、 summary 补一句人话,然后 finish 这一项; · 还有 → **别写 outcome 也别写 route_decided_total**,只写 settled_total 再 finish —— 下一拍会有一步专门叫人拍板。 【finish 之后这一拍到此为止】**别在这一拍顺手发决策卡** —— 那张卡属于下一步 (itemId 要写 T_haggle),这一步收掉之后再往它上面挂任何行动都会被拒 (实测:同一串里 write / write / finish / decide,最后那个 decide 挂着 S3_settle,当场被拒)。 下一拍引擎会把「异议拍板」那一步的做法摊开给你,那时再发。`, }, { item: 'T_haggle', intent: '客户还的价接不接要人定 —— 发一张决策卡,照他选的那条路把定案改掉', writes: ['quote_negotiate.line', 'quote_negotiate.verdict'], reads: ['quote_negotiate.line'], view: 'negotiate-roster', tools: [], /* 人工激活 + 要人拍板 —— 不给 doneWhen,引擎不许替人收 */ guide: `**这一单只发一张决策卡。动手之前先在轨迹里找一行 \`[card-reply]\` 带「人选了:」:** · **找到了** —— 跳到下面【人点完之后】那一段,照他选的那条路把那几行的 deal_status 从 HAGGLE 改掉、写 outcome 与 route_decided_total、finish。**一个 decide 都不许再发** (实测栽过:人点完了,而这一步又从头念了一遍「发一张决策卡」,同一张卡连发六次, 前两次无事发生、后四次被拒 —— 他点过的那一下就白点了); · **没找到** —— 才轮到下面【发一张决策卡】那一段。 【这一步办完了没有,看一个数】待拍板条数 quote_negotiate_line_deal_status_haggle: **它归零就是这一步办完了**。HAGGLE 是过渡态(客户还了价、还没拍板), 拍板那一下必须把它换成 WON / REVISE / LOST 之一 —— 三条路都是结论。 这个数不归零,放行门开不了;它归零,这一步也就不会再找你。 这一步只在**客户还过价**(基座现数 quote_negotiate_line_reply_type_counter > 0)时入场 —— 读的是客户自己填的那一格,不是你判的定案:该不该叫人,不由被叫的那一方说了算。 它触达公司利益,标了人工激活:发卡就算启动,不必单发 start。 工作区这时摆的是**成交定案清单**,整份报价函与定案分布都在上面,他看得见全局再拍板。 【发一张决策卡,照这个骨架】(选项少于两个基座拒发) **三处一个字都不许改**(与说明书里那一段是同一份): · \`itemId\` 只写英文计划项号 \`T_haggle\` —— **别写中文名「异议拍板」**, 中文名不是 id,写了当场被拒(实测栽过两拍:「计划项不存在:异议拍板」); 【目标缺口】那一段摆的是中文名,它不是 id,别照它抄。 · \`ask\` 照抄「 条客户还了价,按哪条路办?」,**只把 N 换成条数** —— 换了问法系统就认不出这是同一张卡,人已经点过的那张会被你再发一遍(实测发出去两张)。 · 三个 \`value\` 照抄 \`accept-counter\` / \`revise\` / \`hold\` —— 它们是这一单三条路的 代号,换了名字下一段的对应关系就对不上,你自己也不知道人点的是哪条。 label 与 consequence 可以按本单的数改写,value 不行。 {"kind":"decide","itemId":"T_haggle","ask":" 条客户还了价,按哪条路办?", "options":[ {"value":"accept-counter","label":"照客户还的价成交","consequence":"当场拿下这几条,毛利让到客户的价位上,让出去的部分不再回来"}, {"value":"revise","label":"退回成本定价重批","consequence":"这几条超出让价授权,回 A4 重新算价再谈 —— 这一单本轮不成交,客户要多等一轮"}, {"value":"hold","label":"守住现价不让","consequence":"报价不动,客户不接受即视为不成交,这几条转情报归档"}], "basis":[{"k":"","v":"报价 · 客户还价 · 让幅 % · 让步梯度判 <码>"}]} · basis 逐条摆还价的那几颗料:报价、客户还价、让幅、N-02 的处置码 —— 裸卡基座拒发。 · **recommended 按让步梯度 N-02 标**,标在与处置码对应的那一项上,只标一项: ACCEPT_COUNTER → accept-counter;NEGOTIATE → accept-counter;ESCALATE → revise。 几条料的码不一致时,按**最靠后那一档**标(有一条要 ESCALATE 就标 revise)。 · 发完这一拍就结束了(发卡挂起)。 【人点完之后】轨迹上那一行长这样:\`[card-reply] …人选了:xxx\`。**照那条路把定案改掉, 别再发第二张卡**,一拍连做 —— 三条路**都要动 deal_status**,一条都不许留在 HAGGLE: · 选 accept-counter:那几行 deal_status 改 **WON**、**final_price 记该行的 counter_price**(那个数不是你定的,是客户报的、人点头认的,你只是替他落账)、 reply_note 补一句「按客户还价成交,由负责人拍板」;verdict 的 outcome 写 \`won\`; · 选 revise:那几行 deal_status 改 **REVISE**、final_price 留空, reply_note 补一句「让幅超出授权,退回成本定价重批」;verdict 的 outcome 写 \`revise\`、 reason 写清超了多少; · 选 hold:那几行 deal_status 改 **LOST**、final_price 留空, reply_note 补一句「守价不让,客户未接受」;verdict 的 outcome 写 \`lost\`、 reason 写「客户还价未达成,守价不让」。 然后把 verdict 写全:**route_decided_total 记 1**、settled_total = 定案条数、 summary 补一句拍板结果,finish 这一项。 **outcome 那一格照上面三条写死的对应关系填,别自己另造词** —— 下游三条边读的就是它。 改完之后待拍板条数就是 0 了,这一步再也不会找你。`, }, { item: 'T_release', intent: '定案已落,提交放行交 BD 验收', writes: [], reads: [], view: 'negotiate-roster', tools: [], /* 放行触达世界,必须人按一下 —— 引擎不自动收它(剧本里也不给 doneWhen) */ guide: `每条都有客户表态、定案守恒、待拍板清零、定案已记 —— 可以走放行了 (T_release 人工激活:动它就算启动,不必单发 start)。先把裁量判据裁掉,然后 submit,同一拍连做: · judge criterion="议价过程说得清:报价函条款齐备、每一轮客户反馈与让价理由逐条可溯,BD 对这个结果负责" —— 看报价函里每一行的条款、客户原话与让价理由:说得出来路就 satisfied=true; 有行说不出的(比如还价成交却没记客户的话),satisfied=**false**,rationale 逐行写清, 交签字的人定。**裁成不满足照样能提交** —— 理由连着卡一起交给他。 criterion 照判据名**整句原样抄**,写别的名字对不上。 **去向不必你选**:三口各带谓词,放行那一刻基座按序求值 —— 有条目判了退回重批就走「退回调整」,有成交就走「转订单履约」,全都没成就走「转情报归档」。 你要做的只是把定案落准,别在提交里手选出口。 终局唯放行:你不能自己宣布完成。`, }, ]; /** * 阶段 —— 进度条的刻度,只给人看。除放行外每个计划项恰属一个阶段; * 放行那一格由基座统一加,人看到的是 x/5。 */ export const NEGOTIATE_PHASES = [ { name: '排版报价函', items: ['S1_compose'] }, { name: '发出并等回音', items: ['S2_send'] }, { name: '逐条定案', items: ['S3_settle'] }, { name: '异议拍板', items: ['T_haggle'] }, ];