From 9674a2ee4bd1c88e4fc04c00ea7467dae5bbb544 Mon Sep 17 00:00:00 2001 From: yumoqing Date: Thu, 10 Sep 2026 16:14:39 +0800 Subject: [PATCH] =?UTF-8?q?feat(ticket):=20=E5=B7=A5=E5=8D=95=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E6=A8=A1=E5=9D=97=E5=BA=94=E7=94=A8=E9=9B=86=E6=88=90?= =?UTF-8?q?=E2=80=94=E2=80=94load=E9=93=BE/build.sh=E4=B8=89=E6=B8=85?= =?UTF-8?q?=E5=8D=95/=E7=A7=8D=E5=AD=90/i18n/=E8=8F=9C=E5=8D=95/=E5=86=92?= =?UTF-8?q?=E7=83=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - app/pipeline_app.py: try-import load_ticket()+load链(pipeline_task之后,依赖pipeline_service的provider注册/llm_bridge/rag_client) - build.sh: clone/pip install/wwwroot软链三清单加ticket(无json/CRUD故不进xls2ui清单) - conf/config.json module_dbname: ticket→pipeline; scripts/import_init.py INIT_MODULES加ticket(码表+owner.maintainer角色种子) - scripts/merge_i18n.py MODULES加ticket; i18n四语言+3词条(我的工单/工单管理/提交新工单) - wwwroot/index.ui: 客户分支「我的工单」;管理分支「工单管理」(is_ticket_staff=owner.maintainer/admin/superuser Jinja门禁) - deploy/smoke: s15/s16工单两页面用例 - rp.json不改: 权限由模块load_path.py逐个精确配(管理页壳owner三角色,业务权限服务端按current_role动态校验) --- app/pipeline_app.py | 6 ++++++ build.sh | 6 +++--- conf/config.json | 3 ++- deploy/smoke/cases.json | 18 ++++++++++++++++++ i18n/en/msg.txt | 3 +++ i18n/jp/msg.txt | 3 +++ i18n/ko/msg.txt | 3 +++ i18n/zh/msg.txt | 3 +++ scripts/import_init.py | 1 + scripts/merge_i18n.py | 1 + wwwroot/index.ui | 15 +++++++++++++++ 11 files changed, 58 insertions(+), 4 deletions(-) diff --git a/app/pipeline_app.py b/app/pipeline_app.py index 741b7ce..260698e 100644 --- a/app/pipeline_app.py +++ b/app/pipeline_app.py @@ -131,6 +131,11 @@ def init(): from pipeline_platform.init import load_pipeline_platform except ImportError: def load_pipeline_platform(): pass + # ticket:平台工单(客户提问→agent预处理→人工运维→转派,接入平台待办通道) + try: + from ticket.init import load_ticket + except ImportError: + def load_ticket(): pass set_globalvariable() ServerEnv().get_module_dbname = get_module_dbname @@ -153,6 +158,7 @@ def init(): load_pipeline_llm() # 模型治理:供应商/账号/端点/组织策略/限额限流/记账 load_pipeline_service() load_pipeline_task() # 任务中心交互层:注册 task_detail/step_panel 页面所需 Jinja helper(依赖 pipeline_service) + load_ticket() # 工单管理:依赖 pipeline_service(待办provider注册+llm_bridge+rag_client),agent poller 随 worker 进程启动 load_pipeline_platform() # 平台内部 agent(依赖 pipeline_service 的 llm_bridge) load_pipeline_bidding() # 投标产线能力包(依赖 pipeline_service 的 capability 分发) load_pipeline_opportunity() # 商机产线能力包(数据来自数据爬取平台内网 HTTP) diff --git a/build.sh b/build.sh index ebcea36..4b53258 100644 --- a/build.sh +++ b/build.sh @@ -56,7 +56,7 @@ done # 注:evaluate 只 clone 不 install——其 wwwroot/json/models 嵌套在包内(evaluate/evaluate/), # 与本脚本 pkgs//wwwroot 软链约定不兼容,且依赖 VBench/torch 重环境; # 待营销产线开发时连同结构规范化一起接入。 -for mod in pipeline-sdlc showcase evaluate pipeline-service pipeline-task tenant app_audit product_management discount pricing unipay smssend accounting uapi rag dingdingflow account_resource storage_resource filemgr supplychain pipeline-bidding pipeline-llm pipeline-platform pipeline-opportunity; do +for mod in pipeline-sdlc showcase evaluate pipeline-service pipeline-task tenant app_audit product_management discount pricing unipay smssend accounting uapi rag dingdingflow account_resource storage_resource filemgr supplychain pipeline-bidding pipeline-llm pipeline-platform pipeline-opportunity ticket; do cd "$cdir/pkgs" if [ ! -d "$mod" ]; then git clone https://git.opencomputing.cn/yumoqing/$mod || echo "SKIP: $mod" @@ -67,7 +67,7 @@ done # 6. pip install all modules from pkgs/(pipeline-service 是普通 install 非 editable,部署必 pull+pip install 都做) # 注意与第 5 步 clone 清单对齐:clone 了却不 install 的模块,主程序 try/except 会静默降级—— # 模块整个消失且零报错(account_resource 等 4 个此前正是这种状态,测试机靠手工补装)。 -for mod in pipeline_core pipeline_ops pipeline-sdlc showcase pipeline-service pipeline-task tenant app_audit product_management discount pricing unipay smssend accounting uapi rag dingdingflow account_resource storage_resource filemgr supplychain pipeline-bidding pipeline-llm pipeline-platform pipeline-opportunity; do +for mod in pipeline_core pipeline_ops pipeline-sdlc showcase pipeline-service pipeline-task tenant app_audit product_management discount pricing unipay smssend accounting uapi rag dingdingflow account_resource storage_resource filemgr supplychain pipeline-bidding pipeline-llm pipeline-platform pipeline-opportunity ticket; do if [ -d "pkgs/$mod" ]; then "$cdir/py3/bin/pip" install "pkgs/$mod/" 2>&1 | tail -1 fi @@ -112,7 +112,7 @@ done # 8. Link module wwwroot directories (symlinks from pkgs/) -for mod in pipeline-sdlc showcase tenant pipeline_core pipeline_ops appbase app_audit product_management discount pricing unipay rbac dapi accounting uapi rag dingdingflow account_resource storage_resource filemgr supplychain pipeline-bidding pipeline-llm pipeline-platform pipeline-opportunity pipeline-task; do +for mod in pipeline-sdlc showcase tenant pipeline_core pipeline_ops appbase app_audit product_management discount pricing unipay rbac dapi accounting uapi rag dingdingflow account_resource storage_resource filemgr supplychain pipeline-bidding pipeline-llm pipeline-platform pipeline-opportunity pipeline-task ticket; do src="pkgs/$mod/wwwroot" dst="wwwroot/$mod" if [ -d "$src" ]; then diff --git a/conf/config.json b/conf/config.json index 2458731..ea3904e 100644 --- a/conf/config.json +++ b/conf/config.json @@ -25,7 +25,8 @@ "pipeline_core": "pipeline", "pipeline_ops": "pipeline", "pipeline_sdlc": "pipeline", - "showcase": "pipeline" + "showcase": "pipeline", + "ticket": "pipeline" }, "website": { "port": 9090, diff --git a/deploy/smoke/cases.json b/deploy/smoke/cases.json index 0adce24..17f19ee 100644 --- a/deploy/smoke/cases.json +++ b/deploy/smoke/cases.json @@ -124,6 +124,24 @@ "status": 200, "contains": "产线" } + }, + { + "id": "s14", + "name": "工单-客户列表页", + "url": "/ticket/my/index.ui", + "auth": "login", + "expect": { + "status": 200 + } + }, + { + "id": "s15", + "name": "工单-管理页", + "url": "/ticket/manage/index.ui", + "auth": "login", + "expect": { + "status": 200 + } } ] } \ No newline at end of file diff --git a/i18n/en/msg.txt b/i18n/en/msg.txt index 57362fc..4175916 100644 --- a/i18n/en/msg.txt +++ b/i18n/en/msg.txt @@ -54,3 +54,6 @@ API Key: API Key 工作空间为通用会话专属目录,不进入项目空间: Workspace is the general session's own directory, not any project space 暂无已购产线: No purchased pipelines 尚未购买该产线或订阅已到期,请到产品商城购买后再开始对话: Pipeline not purchased or subscription expired. Buy it in the Product Store before chatting. +我的工单: My Tickets +工单管理: Ticket Management +提交新工单: New Ticket diff --git a/i18n/jp/msg.txt b/i18n/jp/msg.txt index 266eb78..609672d 100644 --- a/i18n/jp/msg.txt +++ b/i18n/jp/msg.txt @@ -33,3 +33,6 @@ Submit: 送信 显示所有已最小化的窗口: 最小化されたすべてのウィンドウを表示 通用助手: 汎用アシスタント API Key: API Key +我的工单: マイチケット +工单管理: チケット管理 +提交新工单: 新規チケット diff --git a/i18n/ko/msg.txt b/i18n/ko/msg.txt index c4d8c0e..a772b6a 100644 --- a/i18n/ko/msg.txt +++ b/i18n/ko/msg.txt @@ -33,3 +33,6 @@ Submit: 제출 显示所有已最小化的窗口: 최소화된 모든 창 표시 通用助手: 일반 어시스턴트 API Key: API Key +我的工单: 내 티켓 +工单管理: 티켓 관리 +提交新工单: 새 티켓 diff --git a/i18n/zh/msg.txt b/i18n/zh/msg.txt index 2995f38..19aca56 100644 --- a/i18n/zh/msg.txt +++ b/i18n/zh/msg.txt @@ -54,3 +54,6 @@ API Key: API Key 工作空间为通用会话专属目录,不进入项目空间: 工作空间为通用会话专属目录,不进入项目空间 暂无已购产线: 暂无已购产线 尚未购买该产线或订阅已到期,请到产品商城购买后再开始对话: 尚未购买该产线或订阅已到期,请到产品商城购买后再开始对话 +我的工单: 我的工单 +工单管理: 工单管理 +提交新工单: 提交新工单 diff --git a/scripts/import_init.py b/scripts/import_init.py index b076ee0..f91a130 100644 --- a/scripts/import_init.py +++ b/scripts/import_init.py @@ -35,6 +35,7 @@ INIT_MODULES = [ ('pipeline-bidding', 'pkgs/pipeline-bidding/init/data.json'), ('pipeline-opportunity', 'pkgs/pipeline-opportunity/init/data.json'), ('pipeline-llm', 'pkgs/pipeline-llm/init/data.json'), + ('ticket', 'pkgs/ticket/init/data.json'), ] diff --git a/scripts/merge_i18n.py b/scripts/merge_i18n.py index dda3181..4855295 100644 --- a/scripts/merge_i18n.py +++ b/scripts/merge_i18n.py @@ -25,6 +25,7 @@ MODULES = [ ('pipeline-opportunity', os.path.join(ROOT_DIR, 'pkgs', 'pipeline-opportunity', 'i18n')), ('dingdingflow', os.path.join(ROOT_DIR, 'pkgs', 'dingdingflow', 'i18n')), ('rbac', os.path.join(ROOT_DIR, 'pkgs', 'rbac', 'i18n')), + ('ticket', os.path.join(ROOT_DIR, 'pkgs', 'ticket', 'i18n')), ] LANGS = ['zh', 'en', 'ko', 'jp'] diff --git a/wwwroot/index.ui b/wwwroot/index.ui index 51004da..b3b6cf6 100644 --- a/wwwroot/index.ui +++ b/wwwroot/index.ui @@ -2,6 +2,7 @@ {% set is_fin = ('owner.superuser' in roles) or ('owner.admin' in roles) or ('owner.account' in roles) or ('reseller.admin' in roles) or ('reseller.accountant' in roles) or ('reseller.operator' in roles) %} {% set is_customer = ('customer.customer' in roles) or ('*.customer' in roles) %} {% set is_admin = ('owner.superuser' in roles) or ('owner.admin' in roles) %} +{% set is_ticket_staff = is_admin or ('owner.maintainer' in roles) %} { "id": "app", "widgettype": "VBox", @@ -210,6 +211,12 @@ "icon": "", "script": "this.open_tab({name:'cust_apikey',label:'API Key',url:'/dapi/apikey_manage.ui',removable:true})" }, + { + "name": "cust_tickets", + "label": "我的工单", + "icon": "", + "script": "this.open_tab({name:'cust_tickets',label:'我的工单',url:'/ticket/my/index.ui',removable:true})" + }, { "name": "cust_account", "label": "我的账户", @@ -547,6 +554,14 @@ } ] }, +{% if is_ticket_staff %} + { + "name": "ticket_manage", + "label": "工单管理", + "icon": "", + "script": "this.open_tab({name:'ticket_manage',label:'工单管理',url:'/ticket/manage/index.ui',removable:true})" + }, +{% endif %} { "name": "sysmgr", "label": "系统管理",