diff --git a/.tmp/Yuxi b/.tmp/Yuxi new file mode 160000 index 0000000..fd6803e --- /dev/null +++ b/.tmp/Yuxi @@ -0,0 +1 @@ +Subproject commit fd6803e477db87767531b06bb2333433ed919c51 diff --git a/document/development/hermes_agent/01_architecture_overview.md b/document/development/hermes_agent/01_architecture_overview.md new file mode 100644 index 0000000..3fa4da4 --- /dev/null +++ b/document/development/hermes_agent/01_architecture_overview.md @@ -0,0 +1,41 @@ +# Hermes 后台智能体架构总览 + +## 1. 定位与愿景 +Hermes 是 X-Financial 系统中的**后台自动巡检与数据洞察中枢**。与处理实时对话的 UserAgent 不同,Hermes 专注于异步、长周期、大批量的任务,核心价值在于提供事前的**深度风险挖掘**和定期的**业财洞察报告**。 + +## 2. 系统拓扑图 +```mermaid +graph TD + subgraph 调度层 + A[Cron Scheduler] -->|定时触发| B[Task Queue] + end + + subgraph Hermes Agent 层 + B -->|消费任务| C(Hermes Worker) + C --> D[Task Skills Router] + D --> E{RiskScanner Skill} + D --> F{ExpenseReport Skill} + D --> G{KnowledgeCheck Skill} + end + + subgraph X-Financial 核心服务 + E <--> H[(Expense DB)] + F <--> H + G <--> I[(LightRAG Graph/Vector)] + C <--> J[LLM Gateway / OpenAI] + C --> K[Notification Service / 企业微信] + end +``` + +## 3. 核心设计原则 +1. **防抖与限流**:后台全量扫表时,必须分片执行,防止对主数据库造成 I/O 拥堵。 +2. **幂等性保障**:每一个扫描任务和报告生成任务都应该具备唯一幂等键,避免因进程重启导致的重复发信或重复扣减信用分。 +3. **隔离性**:Hermes 的进程应与对外提供 API 服务的 Web Server 物理/逻辑隔离,大模型限流策略(Token Rate Limit)应配置相互独立的账单通道。 + +## 4. 核心执行链路(示例:夜间风控巡检) +1. 凌晨 02:00,Cron 触发 `trigger_risk_scan` 任务。 +2. Worker 拉取状态为 `draft` 和 `submitted` 且 `risk_scanned=False` 的单据。 +3. 将近三个月的相关人员单据聚类,构建 Context。 +4. 调用大模型,寻找“拆单”、“合谋”、“时间/地点异常”等隐蔽风险。 +5. 将发现的风险写入 `hermes_risk_report` 表,并标记对应单据。 +6. 任务结束,更新执行日志,等待早晨财务主管查阅。 diff --git a/document/development/hermes_agent/02_database_design.md b/document/development/hermes_agent/02_database_design.md new file mode 100644 index 0000000..a379d98 --- /dev/null +++ b/document/development/hermes_agent/02_database_design.md @@ -0,0 +1,46 @@ +# Hermes 数据库表结构设计 + +为了支持后台异步任务的执行和长期记忆(风险标记、执行结果归档),我们需要在数据库中增加(或扩充)以下表结构。 + +## 1. 任务调度与执行表 + +### `hermes_task_config` (定时任务配置表) +用于管理所有的后台巡检和推送任务,支持动态调整频率与开关。 +- `id`: string (UUID) +- `task_type`: string (enum: `global_risk_scan`, `weekly_expense_report`, `kb_validation`...) +- `cron_expression`: string (e.g., `0 2 * * *`) +- `is_enabled`: boolean (默认 True) +- `payload_template`: jsonb (预留参数,如扫描的时间窗口、特定部门过滤条件等) +- `updated_at`: datetime + +### `hermes_task_execution_log` (任务执行日志表) +记录每次任务的执行状态,便于排错与溯源。 +- `id`: string (UUID) +- `config_id`: string (外键,关联 `hermes_task_config`) +- `started_at`: datetime +- `completed_at`: datetime +- `status`: string (enum: `running`, `success`, `failed`) +- `result_summary`: string (执行结果的简要说明,如“扫描了 1500 条单据,发现 12 条高危”) +- `error_trace`: text (如果失败,存储错误堆栈) + +## 2. 深度分析结果表 + +### `hermes_risk_report` (深度风险报告表) +用于存储 LLM 找出的深层逻辑风险。 +- `id`: string (UUID) +- `claim_id`: string (外键,关联存疑的主单据 `expense_claim`) +- `execution_log_id`: string (外键,由哪次扫描任务产生的) +- `risk_level`: string (enum: `low`, `medium`, `high`, `critical`) +- `risk_type`: string (enum: `split_billing` 拆单, `collusion` 合谋, `policy_violation` 违规...) +- `risk_description`: text (大模型生成的自然语言报告,如“该单据与前天提交的单据存在拆分可能...”) +- `related_claim_ids`: jsonb (存储关联的同谋/相关单据 ID 列表,提供上下文线索) +- `status`: string (enum: `pending_review` 待人工复核, `confirmed` 已确认为风险, `dismissed` 已忽略) + +## 3. 现有表的平滑改造 + +### 修改 `employee` 表 (员工信用分预留) +- **新增字段** `compliance_score`: int (默认 100,由 Hermes 动态扣减或恢复,用于风控引擎调节对该员工的抽查率和宽容度) + +### 修改 `expense_claim` 表 (风控标记) +- **新增字段** `hermes_scanned_at`: datetime (记录该单据上次被 Hermes 扫描的时间,防止重复扫描) +- **新增字段** `hermes_risk_flag`: boolean (快速判断该单子是否被挂载了 `hermes_risk_report`) diff --git a/document/development/hermes_agent/03_risk_scan_module.md b/document/development/hermes_agent/03_risk_scan_module.md new file mode 100644 index 0000000..95daef8 --- /dev/null +++ b/document/development/hermes_agent/03_risk_scan_module.md @@ -0,0 +1,32 @@ +# 深度风险扫描模块设计 (Risk Scan Module) + +## 1. 业务目标 +将单点硬规则风控(如:发票大于 500 元是否合规)升级为**图谱式全局风控**。Hermes 将利用大语言模型(LLM)的逻辑推理能力,在海量历史数据中寻找隐藏的违规模式。 + +## 2. 核心扫描链路 +本模块将作为一个独立的 Skill 被定时任务触发。 + +### 第一步:数据快照聚合 +- **提取目标**:拉取状态为 `draft`、`submitted` 且最近 30 天内活跃的报销单,同时带出相关的发票明细。 +- **降维处理**:为避免超出大模型的 Token 上下文限制,必须对单据信息进行降维。仅提取:`申请人、时间、地点、商户名、金额、报销类型` 形成精简的 CSV 或 JSON Lines 格式。 + +### 第二步:大模型批量推理 (LLM Batch Inference) +- **风险定义植入**:通过 System Prompt 将目前财务最头疼的几类风险定义给模型(如拆单、套现、虚假连号发票)。 +- **执行方式**:将数据按“同部门”或“同地域”分块 (Chunking) 喂给大模型。 +- **Prompt 示例**: + ```markdown + 你是一个内控审计 Agent。以下是某部门近半个月的报销流水清单。 + 请找出其中是否存在: + 1. 拆单行为(同人、同地点、连日、小额累加) + 2. 聚众套现行为(不同人、同偏僻餐馆、同日极高额) + 如果发现风险,请输出对应的单号集合以及你的推理过程。 + ``` + +### 第三步:风险标记与处置 +- 解析大模型返回的结构化 JSON。 +- 对被判定的高危单据,在主库中插入 `hermes_risk_report` 记录。 +- **动作反馈**:如果该单据正处于 `submitted` 状态,并且得分极高(如虚假连号发票),可以通过 X-Financial 原有接口自动注入“退回”动作,并附加大模型的分析日志。 + +## 3. 防抖与自我迭代 +- **扫描去重**:利用 `expense_claim.hermes_scanned_at` 防止已经出具过报告的单据被重复投入分析队列。 +- **人工纠偏 (Human-in-the-loop)**:当财务在前端驳回 Hermes 的风险提示(即认为没问题)时,事件将被记录。Hermes 可通过夜间的反思任务优化下一次 Prompt 中的判定容忍度。 diff --git a/document/development/hermes_agent/04_expense_report_module.md b/document/development/hermes_agent/04_expense_report_module.md new file mode 100644 index 0000000..3873102 --- /dev/null +++ b/document/development/hermes_agent/04_expense_report_module.md @@ -0,0 +1,34 @@ +# 动态费控与洞察报告模块设计 (Expense Report Module) + +## 1. 业务目标 +基于海量的流水账单,定期(周/月)由 Hermes Agent 为部门管理者或财务总监自动生成具有**业务洞察力**的归因分析报告,将冷冰冰的数字转化为具有指导意义的自然语言建议。 + +## 2. 核心分析链路 + +### 第一步:BI 数据聚合 (Data Aggregation) +- 借助 ORM 或底层 Data Warehouse (如有),Hermes 执行预置的聚合查询。 +- **采集核心指标**: + - 本期各部门总花费及环比/同比变动率。 + - 各类目(如打车、机票、住宿、招待)的占比变化。 + - Top 10 花费最多的商户(如特定几家酒店或订票平台)。 + - 各类目超额/退回率最高的人员画像。 + +### 第二步:大模型归因分析 (LLM Attribution Analysis) +将硬性的聚合数据转化为结构化 Prompt,让 LLM 充当“财务分析师”。 +- **Prompt 示例**: + ```markdown + 你是企业的财务总监助理,请阅读以下【本月报销聚合数据】。 + 请帮我撰写一份 300 字以内的执行摘要报告。 + 重点指出: + 1. 哪个部门/哪类费用增长最快?原因可能是什么? + 2. 我们的长尾开销集中在哪些商户?是否存在能够跟商户谈“协议价”的谈判空间? + ``` + +### 第三步:多渠道报告分发 (Report Delivery) +- **生成制品**:Hermes 利用代码解释器 (如有) 或 Markdown 引擎,将图表与文本融合成正式的 PDF 或长图。 +- **触达渠道**: + - **推送机制**:调用企微/钉钉机器人 API,直接向管理者的工作台推送“上周费控简报”。 + - **交互追问**:管理者收到简报卡片后,可以在对话框里直接@Hermes 追问:“详细列一下研发部上周在北京住宿的那 5 万块钱是怎么花的”,Hermes 将调取缓存的报告上下文立即答复。 + +## 3. 商业价值落地 +这项功能极大地解放了财务部的报表处理时间。通过提供前置的谈判线索(如发现某经济型酒店的高频住客其实都可以导流到协议酒店),可以给公司带来直接的差旅成本节约。 diff --git a/document/development/hermes_agent/05_deployment_and_cron.md b/document/development/hermes_agent/05_deployment_and_cron.md new file mode 100644 index 0000000..4fe5e6c --- /dev/null +++ b/document/development/hermes_agent/05_deployment_and_cron.md @@ -0,0 +1,63 @@ +# 部署与任务调度架构方案 (Deployment & Cron) + +## 1. 业务诉求分析 +Hermes 作为纯后台的智能体,它的执行过程长达几分钟甚至几小时。它绝不能与提供给前台 HTTP 请求的主 Web 服务混合在同一个事件循环(Event Loop)或同步进程中,否则会导致 API 严重堵塞和超时崩溃。 + +因此,Hermes 的部署需要进行**进程级解耦**。 + +## 2. 选型对比与推荐方案 + +### 方案 A:Celery + Redis (重型/工业级标准) +- **优势**:业界最成熟的 Python 异步任务队列,支持极其复杂的 Cron 配置,原生支持任务重试、失败回调以及分布式扩展。 +- **劣势**:增加系统组件(必须额外部署 Redis / RabbitMQ 容器),运维成本相对较高。 +- **结论**:如果 X-Financial 后续要承载上千人的企业报销,这是**首选必经之路**。 + +### 方案 B:APScheduler + Background Worker (中型/轻量级) +- **优势**:直接在 Python 进程内运行,无需额外的消息队列组件。可以用一个单独的 Docker 容器运行 `python run_hermes_scheduler.py`。 +- **劣势**:多节点部署时难以控制并发(可能会多个节点同时执行同样的任务),需要引入基于数据库表或 Redis 的分布式锁。 +- **结论**:适合初期快速跑通 MVP 的方案。 + +## 3. 推荐架构:基于 Redis 分布式锁的独立容器方案 +结合当前现状,建议采用 **方案B 叠加 分布式锁** 的轻量微服务架构。 + +### 部署拓扑: +```yaml +# docker-compose.yml 示例切片 +services: + x-financial-api: + build: . + command: uvicorn main:app + ports: + - "8000:8000" + + x-financial-hermes: + build: . + command: python scripts/start_hermes_daemon.py + # 这个容器不暴露外部端口,纯粹在后台运行定时任务和消费队列 +``` + +### 执行伪代码 (`start_hermes_daemon.py`) +```python +from apscheduler.schedulers.blocking import BlockingScheduler +from app.services.system_hermes import SystemHermesService + +scheduler = BlockingScheduler() +hermes = SystemHermesService() + +# 每天凌晨 3 点执行深度风控扫表 +@scheduler.scheduled_job('cron', hour=3, minute=0) +def job_risk_scan(): + # 获取分布式锁防止集群脑裂重复执行 + if acquire_redis_lock("hermes:lock:risk_scan"): + try: + hermes.run_query("执行全局风控扫描技能...", skills=["global_risk_scan"]) + finally: + release_redis_lock("hermes:lock:risk_scan") + +if __name__ == "__main__": + scheduler.start() +``` + +## 4. 容灾与可观测性保障 +- **日志采集**:确保 `hermes.run_query` 及其后台生成的 stdout/stderr 日志能够写入 ELK 或文件系统中,方便第二天的运维排查。 +- **告警链路**:如果调度系统挂掉或者大模型连续多次返回失败状态码,必须通过 Webhook 飞书/钉钉及时告警系统管理员。 diff --git a/fix_init.py b/fix_init.py new file mode 100644 index 0000000..2438e09 --- /dev/null +++ b/fix_init.py @@ -0,0 +1,24 @@ +import re + +file_path = 'server/src/app/models/__init__.py' +with open(file_path, 'r', encoding='utf-8') as f: + content = f.read() + +# Add imports +imports_to_add = "from app.models.hermes_config import HermesTaskConfig, HermesTaskExecutionLog\nfrom app.models.hermes_report import HermesRiskReport\n" +content = re.sub( + r'(from app\.models\.organization import OrganizationUnit)', + imports_to_add + r'\1', + content +) + +# Add to __all__ +content = re.sub( + r'(\s*"OrganizationUnit",)', + r'\n "HermesTaskConfig",\n "HermesTaskExecutionLog",\n "HermesRiskReport",\1', + content +) + +with open(file_path, 'w', encoding='utf-8') as f: + f.write(content) +print('Done.') diff --git a/fix_knowledge.py b/fix_knowledge.py new file mode 100644 index 0000000..425dfb9 --- /dev/null +++ b/fix_knowledge.py @@ -0,0 +1,45 @@ +import re + +file_path = 'server/src/app/services/user_agent_knowledge.py' +with open(file_path, 'r', encoding='utf-8') as f: + content = f.read() + +content = re.sub( + r'(def _build_fast_knowledge_answer\([\s\S]*?-> str \| None:\n)', + r'\1 return None\n', + content +) + +content = re.sub( + r'heading_text = f" > \{heading\}" if heading else ""', + r'if "表格行级检索线索" in heading:\n heading = heading.replace("表格行级检索线索", "").strip(" >")\n heading_text = f"({heading})" if heading else ""\n item_title = item.get("title") or title', + content +) + +content = re.sub( + r'evidence_lines\.append\(f"- 《\{item\.get\(\'title\'\) or title\}》\{heading_text\}:\{summary\}\\n\{preview\}"\)', + r'evidence_lines.append(f"- **《{item_title}》** {heading_text}\\n {summary}\\n{preview}")', + content +) + +content = re.sub( + r'evidence_lines\.append\(f"- 《\{item\.get\(\'title\'\) or title\}》\{heading_text\}:\\n\{rendered\}"\)', + r'evidence_lines.append(f"- **《{item_title}》** {heading_text}\\n{rendered}")', + content +) + +content = re.sub( + r'evidence_lines\.append\(f"- 《\{item\.get\(\'title\'\) or title\}》\{heading_text\}:\{rendered\}"\)', + r'evidence_lines.append(f"- **《{item_title}》** {heading_text}\\n {rendered}")', + content +) + +content = re.sub( + r'evidence_lines\.append\(f"- 《\{item_title\}》:\{excerpt\}"\)', + r'evidence_lines.append(f"- **《{item_title}》**:{excerpt}")', + content +) + +with open(file_path, 'w', encoding='utf-8') as f: + f.write(content) +print('Done.') diff --git a/fix_response.py b/fix_response.py new file mode 100644 index 0000000..9e9a132 --- /dev/null +++ b/fix_response.py @@ -0,0 +1,15 @@ +import re + +file_path = 'server/src/app/services/user_agent_response.py' +with open(file_path, 'r', encoding='utf-8') as f: + content = f.read() + +content = re.sub( + r'\s*"fallback_answer": fallback_answer,', + '', + content +) + +with open(file_path, 'w', encoding='utf-8') as f: + f.write(content) +print('Done.') diff --git a/server/rules/risk-rules/risk.expense.consecutive_transport_receipts.json b/server/rules/risk-rules/risk.expense.consecutive_transport_receipts.json deleted file mode 100644 index 5354d20..0000000 --- a/server/rules/risk-rules/risk.expense.consecutive_transport_receipts.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "schema_version": "1.0", - "rule_code": "risk.expense.consecutive_transport_receipts", - "name": "连号交通票据", - "enabled": true, - "risk_dimension": "consecutive_receipts", - "ontology_signal": "consecutive_transport_receipts", - "evaluator": "consecutive_transport_receipts", - "applies_to": { - "expense_types": ["transport", "travel"], - "min_attachments": 2 - }, - "inputs": { - "invoice_no": "attachment.invoice_no" - }, - "params": { - "min_consecutive_count": 3 - }, - "outcomes": { - "pass": { "severity": "none", "action": "continue" }, - "fail": { - "severity": "medium", - "action": "manual_review" - } - }, - "metadata": { - "owner": "风控与审计部", - "stability": "platform_builtin", - "source_ref": "常用risk.txt / 三、车辆交通 / 连号票集中报销", - "updated_at": "2026-05-19" - } -} diff --git a/server/rules/risk-rules/risk.expense.entertainment_missing_detail.json b/server/rules/risk-rules/risk.expense.entertainment_missing_detail.json deleted file mode 100644 index d3735da..0000000 --- a/server/rules/risk-rules/risk.expense.entertainment_missing_detail.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "schema_version": "1.0", - "rule_code": "risk.expense.entertainment_missing_detail", - "name": "招待费事由不完整", - "enabled": true, - "risk_dimension": "entertainment_detail", - "ontology_signal": "entertainment_missing_detail", - "evaluator": "entertainment_reason_missing", - "applies_to": { - "domains": ["meal"] - }, - "inputs": { - "reason": "claim.reason_corpus" - }, - "params": {}, - "outcomes": { - "pass": { "severity": "none", "action": "continue" }, - "fail": { - "severity": "medium", - "action": "warn" - } - }, - "metadata": { - "owner": "风控与审计部", - "stability": "platform_builtin", - "source_ref": "常用risk.txt / 三、餐费招待 / 业务招待无事由对象", - "updated_at": "2026-05-19" - } -} diff --git a/server/rules/risk-rules/risk.expense.generated_20260523010818.json b/server/rules/risk-rules/risk.expense.generated_20260523010818.json deleted file mode 100644 index 54bee5a..0000000 --- a/server/rules/risk-rules/risk.expense.generated_20260523010818.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "schema_version": "2.0", - "rule_code": "risk.expense.generated_20260523010818", - "name": "住宿城市必须出现在本次差旅行程城市中风险规则", - "description": "当报销业务满足“住宿城市必须出现在本次差旅行程城市中,如果酒店发票城市与申报目的地或交通票行程城市都不一致,则判定为高风险,并要求补充差旅说明。”时,系统会按高风险进行提示,并要求经办人或审核人补充核对依据。", - "enabled": true, - "risk_dimension": "natural_language_rule", - "risk_category": "报销", - "ontology_signal": "natural_language_risk", - "evaluator": "template_rule", - "template_key": "field_compare_v1", - "applies_to": { - "domains": [ - "expense" - ] - }, - "inputs": { - "fields": [ - { - "key": "claim.reason", - "label": "报销事由", - "type": "text", - "source": "claim" - }, - { - "key": "claim.location", - "label": "申报地点", - "type": "text", - "source": "claim" - }, - { - "key": "attachment.hotel_city", - "label": "住宿城市", - "type": "text", - "source": "attachment" - }, - { - "key": "attachment.route_cities", - "label": "行程城市", - "type": "list", - "source": "attachment" - } - ] - }, - "params": { - "template_key": "field_compare_v1", - "field_keys": [ - "claim.reason", - "claim.location", - "attachment.hotel_city", - "attachment.route_cities" - ], - "condition_summary": "对比报销事由、申报地点、住宿城市之间是否一致或存在交集", - "natural_language": "住宿城市必须出现在本次差旅行程城市中,如果酒店发票城市与申报目的地或交通票行程城市都不一致,则判定为高风险,并要求补充差旅说明。", - "conditions": [ - { - "left": "claim.reason", - "operator": "overlap", - "right": "claim.location" - } - ] - }, - "outcomes": { - "pass": { - "severity": "none", - "action": "continue" - }, - "fail": { - "severity": "high", - "action": "manual_review" - } - }, - "metadata": { - "owner": "WangMin", - "stability": "generated_draft", - "source_ref": "自然语言风险规则", - "created_at": "2026-05-23T01:08:18.310751+00:00", - "created_by": "WangMin", - "natural_language": "住宿城市必须出现在本次差旅行程城市中,如果酒店发票城市与申报目的地或交通票行程城市都不一致,则判定为高风险,并要求补充差旅说明。", - "business_explanation": "当报销业务满足“住宿城市必须出现在本次差旅行程城市中,如果酒店发票城市与申报目的地或交通票行程城市都不一致,则判定为高风险,并要求补充差旅说明。”时,系统会按高风险进行提示,并要求经办人或审核人补充核对依据。", - "condition_summary": "对比报销事由、申报地点、住宿城市之间是否一致或存在交集", - "flow": { - "start": "报销单据提交", - "evidence": "读取报销事由、申报地点、住宿城市", - "decision": "对比报销事由、申报地点、住宿城市之间是否一致或存在交集", - "pass": "未命中风险,继续业务流转", - "fail": "命中高风险,提示复核" - } - } -} diff --git a/server/rules/risk-rules/risk.expense.generated_20260523010846.json b/server/rules/risk-rules/risk.expense.generated_20260523010846.json deleted file mode 100644 index 32da0d5..0000000 --- a/server/rules/risk-rules/risk.expense.generated_20260523010846.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "schema_version": "2.0", - "rule_code": "risk.expense.generated_20260523010846", - "name": "酒店发票城市必须与申报目的地或交通票风险规则", - "description": "当报销业务满足“酒店发票城市必须与申报目的地或交通票行程城市一致,如果都不一致,则判定为高风险,并要求报销人补充异常行程说明。”时,系统会按高风险进行提示,并要求经办人或审核人补充核对依据。", - "enabled": true, - "risk_dimension": "natural_language_rule", - "risk_category": "报销", - "ontology_signal": "natural_language_risk", - "evaluator": "template_rule", - "template_key": "field_compare_v1", - "applies_to": { - "domains": [ - "expense" - ] - }, - "inputs": { - "fields": [ - { - "key": "claim.reason", - "label": "报销事由", - "type": "text", - "source": "claim" - }, - { - "key": "claim.location", - "label": "申报地点", - "type": "text", - "source": "claim" - }, - { - "key": "claim.employee_name", - "label": "报销人", - "type": "text", - "source": "claim" - }, - { - "key": "attachment.route_cities", - "label": "行程城市", - "type": "list", - "source": "attachment" - } - ] - }, - "params": { - "template_key": "field_compare_v1", - "field_keys": [ - "claim.reason", - "claim.location", - "claim.employee_name", - "attachment.route_cities" - ], - "condition_summary": "对比报销事由、申报地点、报销人之间是否一致或存在交集", - "natural_language": "酒店发票城市必须与申报目的地或交通票行程城市一致,如果都不一致,则判定为高风险,并要求报销人补充异常行程说明。", - "conditions": [ - { - "left": "claim.reason", - "operator": "overlap", - "right": "claim.location" - } - ] - }, - "outcomes": { - "pass": { - "severity": "none", - "action": "continue" - }, - "fail": { - "severity": "high", - "action": "manual_review" - } - }, - "metadata": { - "owner": "min.wang@xfinance.com", - "stability": "generated_draft", - "source_ref": "自然语言风险规则", - "created_at": "2026-05-23T01:08:46.286513+00:00", - "created_by": "min.wang@xfinance.com", - "natural_language": "酒店发票城市必须与申报目的地或交通票行程城市一致,如果都不一致,则判定为高风险,并要求报销人补充异常行程说明。", - "business_explanation": "当报销业务满足“酒店发票城市必须与申报目的地或交通票行程城市一致,如果都不一致,则判定为高风险,并要求报销人补充异常行程说明。”时,系统会按高风险进行提示,并要求经办人或审核人补充核对依据。", - "condition_summary": "对比报销事由、申报地点、报销人之间是否一致或存在交集", - "flow": { - "start": "报销单据提交", - "evidence": "读取报销事由、申报地点、报销人", - "decision": "对比报销事由、申报地点、报销人之间是否一致或存在交集", - "pass": "未命中风险,继续业务流转", - "fail": "命中高风险,提示复核" - } - } -} diff --git a/server/rules/risk-rules/risk.expense.generated_20260523011139.json b/server/rules/risk-rules/risk.expense.generated_20260523011139.json deleted file mode 100644 index e97c5c7..0000000 --- a/server/rules/risk-rules/risk.expense.generated_20260523011139.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "schema_version": "2.0", - "rule_code": "risk.expense.generated_20260523011139", - "name": "酒店发票城市一致性校验", - "description": "校验酒店发票城市是否与申报目的地或行程城市一致,不一致时标记为高风险并要求补充说明", - "enabled": true, - "risk_dimension": "natural_language_rule", - "risk_category": "报销", - "ontology_signal": "natural_language_risk", - "evaluator": "template_rule", - "template_key": "field_compare_v1", - "applies_to": { - "domains": [ - "expense" - ] - }, - "inputs": { - "fields": [ - { - "key": "attachment.route_cities", - "label": "行程城市", - "type": "list", - "source": "attachment" - }, - { - "key": "claim.location", - "label": "申报地点", - "type": "text", - "source": "claim" - }, - { - "key": "attachment.hotel_city", - "label": "住宿城市", - "type": "text", - "source": "attachment" - }, - { - "key": "claim.reason", - "label": "报销事由", - "type": "text", - "source": "claim" - } - ] - }, - "params": { - "template_key": "field_compare_v1", - "field_keys": [ - "attachment.hotel_city", - "claim.location", - "attachment.route_cities", - "claim.reason" - ], - "condition_summary": "对比住宿城市、申报地点、行程城市之间是否一致或存在交集", - "natural_language": "酒店发票城市必须与申报目的地或交通票行程城市一致,如果都不一致,则判定为高风险,并要求补充异常行程说明。", - "conditions": [ - { - "left": "attachment.hotel_city", - "operator": "overlap", - "right": "claim.location" - } - ] - }, - "outcomes": { - "pass": { - "severity": "none", - "action": "continue" - }, - "fail": { - "severity": "high", - "action": "manual_review" - } - }, - "metadata": { - "owner": "WangMin", - "stability": "generated_draft", - "source_ref": "自然语言风险规则", - "created_at": "2026-05-23T01:11:39.165281+00:00", - "created_by": "WangMin", - "natural_language": "酒店发票城市必须与申报目的地或交通票行程城市一致,如果都不一致,则判定为高风险,并要求补充异常行程说明。", - "business_explanation": "校验酒店发票城市是否与申报目的地或行程城市一致,不一致时标记为高风险并要求补充说明", - "condition_summary": "对比住宿城市、申报地点、行程城市之间是否一致或存在交集", - "flow": { - "start": "提交酒店发票", - "evidence": "读取住宿城市、申报地点、行程城市", - "decision": "对比住宿城市、申报地点、行程城市之间是否一致或存在交集", - "pass": "继续流转", - "fail": "提示高风险:酒店发票城市与申报目的地及行程城市均不一致,需补充异常行程说明" - } - } -} diff --git a/server/rules/risk-rules/risk.expense.meal_localized_as_travel.json b/server/rules/risk-rules/risk.expense.meal_localized_as_travel.json deleted file mode 100644 index 7dd9386..0000000 --- a/server/rules/risk-rules/risk.expense.meal_localized_as_travel.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "schema_version": "1.0", - "rule_code": "risk.expense.meal_localized_as_travel", - "name": "同城餐饮混入差旅", - "enabled": true, - "risk_dimension": "meal_travel_mix", - "ontology_signal": "meal_as_travel", - "evaluator": "meal_as_travel_same_city", - "applies_to": { - "domains": ["travel"] - }, - "inputs": { - "declared": "claim.location", - "meal_city": "attachment.cities" - }, - "params": {}, - "outcomes": { - "pass": { "severity": "none", "action": "continue" }, - "fail": { - "severity": "medium", - "action": "warn" - } - }, - "metadata": { - "owner": "风控与审计部", - "stability": "platform_builtin", - "source_ref": "常用risk.txt / 三、餐费招待 / 同城餐饮归集异地差旅", - "updated_at": "2026-05-19" - } -} diff --git a/server/rules/risk-rules/risk.expense.reason_too_brief.json b/server/rules/risk-rules/risk.expense.reason_too_brief.json deleted file mode 100644 index 3a7149b..0000000 --- a/server/rules/risk-rules/risk.expense.reason_too_brief.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "schema_version": "1.0", - "rule_code": "risk.expense.reason_too_brief", - "name": "报销事由过短", - "enabled": true, - "risk_dimension": "reason_quality", - "ontology_signal": "reason_too_brief", - "evaluator": "reason_too_brief", - "applies_to": {}, - "inputs": { - "reason": "claim.reason_corpus" - }, - "params": { - "min_reason_length": 6 - }, - "outcomes": { - "pass": { "severity": "none", "action": "continue" }, - "fail": { - "severity": "medium", - "action": "warn" - } - }, - "metadata": { - "owner": "风控与审计部", - "stability": "platform_builtin", - "source_ref": "常用risk.txt / 通用 / 事由不足以支撑真实性判断", - "updated_at": "2026-05-19" - } -} diff --git a/server/rules/risk-rules/risk.invoice.claimant_buyer_name_match.json b/server/rules/risk-rules/risk.invoice.claimant_buyer_name_match.json deleted file mode 100644 index 5122744..0000000 --- a/server/rules/risk-rules/risk.invoice.claimant_buyer_name_match.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "schema_version": "1.0", - "rule_code": "risk.invoice.claimant_buyer_name_match", - "name": "报销人与发票抬头一致", - "enabled": true, - "risk_dimension": "identity_consistency", - "ontology_signal": "buyer_name_mismatch", - "evaluator": "identity_consistency", - "applies_to": { - "min_attachments": 1 - }, - "inputs": { - "claimant": "claim.employee_name", - "buyer": "attachment.buyer_name" - }, - "params": { - "allow_keywords": ["代报", "集团", "公司", "有限公司"] - }, - "outcomes": { - "pass": { "severity": "none", "action": "continue" }, - "fail": { - "severity": "high", - "action": "manual_review" - } - }, - "metadata": { - "owner": "风控与审计部", - "stability": "platform_builtin", - "source_ref": "常用risk.txt / 二、发票类 / 抬头错误", - "updated_at": "2026-05-19" - } -} diff --git a/server/rules/risk-rules/risk.invoice.cross_year_invoice.json b/server/rules/risk-rules/risk.invoice.cross_year_invoice.json deleted file mode 100644 index 0f95492..0000000 --- a/server/rules/risk-rules/risk.invoice.cross_year_invoice.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "schema_version": "1.0", - "rule_code": "risk.invoice.cross_year_invoice", - "name": "跨年发票入账", - "enabled": true, - "risk_dimension": "cross_year_invoice", - "ontology_signal": "cross_year_invoice", - "evaluator": "cross_year_invoice", - "applies_to": { - "min_attachments": 1 - }, - "inputs": { - "invoice_date": "attachment.invoice_date", - "claim_date": ["claim.occurred_at", "item.item_date"] - }, - "params": {}, - "outcomes": { - "pass": { "severity": "none", "action": "continue" }, - "fail": { - "severity": "medium", - "action": "warn" - } - }, - "metadata": { - "owner": "风控与审计部", - "stability": "platform_builtin", - "source_ref": "常用risk.txt / 二、发票类 / 跨年发票", - "updated_at": "2026-05-19" - } -} diff --git a/server/rules/risk-rules/risk.invoice.document_expense_mismatch.json b/server/rules/risk-rules/risk.invoice.document_expense_mismatch.json deleted file mode 100644 index 487287c..0000000 --- a/server/rules/risk-rules/risk.invoice.document_expense_mismatch.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "schema_version": "1.0", - "rule_code": "risk.invoice.document_expense_mismatch", - "name": "开票内容与报销场景不符", - "enabled": true, - "risk_dimension": "document_expense_mismatch", - "ontology_signal": "document_expense_mismatch", - "evaluator": "document_expense_mismatch", - "applies_to": { - "min_attachments": 1 - }, - "inputs": { - "document_type": "attachment.document_type", - "expense_type": ["claim.expense_type", "item.item_type"] - }, - "params": {}, - "outcomes": { - "pass": { "severity": "none", "action": "continue" }, - "fail": { - "severity": "medium", - "action": "warn" - } - }, - "metadata": { - "owner": "风控与审计部", - "stability": "platform_builtin", - "source_ref": "常用risk.txt / 二、发票类 / 开票内容与业务不符", - "updated_at": "2026-05-19" - } -} diff --git a/server/rules/risk-rules/risk.invoice.duplicate_invoice.json b/server/rules/risk-rules/risk.invoice.duplicate_invoice.json deleted file mode 100644 index 60632d9..0000000 --- a/server/rules/risk-rules/risk.invoice.duplicate_invoice.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "schema_version": "1.0", - "rule_code": "risk.invoice.duplicate_invoice", - "name": "发票重复报销", - "enabled": true, - "risk_dimension": "duplicate_invoice", - "ontology_signal": "duplicate_invoice", - "evaluator": "duplicate_invoice", - "applies_to": { - "min_attachments": 1 - }, - "inputs": { - "invoice_no": "attachment.invoice_no" - }, - "params": {}, - "outcomes": { - "pass": { "severity": "none", "action": "continue" }, - "fail": { - "severity": "high", - "action": "block" - } - }, - "metadata": { - "owner": "风控与审计部", - "stability": "platform_builtin", - "source_ref": "常用risk.txt / 二、发票类 / 重复报销", - "updated_at": "2026-05-19" - } -} diff --git a/server/rules/risk-rules/risk.invoice.vague_goods_description.json b/server/rules/risk-rules/risk.invoice.vague_goods_description.json deleted file mode 100644 index 942e9bb..0000000 --- a/server/rules/risk-rules/risk.invoice.vague_goods_description.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "schema_version": "1.0", - "rule_code": "risk.invoice.vague_goods_description", - "name": "发票品名过于笼统", - "enabled": true, - "risk_dimension": "vague_goods_description", - "ontology_signal": "vague_goods_description", - "evaluator": "vague_goods_description", - "applies_to": { - "expense_types": ["office", "other"], - "min_attachments": 1 - }, - "inputs": { - "ocr": "attachment.ocr_text" - }, - "params": {}, - "outcomes": { - "pass": { "severity": "none", "action": "continue" }, - "fail": { - "severity": "medium", - "action": "warn" - } - }, - "metadata": { - "owner": "风控与审计部", - "stability": "platform_builtin", - "source_ref": "常用risk.txt / 二、发票类 / 品名笼统", - "updated_at": "2026-05-19" - } -} diff --git a/server/rules/risk-rules/risk.invoice.void_or_red_invoice.json b/server/rules/risk-rules/risk.invoice.void_or_red_invoice.json deleted file mode 100644 index 9cb9185..0000000 --- a/server/rules/risk-rules/risk.invoice.void_or_red_invoice.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "schema_version": "1.0", - "rule_code": "risk.invoice.void_or_red_invoice", - "name": "作废或红冲发票", - "enabled": true, - "risk_dimension": "void_or_red_invoice", - "ontology_signal": "void_or_red_invoice", - "evaluator": "invoice_void_or_red", - "applies_to": { - "min_attachments": 1 - }, - "inputs": { - "status": "attachment.invoice_status", - "ocr": "attachment.ocr_text" - }, - "params": {}, - "outcomes": { - "pass": { "severity": "none", "action": "continue" }, - "fail": { - "severity": "high", - "action": "block" - } - }, - "metadata": { - "owner": "风控与审计部", - "stability": "platform_builtin", - "source_ref": "常用risk.txt / 二、发票类 / 作废红冲发票", - "updated_at": "2026-05-19" - } -} diff --git a/server/rules/risk-rules/risk.travel.base_location_overlap.json b/server/rules/risk-rules/risk.travel.base_location_overlap.json deleted file mode 100644 index 0bbffa3..0000000 --- a/server/rules/risk-rules/risk.travel.base_location_overlap.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "schema_version": "1.0", - "rule_code": "risk.travel.base_location_overlap", - "name": "常驻地重合出差风险", - "enabled": true, - "risk_dimension": "base_location_overlap", - "ontology_signal": "base_location_overlap", - "evaluator": "base_location_overlap", - "applies_to": { - "domains": ["travel"] - }, - "inputs": { - "employee_base": "employee.location", - "declared": "claim.location" - }, - "params": {}, - "outcomes": { - "pass": { "severity": "none", "action": "continue" }, - "fail": { - "severity": "high", - "action": "manual_review" - } - }, - "metadata": { - "owner": "风控与审计部", - "stability": "platform_builtin", - "source_ref": "常用risk.txt / 一、出差类 / 两头在外", - "updated_at": "2026-05-19" - } -} diff --git a/server/rules/risk-rules/risk.travel.destination_receipt_location.json b/server/rules/risk-rules/risk.travel.destination_receipt_location.json deleted file mode 100644 index a54c346..0000000 --- a/server/rules/risk-rules/risk.travel.destination_receipt_location.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "schema_version": "1.0", - "rule_code": "risk.travel.destination_receipt_location", - "name": "申报地点与票据地点一致", - "risk_dimension": "location_consistency", - "ontology_signal": "location_mismatch", - "evaluator": "location_consistency", - "inputs": { - "declared": "claim.location", - "evidence": ["attachment.cities", "item.item_location"] - }, - "params": { - "match_mode": "city_fuzzy", - "missing_evidence": "warn" - }, - "outcomes": { - "pass": { "severity": "none", "action": "continue" }, - "fail": { - "severity": "high", - "action": "manual_review", - "message_template": "申报地点 {declared} 与票据识别地点 {evidence} 不一致" - } - }, - "metadata": { - "owner": "风控与审计部", - "stability": "platform_builtin", - "updated_at": "2026-05-18" - } -} diff --git a/server/rules/risk-rules/risk.travel.hotel_without_itinerary.json b/server/rules/risk-rules/risk.travel.hotel_without_itinerary.json deleted file mode 100644 index 1c5fce7..0000000 --- a/server/rules/risk-rules/risk.travel.hotel_without_itinerary.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "schema_version": "1.0", - "rule_code": "risk.travel.hotel_without_itinerary", - "name": "住宿城市与行程不一致", - "enabled": true, - "risk_dimension": "hotel_itinerary", - "ontology_signal": "hotel_itinerary_mismatch", - "evaluator": "hotel_without_itinerary", - "applies_to": { - "domains": ["travel"], - "expense_types": ["hotel", "travel"] - }, - "inputs": { - "declared": "claim.location", - "hotel": "attachment.hotel_city", - "itinerary": "attachment.route_cities" - }, - "params": {}, - "outcomes": { - "pass": { "severity": "none", "action": "continue" }, - "fail": { - "severity": "high", - "action": "manual_review" - } - }, - "metadata": { - "owner": "风控与审计部", - "stability": "platform_builtin", - "source_ref": "常用risk.txt / 三、住宿费 / 夜间异地住宿、酒店连续多天", - "updated_at": "2026-05-19" - } -} diff --git a/server/rules/risk-rules/risk.travel.intracity_travel_claim.json b/server/rules/risk-rules/risk.travel.intracity_travel_claim.json deleted file mode 100644 index 64f2ddd..0000000 --- a/server/rules/risk-rules/risk.travel.intracity_travel_claim.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "schema_version": "1.0", - "rule_code": "risk.travel.intracity_travel_claim", - "name": "同城虚报差旅补贴", - "enabled": true, - "risk_dimension": "intracity_travel", - "ontology_signal": "intracity_travel", - "evaluator": "intracity_travel_claim", - "applies_to": { - "domains": ["travel"] - }, - "inputs": { - "declared": "claim.location", - "evidence": ["attachment.route", "attachment.cities"] - }, - "params": {}, - "outcomes": { - "pass": { "severity": "none", "action": "continue" }, - "fail": { - "severity": "high", - "action": "manual_review" - } - }, - "metadata": { - "owner": "风控与审计部", - "stability": "platform_builtin", - "source_ref": "常用risk.txt / 一、出差类 / 同城虚报差旅", - "updated_at": "2026-05-19" - } -} diff --git a/server/rules/risk-rules/risk.travel.multi_city_reason_required.json b/server/rules/risk-rules/risk.travel.multi_city_reason_required.json deleted file mode 100644 index 2554f1c..0000000 --- a/server/rules/risk-rules/risk.travel.multi_city_reason_required.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "schema_version": "1.0", - "rule_code": "risk.travel.multi_city_reason_required", - "name": "多城市行程需说明", - "enabled": true, - "risk_dimension": "multi_city_itinerary", - "ontology_signal": "multi_city_itinerary", - "evaluator": "multi_city_reason_required", - "applies_to": { - "domains": ["travel"] - }, - "inputs": { - "reason": "claim.reason_corpus", - "cities": ["attachment.cities", "item.item_location"] - }, - "params": {}, - "outcomes": { - "pass": { "severity": "none", "action": "continue" }, - "fail": { - "severity": "medium", - "action": "warn" - } - }, - "metadata": { - "owner": "风控与审计部", - "stability": "platform_builtin", - "source_ref": "常用risk.txt / 一、出差类 / 绕道出行、行程不符", - "updated_at": "2026-05-19" - } -} diff --git a/server/scripts/start_hermes_daemon.py b/server/scripts/start_hermes_daemon.py new file mode 100644 index 0000000..94e0cd1 --- /dev/null +++ b/server/scripts/start_hermes_daemon.py @@ -0,0 +1,68 @@ +import os +import sys +import time +import logging + +# Ensure src is in the python path +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../src"))) + +from app.core.logging import setup_logging +from app.db.session import get_session_factory +from app.models.hermes_config import HermesTaskConfig +from app.services.hermes_scheduler import hermes_scheduler + +logger = logging.getLogger("hermes_daemon") + +def init_default_config(): + """Ensure there is at least one active global_risk_scan task in the database.""" + session_factory = get_session_factory() + db = session_factory() + try: + # 初始化 global_risk_scan + existing_risk = db.query(HermesTaskConfig).filter_by(task_type="global_risk_scan").first() + if not existing_risk: + logger.info("No global_risk_scan config found. Initializing default config.") + db.add(HermesTaskConfig( + task_type="global_risk_scan", + cron_expression="0 2 * * *", + is_enabled=True + )) + + # 初始化 weekly_expense_report + existing_report = db.query(HermesTaskConfig).filter_by(task_type="weekly_expense_report").first() + if not existing_report: + logger.info("No weekly_expense_report config found. Initializing default config.") + db.add(HermesTaskConfig( + task_type="weekly_expense_report", + cron_expression="0 9 * * 1", # 每周一早9点(在简化版中暂时代表周报频率) + is_enabled=True + )) + + db.commit() + except Exception as e: + logger.error(f"Failed to initialize default config: {e}") + finally: + db.close() + + +def main(): + setup_logging() + logger.info("Initializing Hermes Background Daemon...") + + # 注入默认配置 + init_default_config() + + # 启动调度器 + hermes_scheduler.start() + + logger.info("Hermes Daemon is running. Press Ctrl+C to stop.") + try: + while True: + time.sleep(1) # 主线程保持存活 + except KeyboardInterrupt: + logger.info("Keyboard interrupt received. Shutting down...") + hermes_scheduler.shutdown() + logger.info("Shutdown complete.") + +if __name__ == "__main__": + main() diff --git a/server/src/app/api/v1/endpoints/agent_assets.py b/server/src/app/api/v1/endpoints/agent_assets.py index d1ad2f6..570a52f 100644 --- a/server/src/app/api/v1/endpoints/agent_assets.py +++ b/server/src/app/api/v1/endpoints/agent_assets.py @@ -23,7 +23,16 @@ from app.schemas.agent_asset import ( AgentAssetRead, AgentAssetReviewCreate, AgentAssetReviewRead, + AgentAssetRiskRuleEnabledUpdate, AgentAssetRiskRuleGenerateRequest, + AgentAssetRiskRuleLatestTestSummary, + AgentAssetRiskRuleReportRequest, + AgentAssetRiskRuleReturnRequest, + AgentAssetRiskRuleSampleTestRequest, + AgentAssetRiskRuleScenarioTestRequest, + AgentAssetRiskRuleSimulationRead, + AgentAssetRiskRuleSimulationRequest, + AgentAssetRiskRuleTestRunRead, AgentAssetRuleJsonRead, AgentAssetRuleJsonWrite, AgentAssetSpreadsheetChangeRecordRead, @@ -131,6 +140,116 @@ def get_agent_asset_rule_json( _handle_asset_error(exc) +@router.get( + "/{asset_id}/risk-rule-tests/latest", + response_model=AgentAssetRiskRuleLatestTestSummary, + summary="读取风险规则最近测试摘要", + description="返回当前风险规则工作版本最近一次样例测试、场景试运行和测试报告。", +) +def get_agent_asset_risk_rule_latest_test( + asset_id: str, + _: CurrentUser, + db: DbSession, +) -> AgentAssetRiskRuleLatestTestSummary: + try: + return AgentAssetService(db).get_latest_risk_rule_test_summary(asset_id) + except Exception as exc: + _handle_asset_error(exc) + + +@router.post( + "/{asset_id}/risk-rule-tests/simulate", + response_model=AgentAssetRiskRuleSimulationRead, + summary="执行风险规则对话仿真", + description="基于临时对话输入和附件元信息执行风险识别,不创建业务单据,不写入测试记录。", +) +def simulate_agent_asset_risk_rule_test( + asset_id: str, + payload: AgentAssetRiskRuleSimulationRequest, + _: RuleEditorUser, + db: DbSession, +) -> AgentAssetRiskRuleSimulationRead: + try: + return AgentAssetService(db).simulate_risk_rule_message(asset_id, payload) + except Exception as exc: + _handle_asset_error(exc) + + +@router.post( + "/{asset_id}/risk-rule-tests/sample", + response_model=AgentAssetRiskRuleTestRunRead, + summary="执行风险规则快速样例测试", + description="使用人工样例或系统默认样例执行当前 JSON 风险规则,不依赖大模型判断结果。", +) +def run_agent_asset_risk_rule_sample_test( + asset_id: str, + payload: AgentAssetRiskRuleSampleTestRequest, + current_user: RuleEditorUser, + db: DbSession, + x_actor: ActorHeader = None, + x_request_id: RequestIdHeader = None, +) -> AgentAssetRiskRuleTestRunRead: + try: + return AgentAssetService(db).run_risk_rule_sample_test( + asset_id, + payload, + actor=(x_actor or current_user.name or "system").strip() or "system", + request_id=x_request_id, + ) + except Exception as exc: + _handle_asset_error(exc) + + +@router.post( + "/{asset_id}/risk-rule-tests/scenario", + response_model=AgentAssetRiskRuleTestRunRead, + summary="执行风险规则真实场景试运行", + description="按测试意图读取真实业务样本并沙盒执行风险规则,不写回业务单据。", +) +def run_agent_asset_risk_rule_scenario_test( + asset_id: str, + payload: AgentAssetRiskRuleScenarioTestRequest, + current_user: RuleEditorUser, + db: DbSession, + x_actor: ActorHeader = None, + x_request_id: RequestIdHeader = None, +) -> AgentAssetRiskRuleTestRunRead: + try: + return AgentAssetService(db).run_risk_rule_scenario_test( + asset_id, + payload, + actor=(x_actor or current_user.name or "system").strip() or "system", + request_id=x_request_id, + ) + except Exception as exc: + _handle_asset_error(exc) + + +@router.post( + "/{asset_id}/risk-rule-tests/report", + response_model=AgentAssetRiskRuleTestRunRead, + summary="确认风险规则测试报告", + description="在样例测试和真实场景试运行通过后,保存当前版本测试通过记录。", +) +def confirm_agent_asset_risk_rule_test_report( + asset_id: str, + payload: AgentAssetRiskRuleReportRequest, + current_user: RuleEditorUser, + db: DbSession, + x_actor: ActorHeader = None, + x_request_id: RequestIdHeader = None, +) -> AgentAssetRiskRuleTestRunRead: + try: + return AgentAssetService(db).confirm_risk_rule_test_report( + asset_id, + payload, + actor=(x_actor or current_user.name or "system").strip() or "system", + request_id=x_request_id, + ) + except Exception as exc: + _handle_asset_error(exc) + + @router.put( "/{asset_id}/rule-json", response_model=AgentAssetRuleJsonRead, @@ -586,6 +705,112 @@ def activate_agent_asset( _handle_asset_error(exc) +@router.post( + "/{asset_id}/risk-rule-enabled", + response_model=AgentAssetRead, + summary="设置风险规则启用状态", + description=( + "高级管理人员可独立启用或停用 JSON 风险规则;停用后即使已上线也不会进入真实业务扫描。" + ), +) +def set_agent_asset_risk_rule_enabled( + asset_id: str, + payload: AgentAssetRiskRuleEnabledUpdate, + current_user: RuleReviewerUser, + db: DbSession, + x_actor: ActorHeader = None, + x_request_id: RequestIdHeader = None, +) -> AgentAssetRead: + try: + asset = AgentAssetService(db).set_risk_rule_enabled( + asset_id, + enabled=payload.enabled, + actor=(x_actor or current_user.name or "system").strip() or "system", + request_id=x_request_id, + ) + detail = AgentAssetService(db).get_asset(asset.id) + if detail is None: + raise LookupError("Asset not found") + return detail + except Exception as exc: + _handle_asset_error(exc) + + +@router.post( + "/{asset_id}/return", + response_model=AgentAssetRiskRuleLatestTestSummary, + summary="回退待审核风险规则", + description="高级管理人员将待审核风险规则回退到草稿,并记录回退原因。", +) +def return_agent_asset_risk_rule( + asset_id: str, + payload: AgentAssetRiskRuleReturnRequest, + current_user: RuleReviewerUser, + db: DbSession, + x_actor: ActorHeader = None, + x_request_id: RequestIdHeader = None, +) -> AgentAssetRiskRuleLatestTestSummary: + try: + return AgentAssetService(db).return_risk_rule( + asset_id, + note=payload.note, + actor=(x_actor or current_user.name or "system").strip() or "system", + request_id=x_request_id, + ) + except Exception as exc: + _handle_asset_error(exc) + + +@router.post( + "/{asset_id}/publish", + response_model=AgentAssetRead, + summary="审核并发布风险规则", + description="高级管理人员确认测试通过后,将待审核风险规则一次性审核通过并发布上线。", +) +def publish_agent_asset_risk_rule( + asset_id: str, + current_user: RuleReviewerUser, + db: DbSession, + x_actor: ActorHeader = None, + x_request_id: RequestIdHeader = None, +) -> AgentAssetRead: + try: + asset = AgentAssetService(db).publish_risk_rule( + asset_id, + actor=(x_actor or current_user.name or "system").strip() or "system", + request_id=x_request_id, + ) + detail = AgentAssetService(db).get_asset(asset.id) + if detail is None: + raise LookupError("Asset not found") + return detail + except Exception as exc: + _handle_asset_error(exc) + + +@router.delete( + "/{asset_id}", + status_code=status.HTTP_204_NO_CONTENT, + summary="删除未发布风险规则", + description="仅允许删除从未发布过的 JSON 风险规则,并同步删除规则 JSON 文件。", +) +def delete_agent_asset( + asset_id: str, + current_user: RuleEditorUser, + db: DbSession, + x_actor: ActorHeader = None, + x_request_id: RequestIdHeader = None, +) -> None: + try: + AgentAssetService(db).delete_unpublished_asset( + asset_id, + actor=(x_actor or current_user.name or "system").strip() or "system", + request_id=x_request_id, + ) + except Exception as exc: + _handle_asset_error(exc) + + @router.post( "/{asset_id}/versions/{version}/restore", response_model=AgentAssetRead, diff --git a/server/src/app/db/base.py b/server/src/app/db/base.py index fd65bfb..fddcc46 100644 --- a/server/src/app/db/base.py +++ b/server/src/app/db/base.py @@ -1,6 +1,6 @@ from app.db.base_class import Base from app.models.agent_conversation import AgentConversation, AgentConversationMessage -from app.models.agent_asset import AgentAsset, AgentAssetReview, AgentAssetVersion +from app.models.agent_asset import AgentAsset, AgentAssetReview, AgentAssetTestRun, AgentAssetVersion from app.models.agent_run import AgentRun, AgentToolCall, SemanticParseLog from app.models.approval import ApprovalRecord from app.models.audit_log import AuditLog @@ -27,6 +27,7 @@ __all__ = [ "AgentConversationMessage", "AgentAsset", "AgentAssetReview", + "AgentAssetTestRun", "AgentAssetVersion", "AgentRun", "AgentToolCall", diff --git a/server/src/app/models/__init__.py b/server/src/app/models/__init__.py index 6544cc1..f3b07a1 100644 --- a/server/src/app/models/__init__.py +++ b/server/src/app/models/__init__.py @@ -11,6 +11,8 @@ from app.models.financial_record import ( ExpenseClaim, ExpenseClaimItem, ) +from app.models.hermes_config import HermesTaskConfig, HermesTaskExecutionLog +from app.models.hermes_report import HermesRiskReport from app.models.organization import OrganizationUnit from app.models.reimbursement import ReimbursementRequest from app.models.role import Role @@ -34,6 +36,9 @@ __all__ = [ "EmployeeChangeLog", "ExpenseClaim", "ExpenseClaimItem", + "HermesTaskConfig", + "HermesTaskExecutionLog", + "HermesRiskReport", "OrganizationUnit", "ReimbursementRequest", "Role", diff --git a/server/src/app/models/agent_asset.py b/server/src/app/models/agent_asset.py index 4ac1f45..a6e79a0 100644 --- a/server/src/app/models/agent_asset.py +++ b/server/src/app/models/agent_asset.py @@ -4,7 +4,7 @@ import uuid from datetime import datetime from typing import Any -from sqlalchemy import DateTime, ForeignKey, String, Text, UniqueConstraint, func +from sqlalchemy import Boolean, DateTime, ForeignKey, String, Text, UniqueConstraint, func from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.types import JSON @@ -46,6 +46,12 @@ class AgentAsset(Base): order_by="desc(AgentAssetReview.created_at)", ) scheduled_runs = relationship("AgentRun", back_populates="task_asset") + test_runs = relationship( + "AgentAssetTestRun", + back_populates="asset", + cascade="all, delete-orphan", + order_by="desc(AgentAssetTestRun.created_at)", + ) class AgentAssetVersion(Base): @@ -79,3 +85,21 @@ class AgentAssetReview(Base): created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) asset = relationship("AgentAsset", back_populates="reviews") + + +class AgentAssetTestRun(Base): + __tablename__ = "agent_asset_test_runs" + + id: Mapped[str] = mapped_column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) + asset_id: Mapped[str] = mapped_column(ForeignKey("agent_assets.id"), index=True) + version: Mapped[str] = mapped_column(String(30), index=True) + test_type: Mapped[str] = mapped_column(String(30), index=True) + status: Mapped[str] = mapped_column(String(20), index=True) + passed: Mapped[bool] = mapped_column(Boolean, default=False, index=True) + summary: Mapped[str] = mapped_column(Text(), default="") + input_json: Mapped[dict[str, Any]] = mapped_column(JSON, default=dict) + result_json: Mapped[dict[str, Any]] = mapped_column(JSON, default=dict) + created_by: Mapped[str] = mapped_column(String(100)) + created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) + + asset = relationship("AgentAsset", back_populates="test_runs") diff --git a/server/src/app/models/employee.py b/server/src/app/models/employee.py index 5c4269f..5aeda95 100644 --- a/server/src/app/models/employee.py +++ b/server/src/app/models/employee.py @@ -3,7 +3,7 @@ from __future__ import annotations import uuid from datetime import date, datetime -from sqlalchemy import Boolean, Column, Date, DateTime, ForeignKey, String, Table, func +from sqlalchemy import Boolean, Column, Date, DateTime, ForeignKey, Integer, String, Table, func from sqlalchemy.orm import Mapped, mapped_column, relationship from app.db.base_class import Base @@ -35,6 +35,7 @@ class Employee(Base): password_hash: Mapped[str | None] = mapped_column(String(255), nullable=True) employment_status: Mapped[str] = mapped_column(String(30), default="在职", index=True) sync_state: Mapped[str] = mapped_column(String(30), default="已同步") + compliance_score: Mapped[int] = mapped_column(Integer, default=100) spotlight: Mapped[bool] = mapped_column(Boolean, default=False) last_sync_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True) organization_unit_id: Mapped[str | None] = mapped_column( diff --git a/server/src/app/models/financial_record.py b/server/src/app/models/financial_record.py index 19468df..7a6b025 100644 --- a/server/src/app/models/financial_record.py +++ b/server/src/app/models/financial_record.py @@ -5,7 +5,7 @@ from datetime import date, datetime from decimal import Decimal from typing import Any -from sqlalchemy import Date, DateTime, ForeignKey, Integer, Numeric, String, Text, func +from sqlalchemy import Boolean, Date, DateTime, ForeignKey, Integer, Numeric, String, Text, func from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.types import JSON @@ -39,6 +39,8 @@ class ExpenseClaim(Base): status: Mapped[str] = mapped_column(String(30), index=True) approval_stage: Mapped[str | None] = mapped_column(String(50), nullable=True) risk_flags_json: Mapped[list[Any]] = mapped_column(JSON, default=list) + hermes_scanned_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True) + hermes_risk_flag: Mapped[bool] = mapped_column(Boolean, default=False, index=True) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) updated_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), onupdate=func.now() diff --git a/server/src/app/models/hermes_config.py b/server/src/app/models/hermes_config.py new file mode 100644 index 0000000..13cdc6b --- /dev/null +++ b/server/src/app/models/hermes_config.py @@ -0,0 +1,48 @@ +from __future__ import annotations + +import uuid +from datetime import datetime +from typing import Any + +from sqlalchemy import Boolean, DateTime, ForeignKey, String, Text, func +from sqlalchemy.orm import Mapped, mapped_column, relationship +from sqlalchemy.types import JSON + +from app.db.base_class import Base + + +class HermesTaskConfig(Base): + __tablename__ = "hermes_task_configs" + + id: Mapped[str] = mapped_column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) + task_type: Mapped[str] = mapped_column(String(50), index=True) + cron_expression: Mapped[str] = mapped_column(String(100)) + is_enabled: Mapped[bool] = mapped_column(Boolean, default=True) + payload_template: Mapped[dict[str, Any]] = mapped_column(JSON, default=dict) + + created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) + updated_at: Mapped[datetime] = mapped_column( + DateTime(timezone=True), server_default=func.now(), onupdate=func.now() + ) + + execution_logs = relationship( + "HermesTaskExecutionLog", + back_populates="config", + cascade="all, delete-orphan", + order_by="desc(HermesTaskExecutionLog.started_at)", + ) + + +class HermesTaskExecutionLog(Base): + __tablename__ = "hermes_task_execution_logs" + + id: Mapped[str] = mapped_column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) + config_id: Mapped[str] = mapped_column(String(36), ForeignKey("hermes_task_configs.id"), index=True) + status: Mapped[str] = mapped_column(String(30), index=True) + result_summary: Mapped[str | None] = mapped_column(String(255), nullable=True) + error_trace: Mapped[str | None] = mapped_column(Text(), nullable=True) + + started_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) + completed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True) + + config = relationship("HermesTaskConfig", back_populates="execution_logs") diff --git a/server/src/app/models/hermes_report.py b/server/src/app/models/hermes_report.py new file mode 100644 index 0000000..0f1b2af --- /dev/null +++ b/server/src/app/models/hermes_report.py @@ -0,0 +1,34 @@ +from __future__ import annotations + +import uuid +from datetime import datetime +from typing import Any + +from sqlalchemy import DateTime, ForeignKey, String, Text, func +from sqlalchemy.orm import Mapped, mapped_column, relationship +from sqlalchemy.types import JSON + +from app.db.base_class import Base + + +class HermesRiskReport(Base): + __tablename__ = "hermes_risk_reports" + + id: Mapped[str] = mapped_column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) + claim_id: Mapped[str] = mapped_column(ForeignKey("expense_claims.id"), index=True) + execution_log_id: Mapped[str] = mapped_column(ForeignKey("hermes_task_execution_logs.id"), index=True) + + risk_level: Mapped[str] = mapped_column(String(20), index=True) + risk_type: Mapped[str] = mapped_column(String(50), index=True) + risk_description: Mapped[str] = mapped_column(Text()) + + related_claim_ids: Mapped[list[str]] = mapped_column(JSON, default=list) + status: Mapped[str] = mapped_column(String(30), default="pending_review", index=True) + + created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) + updated_at: Mapped[datetime] = mapped_column( + DateTime(timezone=True), server_default=func.now(), onupdate=func.now() + ) + + claim = relationship("ExpenseClaim", foreign_keys=[claim_id]) + execution_log = relationship("HermesTaskExecutionLog", foreign_keys=[execution_log_id]) diff --git a/server/src/app/repositories/agent_asset.py b/server/src/app/repositories/agent_asset.py index ff6cde6..2237884 100644 --- a/server/src/app/repositories/agent_asset.py +++ b/server/src/app/repositories/agent_asset.py @@ -3,7 +3,12 @@ from __future__ import annotations from sqlalchemy import or_, select from sqlalchemy.orm import Session -from app.models.agent_asset import AgentAsset, AgentAssetReview, AgentAssetVersion +from app.models.agent_asset import ( + AgentAsset, + AgentAssetReview, + AgentAssetTestRun, + AgentAssetVersion, +) class AgentAssetRepository: @@ -84,6 +89,17 @@ class AgentAssetRepository: stmt = stmt.limit(limit) return list(self.db.scalars(stmt).all()) + def list_reviews_for_assets(self, asset_ids: list[str]) -> list[AgentAssetReview]: + if not asset_ids: + return [] + + stmt = ( + select(AgentAssetReview) + .where(AgentAssetReview.asset_id.in_(asset_ids)) + .order_by(AgentAssetReview.asset_id, AgentAssetReview.created_at.desc()) + ) + return list(self.db.scalars(stmt).all()) + def get_review( self, asset_id: str, version: str, review_status: str | None = None ) -> AgentAssetReview | None: @@ -119,3 +135,54 @@ class AgentAssetRepository: self.db.commit() self.db.refresh(review) return review + + def list_test_runs( + self, + asset_id: str, + *, + version: str | None = None, + test_type: str | None = None, + status: str | None = None, + limit: int | None = None, + ) -> list[AgentAssetTestRun]: + stmt = ( + select(AgentAssetTestRun) + .where(AgentAssetTestRun.asset_id == asset_id) + .order_by(AgentAssetTestRun.created_at.desc()) + ) + if version: + stmt = stmt.where(AgentAssetTestRun.version == version) + if test_type: + stmt = stmt.where(AgentAssetTestRun.test_type == test_type) + if status: + stmt = stmt.where(AgentAssetTestRun.status == status) + if limit is not None: + stmt = stmt.limit(limit) + return list(self.db.scalars(stmt).all()) + + def get_latest_test_run( + self, + asset_id: str, + *, + version: str | None = None, + test_type: str | None = None, + status: str | None = None, + ) -> AgentAssetTestRun | None: + items = self.list_test_runs( + asset_id, + version=version, + test_type=test_type, + status=status, + limit=1, + ) + return items[0] if items else None + + def create_test_run(self, test_run: AgentAssetTestRun) -> AgentAssetTestRun: + self.db.add(test_run) + self.db.commit() + self.db.refresh(test_run) + return test_run + + def delete_asset(self, asset: AgentAsset) -> None: + self.db.delete(asset) + self.db.commit() diff --git a/server/src/app/schemas/agent_asset.py b/server/src/app/schemas/agent_asset.py index 9f6a551..d80c54a 100644 --- a/server/src/app/schemas/agent_asset.py +++ b/server/src/app/schemas/agent_asset.py @@ -112,8 +112,111 @@ class AgentAssetRuleJsonRead(BaseModel): class AgentAssetRiskRuleGenerateRequest(BaseModel): business_domain: AgentAssetDomain = AgentAssetDomain.EXPENSE + expense_category: str | None = Field(default=None, max_length=40) risk_level: str = Field(default="medium", pattern="^(low|medium|high)$") natural_language: str = Field(min_length=8, max_length=2000) + requires_attachment: bool = False + + +class AgentAssetRiskRuleSampleCase(BaseModel): + case_id: str | None = Field(default=None, max_length=60) + name: str = Field(default="测试样例", min_length=1, max_length=80) + values: dict[str, Any] = Field(default_factory=dict) + expected_hit: bool = True + expected_severity: str | None = Field(default=None, max_length=20) + note: str | None = None + + +class AgentAssetRiskRuleSampleTestRequest(BaseModel): + version: str | None = Field(default=None, max_length=30) + cases: list[AgentAssetRiskRuleSampleCase] = Field(default_factory=list) + + +class AgentAssetRiskRuleScenarioTestRequest(BaseModel): + version: str | None = Field(default=None, max_length=30) + intent: str = Field(default="", max_length=1000) + filters: dict[str, Any] = Field(default_factory=dict) + + +class AgentAssetRiskRuleReportRequest(BaseModel): + version: str | None = Field(default=None, max_length=30) + confirm_passed: bool = True + note: str | None = Field(default=None, max_length=1000) + + +class AgentAssetRiskRuleSimulationAttachment(BaseModel): + name: str = Field(default="", max_length=240) + content_type: str | None = Field(default=None, max_length=120) + size: int | None = Field(default=None, ge=0) + note: str | None = Field(default=None, max_length=500) + ocr_text: str | None = Field(default=None, max_length=20000) + summary: str | None = Field(default=None, max_length=2000) + document_type: str | None = Field(default=None, max_length=80) + document_type_label: str | None = Field(default=None, max_length=120) + scene_code: str | None = Field(default=None, max_length=80) + scene_label: str | None = Field(default=None, max_length=120) + avg_score: float | None = Field(default=None, ge=0.0, le=1.0) + recognition_status: str | None = Field(default=None, max_length=40) + document_fields: list[dict[str, Any]] = Field(default_factory=list) + + +class AgentAssetRiskRuleSimulationRequest(BaseModel): + version: str | None = Field(default=None, max_length=30) + message: str = Field(default="", max_length=4000) + field_values: dict[str, Any] = Field(default_factory=dict) + attachments: list[AgentAssetRiskRuleSimulationAttachment] = Field(default_factory=list) + + +class AgentAssetRiskRuleSimulationRead(BaseModel): + version: str + ready: bool = True + stage: str = "executed" + hit: bool + severity: str = "none" + severity_label: str = "未命中" + summary: str + blocking_reason: str = "" + message: str = "" + field_values: dict[str, Any] = Field(default_factory=dict) + evidence: dict[str, Any] = Field(default_factory=dict) + attachments: list[dict[str, Any]] = Field(default_factory=list) + recognized_fields: list[dict[str, Any]] = Field(default_factory=list) + missing_fields: list[dict[str, Any]] = Field(default_factory=list) + recognition_summary: list[dict[str, Any]] = Field(default_factory=list) + execution_mode: str = "risk_rule_simulation" + created_at: datetime + + +class AgentAssetRiskRuleReturnRequest(BaseModel): + note: str = Field(min_length=1, max_length=1000) + + +class AgentAssetRiskRuleEnabledUpdate(BaseModel): + enabled: bool + + +class AgentAssetRiskRuleTestRunRead(BaseModel): + model_config = ConfigDict(from_attributes=True) + + id: str + asset_id: str + version: str + test_type: str + status: str + passed: bool + summary: str + input_json: dict[str, Any] = Field(default_factory=dict) + result_json: dict[str, Any] = Field(default_factory=dict) + created_by: str + created_at: datetime + + +class AgentAssetRiskRuleLatestTestSummary(BaseModel): + version: str = "" + sample: AgentAssetRiskRuleTestRunRead | None = None + scenario: AgentAssetRiskRuleTestRunRead | None = None + report: AgentAssetRiskRuleTestRunRead | None = None + test_passed: bool = False class AgentAssetVersionTimelineItemRead(BaseModel): @@ -187,6 +290,8 @@ class AgentAssetListItem(BaseModel): config_json: dict[str, Any] change_count: int = 0 modified_by: str | None = None + published_by: str | None = None + published_at: datetime | None = None created_at: datetime updated_at: datetime @@ -197,3 +302,4 @@ class AgentAssetRead(AgentAssetListItem): current_version_change_note: str | None = None recent_versions: list[AgentAssetVersionRead] = Field(default_factory=list) latest_review: AgentAssetReviewRead | None = None + latest_test_summary: AgentAssetRiskRuleLatestTestSummary | None = None diff --git a/server/src/app/schemas/settings.py b/server/src/app/schemas/settings.py index 8a96b23..a6e93d1 100644 --- a/server/src/app/schemas/settings.py +++ b/server/src/app/schemas/settings.py @@ -164,6 +164,7 @@ class SettingsRead(BaseModel): companyForm: SettingsCompanyForm adminForm: SettingsAdminForm sessionForm: SettingsSessionForm + hermesForm: dict llmForm: SettingsLlmForm renderForm: SettingsRenderForm logForm: SettingsLogForm @@ -174,6 +175,7 @@ class SettingsWrite(BaseModel): companyForm: SettingsCompanyForm adminForm: SettingsAdminForm sessionForm: SettingsSessionForm + hermesForm: dict llmForm: SettingsLlmForm renderForm: SettingsRenderForm logForm: SettingsLogForm diff --git a/server/src/app/services/agent_asset_risk_rule_simulation.py b/server/src/app/services/agent_asset_risk_rule_simulation.py new file mode 100644 index 0000000..faf29fe --- /dev/null +++ b/server/src/app/services/agent_asset_risk_rule_simulation.py @@ -0,0 +1,552 @@ +from __future__ import annotations + +import re +from datetime import UTC, date, datetime +from typing import Any + +from app.schemas.agent_asset import ( + AgentAssetRiskRuleSimulationAttachment, + AgentAssetRiskRuleSimulationRead, + AgentAssetRiskRuleSimulationRequest, +) +from app.services.risk_rule_template_executor import RiskRuleTemplateExecutor + + +class AgentAssetRiskRuleSimulationMixin: + def simulate_risk_rule_message( + self, + asset_id: str, + body: AgentAssetRiskRuleSimulationRequest, + ) -> AgentAssetRiskRuleSimulationRead: + _, version, manifest = self._load_risk_rule_for_test(asset_id, body.version) + attachments = self._normalize_simulation_attachments(body.attachments) + field_values, source_map, recognized_fields = self._build_simulation_field_values( + manifest, + message=body.message, + explicit_values=body.field_values, + attachments=attachments, + ) + recognition_summary = self._build_recognition_summary(attachments) + required_keys = self._extract_execution_field_keys(manifest) + missing_fields = self._build_missing_fields( + manifest, + field_values=field_values, + source_map=source_map, + required_keys=required_keys, + ) + block = self._resolve_simulation_block( + manifest, + message=body.message, + attachments=attachments, + missing_fields=missing_fields, + ) + if block: + return AgentAssetRiskRuleSimulationRead( + version=version, + ready=False, + stage=block["stage"], + hit=False, + severity="none", + severity_label="待补充", + summary=block["summary"], + blocking_reason=block["reason"], + field_values=field_values, + attachments=attachments, + recognized_fields=recognized_fields, + missing_fields=missing_fields, + recognition_summary=recognition_summary, + created_at=datetime.now(UTC), + ) + + claim, contexts = self._build_synthetic_claim(field_values, manifest) + result = RiskRuleTemplateExecutor().evaluate(manifest, claim=claim, contexts=contexts) + hit = result is not None + severity = ( + str((manifest.get("outcomes") or {}).get("fail", {}).get("severity") or "medium") + if hit + else "none" + ) + severity_label = self._risk_severity_label(severity) + message = str(result.get("message") or "") if isinstance(result, dict) else "" + summary = ( + f"本次仿真命中{severity_label},仅生成风险识别结果,不创建业务单据。" + if hit + else "本次仿真未命中风险,仅完成规则识别,不创建业务单据。" + ) + evidence = result.get("evidence") if isinstance(result, dict) else {} + return AgentAssetRiskRuleSimulationRead( + version=version, + ready=True, + stage="executed", + hit=hit, + severity=severity, + severity_label=severity_label, + summary=summary, + message=message, + field_values=field_values, + evidence=evidence if isinstance(evidence, dict) else {}, + attachments=attachments, + recognized_fields=recognized_fields, + missing_fields=[], + recognition_summary=recognition_summary, + created_at=datetime.now(UTC), + ) + + def _build_simulation_field_values( + self, + manifest: dict[str, Any], + *, + message: str, + explicit_values: dict[str, Any], + attachments: list[dict[str, Any]], + ) -> tuple[dict[str, Any], dict[str, str], list[dict[str, Any]]]: + fields = self._extract_manifest_fields(manifest) + values: dict[str, Any] = {} + source_map: dict[str, str] = {} + safe_explicit_values = explicit_values if isinstance(explicit_values, dict) else {} + corpus = self._build_simulation_corpus(message, attachments) + city_mentions = self._extract_city_mentions(corpus) + + for field in fields: + key = field["key"] + explicit_value = safe_explicit_values.get(key) + if self._has_meaningful_value(explicit_value): + values[key] = explicit_value + source_map[key] = "manual" + continue + attachment_value = self._find_attachment_field_value( + key, + field.get("label") or key, + attachments, + ) + if self._has_meaningful_value(attachment_value): + values[key] = attachment_value + source_map[key] = "ocr" + continue + inferred = self._infer_simulation_value( + key, + field.get("label") or key, + corpus=corpus, + city_mentions=city_mentions, + ) + if self._has_meaningful_value(inferred): + values[key] = inferred + source_map[key] = "inferred" + + self._apply_compare_city_hints(manifest, values, source_map, city_mentions) + recognized_fields = self._build_recognized_fields(fields, values, source_map) + return values, source_map, recognized_fields + + def _infer_simulation_value( + self, + field_key: str, + label: str, + *, + corpus: str, + city_mentions: list[str], + ) -> Any: + key_text = f"{field_key} {label}".lower() + if field_key.endswith("route_cities"): + return city_mentions or [] + if "city" in field_key or "location" in field_key: + if any( + token in key_text + for token in ("hotel", "invoice", "attachment", "发票", "酒店", "住宿") + ): + return city_mentions[0] if city_mentions else "" + if any(token in key_text for token in ("route", "trip", "目的", "行程", "申报")): + return ( + city_mentions[1] + if len(city_mentions) > 1 + else (city_mentions[0] if city_mentions else "") + ) + return city_mentions[0] if city_mentions else "" + if field_key.endswith("amount"): + return self._extract_amount(corpus) + if field_key.endswith("issue_date") or field_key.endswith("item_date"): + return self._extract_iso_date(corpus) + if field_key.endswith("invoice_no"): + return self._extract_invoice_no(corpus) + if field_key.endswith("ocr_text"): + return corpus + if field_key.endswith("goods_name"): + return self._infer_goods_name(corpus) + if field_key.endswith("item_type"): + return self._infer_item_type(corpus) + if field_key.endswith("reason") or field_key.endswith("item_reason"): + return corpus or "仿真测试报销事由" + return None + + def _apply_compare_city_hints( + self, + manifest: dict[str, Any], + values: dict[str, Any], + source_map: dict[str, str], + city_mentions: list[str], + ) -> None: + if len(city_mentions) < 2: + return + params = manifest.get("params") if isinstance(manifest.get("params"), dict) else {} + conditions = params.get("conditions") if isinstance(params.get("conditions"), list) else [] + for condition in conditions: + if not isinstance(condition, dict): + continue + left = str(condition.get("left") or "").strip() + right = str(condition.get("right") or "").strip() + if not left or not right: + continue + if self._looks_like_city_field(left): + values[left] = city_mentions[0] + source_map[left] = source_map.get(left) or "inferred" + if self._looks_like_city_field(right): + values[right] = city_mentions[1] + source_map[right] = source_map.get(right) or "inferred" + + @staticmethod + def _normalize_simulation_attachments( + attachments: list[AgentAssetRiskRuleSimulationAttachment], + ) -> list[dict[str, Any]]: + normalized: list[dict[str, Any]] = [] + for item in list(attachments or [])[:12]: + normalized.append( + { + "name": str(item.name or "").strip(), + "content_type": str(item.content_type or "").strip(), + "size": item.size or 0, + "note": str(item.note or "").strip(), + "ocr_text": str(item.ocr_text or "").strip(), + "summary": str(item.summary or "").strip(), + "document_type": str(item.document_type or "").strip(), + "document_type_label": str(item.document_type_label or "").strip(), + "scene_code": str(item.scene_code or "").strip(), + "scene_label": str(item.scene_label or "").strip(), + "avg_score": float(item.avg_score or 0.0), + "recognition_status": str(item.recognition_status or "").strip(), + "document_fields": AgentAssetRiskRuleSimulationMixin._normalize_document_fields( + item.document_fields + ), + } + ) + return normalized + + @staticmethod + def _build_simulation_corpus(message: str, attachments: list[dict[str, Any]]) -> str: + parts = [str(message or "").strip()] + for item in attachments: + parts.append(str(item.get("name") or "").strip()) + parts.append(str(item.get("note") or "").strip()) + parts.append(str(item.get("summary") or "").strip()) + parts.append(str(item.get("ocr_text") or "").strip()) + for field in list(item.get("document_fields") or []): + if isinstance(field, dict): + parts.append(str(field.get("value") or "").strip()) + return "\n".join(part for part in parts if part) + + @staticmethod + def _normalize_document_fields(fields: list[dict[str, Any]]) -> list[dict[str, Any]]: + normalized: list[dict[str, Any]] = [] + for field in list(fields or [])[:30]: + if not isinstance(field, dict): + continue + key = str(field.get("key") or "").strip() + label = str(field.get("label") or "").strip() + value = field.get("value") + if key and label and AgentAssetRiskRuleSimulationMixin._has_meaningful_value(value): + normalized.append({"key": key, "label": label, "value": value}) + return normalized + + def _find_attachment_field_value( + self, + field_key: str, + label: str, + attachments: list[dict[str, Any]], + ) -> Any: + short_key = field_key.removeprefix("attachment.") + for attachment in attachments: + if short_key == "ocr_text": + value = attachment.get("ocr_text") or attachment.get("summary") + if self._has_meaningful_value(value): + return value + for field in list(attachment.get("document_fields") or []): + if not isinstance(field, dict): + continue + candidate_key = str(field.get("key") or "").strip().lower() + candidate_label = str(field.get("label") or "").strip() + if self._field_matches_simulation_key( + candidate_key, candidate_label, short_key, label + ): + return field.get("value") + return None + + @staticmethod + def _field_matches_simulation_key( + candidate_key: str, + candidate_label: str, + short_key: str, + target_label: str, + ) -> bool: + compact_candidate = candidate_key.replace("_", "") + compact_target = short_key.replace("_", "").lower() + if compact_target and compact_target in compact_candidate: + return True + label_text = f"{candidate_label} {target_label}" + label_map = { + "invoice_no": ("发票号", "发票号码", "票号"), + "hotel_city": ("住宿城市", "酒店城市", "酒店地点", "住宿", "酒店"), + "route_cities": ("行程", "路线", "目的地", "出差城市"), + "goods_name": ("品名", "商品", "服务名称"), + "amount": ("金额", "价税合计", "合计"), + "issue_date": ("日期", "开票日期", "发票日期"), + } + return any(token in label_text for token in label_map.get(short_key, ())) + + def _extract_execution_field_keys(self, manifest: dict[str, Any]) -> list[str]: + params = manifest.get("params") if isinstance(manifest.get("params"), dict) else {} + template_key = str(manifest.get("template_key") or params.get("template_key") or "").strip() + keys: list[str] = [] + if template_key == "field_compare_v1": + conditions = ( + params.get("conditions") if isinstance(params.get("conditions"), list) else [] + ) + for condition in conditions: + if not isinstance(condition, dict): + continue + for side in ("left", "right"): + key = str(condition.get(side) or "").strip() + if key and key not in keys: + keys.append(key) + elif template_key == "keyword_match_v1": + for key in self._read_string_list( + params.get("search_fields") or params.get("field_keys") + ): + if key not in keys: + keys.append(key) + elif template_key == "field_required_v1": + return [] + return keys + + def _build_missing_fields( + self, + manifest: dict[str, Any], + *, + field_values: dict[str, Any], + source_map: dict[str, str], + required_keys: list[str], + ) -> list[dict[str, Any]]: + labels = {field["key"]: field["label"] for field in self._extract_manifest_fields(manifest)} + missing: list[dict[str, Any]] = [] + for key in required_keys: + value = field_values.get(key) + if key not in source_map or not self._has_meaningful_value(value): + missing.append({"key": key, "label": labels.get(key, key)}) + return missing + + def _resolve_simulation_block( + self, + manifest: dict[str, Any], + *, + message: str, + attachments: list[dict[str, Any]], + missing_fields: list[dict[str, Any]], + ) -> dict[str, str] | None: + has_attachment = bool(attachments) + requires_attachment = self._rule_requires_attachment(manifest) + has_recognition = any( + self._has_meaningful_value(item.get("ocr_text")) + or self._has_meaningful_value(item.get("summary")) + or self._has_meaningful_value(item.get("document_fields")) + for item in attachments + ) + has_user_evidence = self._has_meaningful_user_message(message) + if requires_attachment and not has_attachment: + return { + "stage": "needs_attachment", + "summary": "当前规则要求上传附件,暂不能仅凭文字执行风险判断。", + "reason": "请上传测试单据,并填写本次测试意图后再执行仿真。", + } + if requires_attachment and not has_user_evidence: + return { + "stage": "needs_test_intent", + "summary": "当前规则要求附件和测试说明一起进入仿真判断。", + "reason": "请补充本次测试意图或关键业务事实,再执行风险识别。", + } + if has_attachment and not has_recognition and not has_user_evidence: + return { + "stage": "needs_recognition", + "summary": "单据尚未完成识别,暂不能执行风险规则。", + "reason": "请先完成 OCR 识别,或在对话中补充票据城市、金额、发票号等关键信息。", + } + template_key = str( + manifest.get("template_key") or (manifest.get("params") or {}).get("template_key") or "" + ).strip() + if template_key != "field_required_v1" and missing_fields: + labels = "、".join( + str(item.get("label") or item.get("key")) for item in missing_fields[:4] + ) + return { + "stage": "needs_field_confirmation", + "summary": f"还缺少规则执行所需字段:{labels},暂不能判断是否命中。", + "reason": "请补充缺失字段,或上传可识别出这些字段的票据后再执行。", + } + if not has_attachment and not has_user_evidence: + return { + "stage": "needs_input", + "summary": "请先描述测试单据或上传票据,再执行风险识别。", + "reason": "当前没有可用于规则判断的业务事实。", + } + return None + + @staticmethod + def _rule_requires_attachment(manifest: dict[str, Any]) -> bool: + if bool(manifest.get("requires_attachment")): + return True + metadata = manifest.get("metadata") if isinstance(manifest.get("metadata"), dict) else {} + return bool(metadata.get("requires_attachment")) + + @staticmethod + def _has_meaningful_user_message(message: str) -> bool: + text = str(message or "").strip() + if not text: + return False + generic_prompts = ( + "请识别我上传的临时单据是否命中这条风险规则", + "请识别上传单据是否命中风险规则", + ) + return not any(prompt in text for prompt in generic_prompts) + + @staticmethod + def _build_recognized_fields( + fields: list[dict[str, str]], + values: dict[str, Any], + source_map: dict[str, str], + ) -> list[dict[str, Any]]: + labels = {field["key"]: field["label"] for field in fields} + return [ + { + "key": key, + "label": labels.get(key, key), + "value": value, + "source": source_map.get(key, ""), + } + for key, value in values.items() + if source_map.get(key) + ] + + @staticmethod + def _build_recognition_summary(attachments: list[dict[str, Any]]) -> list[dict[str, Any]]: + return [ + { + "name": item.get("name") or "", + "status": item.get("recognition_status") + or ( + "recognized" + if item.get("ocr_text") or item.get("document_fields") + else "pending" + ), + "document_type_label": item.get("document_type_label") or "", + "scene_label": item.get("scene_label") or "", + "summary": item.get("summary") or "", + "field_count": len(list(item.get("document_fields") or [])), + "avg_score": item.get("avg_score") or 0.0, + } + for item in attachments + ] + + @staticmethod + def _extract_city_mentions(text: str) -> list[str]: + city_names = [ + "北京", + "上海", + "广州", + "深圳", + "杭州", + "南京", + "成都", + "武汉", + "重庆", + "天津", + "苏州", + "西安", + ] + pattern = "|".join(re.escape(city) for city in city_names) + found: list[str] = [] + for match in re.finditer(pattern, text): + city = match.group(0) + if city not in found: + found.append(city) + return found + + @staticmethod + def _extract_amount(text: str) -> str: + match = re.search(r"(\d{2,8}(?:\.\d{1,2})?)\s*(?:元|块|人民币|CNY)?", text, re.IGNORECASE) + return match.group(1) if match else "" + + @staticmethod + def _extract_iso_date(text: str) -> str: + match = re.search(r"(20\d{2})[-/.年](\d{1,2})[-/.月](\d{1,2})", text) + if not match: + return "" + year, month, day = (int(part) for part in match.groups()) + try: + return date(year, month, day).isoformat() + except ValueError: + return "" + + @staticmethod + def _extract_invoice_no(text: str) -> str: + match = re.search(r"(?:发票号|发票号码|票号)[::\s]*([A-Z0-9-]{6,32})", text, re.IGNORECASE) + return match.group(1) if match else "" + + @staticmethod + def _infer_item_type(text: str) -> str: + if not text: + return "" + if any(keyword in text for keyword in ("酒店", "住宿", "宾馆")): + return "住宿费" + if any(keyword in text for keyword in ("机票", "航班", "火车", "高铁", "打车")): + return "交通费" + if any(keyword in text for keyword in ("餐饮", "餐费", "招待")): + return "餐饮费" + return "差旅费" + + @staticmethod + def _infer_goods_name(text: str) -> str: + if not text: + return "" + if any(keyword in text for keyword in ("酒店", "住宿", "宾馆")): + return "住宿服务" + if any(keyword in text for keyword in ("机票", "航班", "火车", "高铁", "打车")): + return "交通服务" + if any(keyword in text for keyword in ("餐饮", "餐费", "招待")): + return "餐饮服务" + return "报销服务" + + @staticmethod + def _looks_like_city_field(field_key: str) -> bool: + lowered = field_key.lower() + return "city" in lowered or "location" in lowered or lowered.endswith("route_cities") + + @staticmethod + def _has_meaningful_value(value: Any) -> bool: + if value is None: + return False + if isinstance(value, str): + return bool(value.strip()) + if isinstance(value, (list, tuple, set, dict)): + return bool(value) + return True + + @staticmethod + def _risk_severity_label(severity: str) -> str: + return { + "low": "低风险", + "medium": "中风险", + "high": "高风险", + "none": "未命中", + }.get(str(severity or "").strip().lower(), "风险") + + @staticmethod + def _read_string_list(value: Any) -> list[str]: + if not isinstance(value, list): + return [] + return [str(item or "").strip() for item in value if str(item or "").strip()] diff --git a/server/src/app/services/agent_asset_risk_rule_testing.py b/server/src/app/services/agent_asset_risk_rule_testing.py new file mode 100644 index 0000000..2c6055d --- /dev/null +++ b/server/src/app/services/agent_asset_risk_rule_testing.py @@ -0,0 +1,723 @@ +from __future__ import annotations + +import re +from datetime import UTC, date, datetime, timedelta +from decimal import Decimal, InvalidOperation +from typing import Any + +from sqlalchemy import or_, select + +from app.core.agent_enums import ( + AgentAssetDomain, + AgentAssetStatus, + AgentAssetType, + AgentReviewStatus, +) +from app.models.agent_asset import AgentAsset, AgentAssetReview, AgentAssetTestRun +from app.models.financial_record import ExpenseClaim, ExpenseClaimItem +from app.schemas.agent_asset import ( + AgentAssetRiskRuleLatestTestSummary, + AgentAssetRiskRuleReportRequest, + AgentAssetRiskRuleSampleCase, + AgentAssetRiskRuleSampleTestRequest, + AgentAssetRiskRuleScenarioTestRequest, + AgentAssetRiskRuleTestRunRead, +) +from app.services.expense_claims import ExpenseClaimService +from app.services.risk_rule_template_executor import RiskRuleTemplateExecutor + + +class AgentAssetRiskRuleTestingMixin: + def get_latest_risk_rule_test_summary( + self, + asset_or_id: AgentAsset | str, + *, + version: str | None = None, + ) -> AgentAssetRiskRuleLatestTestSummary: + asset = self._resolve_asset(asset_or_id) + target_version = self._resolve_target_version(asset, version) + sample = self.repository.get_latest_test_run( + asset.id, version=target_version, test_type="sample" + ) + scenario = self.repository.get_latest_test_run( + asset.id, version=target_version, test_type="scenario" + ) + report = self.repository.get_latest_test_run( + asset.id, version=target_version, test_type="report", status="passed" + ) + return AgentAssetRiskRuleLatestTestSummary( + version=target_version, + sample=self._serialize_test_run(sample), + scenario=self._serialize_test_run(scenario), + report=self._serialize_test_run(report), + test_passed=bool(report and report.passed), + ) + + def run_risk_rule_sample_test( + self, + asset_id: str, + body: AgentAssetRiskRuleSampleTestRequest, + *, + actor: str, + request_id: str | None = None, + ) -> AgentAssetRiskRuleTestRunRead: + asset, version, manifest = self._load_risk_rule_for_test(asset_id, body.version) + cases = body.cases or self._build_default_sample_cases(manifest) + results = [self._run_sample_case(manifest, case) for case in cases] + passed = bool(results) and all(item["passed"] for item in results) + summary = f"快速样例测试 {'通过' if passed else '未通过'},共 {len(results)} 条。" + return self._create_test_run( + asset, + version=version, + test_type="sample", + passed=passed, + summary=summary, + input_json={"cases": [case.model_dump() for case in cases]}, + result_json={"cases": results, "case_count": len(results)}, + actor=actor, + request_id=request_id, + ) + + def run_risk_rule_scenario_test( + self, + asset_id: str, + body: AgentAssetRiskRuleScenarioTestRequest, + *, + actor: str, + request_id: str | None = None, + ) -> AgentAssetRiskRuleTestRunRead: + asset, version, manifest = self._load_risk_rule_for_test(asset_id, body.version) + if asset.domain != AgentAssetDomain.EXPENSE.value: + raise ValueError("一期真实场景试运行仅支持报销业务域。") + + parsed_scope = self._parse_scenario_scope(body.intent, body.filters) + claims = self._query_expense_claim_samples(parsed_scope) + claim_results = [self._run_claim_scenario(manifest, claim) for claim in claims] + hit_items = [item for item in claim_results if item["hit"]] + severity_counts: dict[str, int] = {} + for item in hit_items: + severity = str(item.get("severity") or "unknown") + severity_counts[severity] = severity_counts.get(severity, 0) + 1 + + passed = bool(claim_results) + summary = ( + f"真实场景试运行完成,样本 {len(claim_results)} 条,命中 {len(hit_items)} 条。" + if passed + else "真实场景试运行未找到可测样本。" + ) + return self._create_test_run( + asset, + version=version, + test_type="scenario", + passed=passed, + summary=summary, + input_json={ + "intent": body.intent, + "filters": body.filters, + "parsed_scope": parsed_scope, + }, + result_json={ + "total_count": len(claim_results), + "hit_count": len(hit_items), + "severity_counts": severity_counts, + "items": claim_results[:50], + }, + actor=actor, + request_id=request_id, + ) + + def confirm_risk_rule_test_report( + self, + asset_id: str, + body: AgentAssetRiskRuleReportRequest, + *, + actor: str, + request_id: str | None = None, + ) -> AgentAssetRiskRuleTestRunRead: + asset, version, _ = self._load_risk_rule_for_test(asset_id, body.version) + sample = self.repository.get_latest_test_run( + asset.id, version=version, test_type="sample", status="passed" + ) + scenario = self.repository.get_latest_test_run( + asset.id, version=version, test_type="scenario" + ) + if sample is None: + raise ValueError("提交审核前必须先完成快速样例测试。") + if not body.confirm_passed: + raise ValueError("请确认测试通过后再保存测试报告。") + + summary = "测试报告已确认,当前版本可提交审核。" + if scenario is None: + summary = "快速样例测试已确认通过,真实场景试运行未执行。" + elif not scenario.passed: + summary = "快速样例测试已确认通过,真实场景试运行未找到可测样本。" + return self._create_test_run( + asset, + version=version, + test_type="report", + passed=True, + summary=summary, + input_json={"confirm_passed": True, "note": body.note or ""}, + result_json={ + "sample_test_run_id": sample.id, + "scenario_test_run_id": scenario.id, + "sample_summary": sample.summary, + "scenario_summary": scenario.summary, + }, + actor=actor, + request_id=request_id, + ) + + def delete_unpublished_asset( + self, + asset_id: str, + *, + actor: str, + request_id: str | None = None, + ) -> None: + asset = self._resolve_asset(asset_id) + self._require_json_risk_asset(asset) + if str(asset.published_version or "").strip(): + raise PermissionError("已发布过的风险规则不能删除。") + + before = self._asset_snapshot(asset) + self._delete_risk_rule_json_file(asset) + self.repository.delete_asset(asset) + self.audit_service.log_action( + actor=actor, + action="delete_agent_asset", + resource_type=AgentAssetType.RULE.value, + resource_id=asset_id, + before_json=before, + after_json={"deleted": True}, + request_id=request_id, + ) + + def return_risk_rule( + self, + asset_id: str, + *, + note: str, + actor: str, + request_id: str | None = None, + ) -> AgentAssetRiskRuleLatestTestSummary: + asset = self._resolve_asset(asset_id) + self._require_json_risk_asset(asset) + version = self._resolve_target_version(asset, None) + if asset.status != AgentAssetStatus.REVIEW.value: + raise ValueError("只有待审核风险规则可以回退。") + + before = self._asset_snapshot(asset) + review = AgentAssetReview( + asset_id=asset.id, + version=version, + reviewer=actor, + review_status=AgentReviewStatus.REJECTED.value, + review_note=str(note or "审核回退").strip() or "审核回退", + reviewed_at=datetime.now(UTC), + ) + self.db.add(review) + asset.reviewer = actor + asset.status = AgentAssetStatus.DRAFT.value + self.db.add(asset) + self.db.commit() + self.audit_service.log_action( + actor=actor, + action="return_agent_asset", + resource_type=AgentAssetType.RULE.value, + resource_id=asset.id, + before_json=before, + after_json={"version": version, "status": asset.status, "note": note}, + request_id=request_id, + ) + return self.get_latest_risk_rule_test_summary(asset) + + def publish_risk_rule( + self, + asset_id: str, + *, + actor: str, + request_id: str | None = None, + ) -> AgentAsset: + asset = self._resolve_asset(asset_id) + self._require_json_risk_asset(asset) + version = self._resolve_target_version(asset, None) + if asset.status != AgentAssetStatus.REVIEW.value: + raise ValueError("只有待审核风险规则可以发布上线。") + if not self.get_latest_risk_rule_test_summary(asset, version=version).test_passed: + raise PermissionError("当前规则版本尚未完成测试通过确认,不能发布。") + + before = self._asset_snapshot(asset) + approved_review = self.repository.get_review( + asset.id, version, AgentReviewStatus.APPROVED.value + ) + if approved_review is None: + self.db.add( + AgentAssetReview( + asset_id=asset.id, + version=version, + reviewer=actor, + review_status=AgentReviewStatus.APPROVED.value, + review_note="发布上线前审核通过。", + reviewed_at=datetime.now(UTC), + ) + ) + asset.reviewer = actor + asset.published_version = version + asset.status = AgentAssetStatus.ACTIVE.value + self.db.add(asset) + self.db.commit() + self.audit_service.log_action( + actor=actor, + action="publish_agent_asset", + resource_type=AgentAssetType.RULE.value, + resource_id=asset.id, + before_json=before, + after_json=self._asset_snapshot(asset), + request_id=request_id, + ) + refreshed = self.repository.get(asset.id) + if refreshed is None: + raise LookupError("Asset not found") + return refreshed + + def set_risk_rule_enabled( + self, + asset_id: str, + *, + enabled: bool, + actor: str, + request_id: str | None = None, + ) -> AgentAsset: + asset = self._resolve_asset(asset_id) + self._require_json_risk_asset(asset) + before = self._asset_snapshot(asset) + rule_library, file_name = self._resolve_json_risk_rule_document(asset) + manifest = self.rule_library_manager.read_rule_library_json( + library=rule_library, + file_name=file_name, + ) + manifest["enabled"] = bool(enabled) + self.rule_library_manager.write_rule_library_json( + library=rule_library, + file_name=file_name, + payload=manifest, + ) + + config_json = dict(asset.config_json or {}) + config_json["enabled"] = bool(enabled) + asset.config_json = config_json + updated = self.repository.save_asset(asset) + self.audit_service.log_action( + actor=actor, + action="set_risk_rule_enabled", + resource_type=AgentAssetType.RULE.value, + resource_id=asset.id, + before_json=before, + after_json=self._asset_snapshot(updated), + request_id=request_id, + ) + return updated + + def _load_risk_rule_for_test( + self, asset_id: str, version: str | None + ) -> tuple[AgentAsset, str, dict[str, Any]]: + asset = self._resolve_asset(asset_id) + self._require_json_risk_asset(asset) + target_version = self._resolve_target_version(asset, version) + if self.repository.get_version(asset.id, target_version) is None: + raise LookupError(f"版本 {target_version} 不存在") + + rule_library, file_name = self._resolve_json_risk_rule_document(asset) + manifest = self.rule_library_manager.read_rule_library_json( + library=rule_library, + file_name=file_name, + ) + return asset, target_version, manifest + + def _create_test_run( + self, + asset: AgentAsset, + *, + version: str, + test_type: str, + passed: bool, + summary: str, + input_json: dict[str, Any], + result_json: dict[str, Any], + actor: str, + request_id: str | None, + ) -> AgentAssetRiskRuleTestRunRead: + status = "passed" if passed else "failed" + created = self.repository.create_test_run( + AgentAssetTestRun( + asset_id=asset.id, + version=version, + test_type=test_type, + status=status, + passed=passed, + summary=summary, + input_json=input_json, + result_json=result_json, + created_by=actor, + ) + ) + self.audit_service.log_action( + actor=actor, + action=f"risk_rule_test_{test_type}", + resource_type=AgentAssetType.RULE.value, + resource_id=asset.id, + before_json=None, + after_json={"version": version, "status": status, "summary": summary}, + request_id=request_id, + ) + return AgentAssetRiskRuleTestRunRead.model_validate(created) + + def _run_sample_case( + self, + manifest: dict[str, Any], + case: AgentAssetRiskRuleSampleCase, + ) -> dict[str, Any]: + claim, contexts = self._build_synthetic_claim(case.values, manifest) + result = RiskRuleTemplateExecutor().evaluate(manifest, claim=claim, contexts=contexts) + actual_hit = result is not None + actual_severity = ( + str((manifest.get("outcomes") or {}).get("fail", {}).get("severity") or "").strip() + if actual_hit + else "none" + ) + expected_severity = str(case.expected_severity or "").strip() + severity_passed = ( + not actual_hit or not expected_severity or expected_severity == actual_severity + ) + passed = actual_hit == case.expected_hit and severity_passed + return { + "case_id": case.case_id or "", + "name": case.name, + "values": case.values, + "expected_hit": case.expected_hit, + "expected_severity": expected_severity, + "actual_hit": actual_hit, + "actual_severity": actual_severity, + "passed": passed, + "message": str(result.get("message") or "") if isinstance(result, dict) else "", + "evidence": result.get("evidence") if isinstance(result, dict) else {}, + } + + def _run_claim_scenario(self, manifest: dict[str, Any], claim: ExpenseClaim) -> dict[str, Any]: + contexts = ExpenseClaimService(self.db)._build_claim_attachment_contexts(claim) + result = RiskRuleTemplateExecutor().evaluate(manifest, claim=claim, contexts=contexts) + hit = result is not None + return { + "claim_id": claim.id, + "claim_no": claim.claim_no, + "employee_name": claim.employee_name, + "department_name": claim.department_name, + "expense_type": claim.expense_type, + "amount": float(claim.amount or 0), + "status": claim.status, + "occurred_at": claim.occurred_at.isoformat() if claim.occurred_at else "", + "hit": hit, + "severity": str((manifest.get("outcomes") or {}).get("fail", {}).get("severity") or "") + if hit + else "none", + "message": str(result.get("message") or "") if isinstance(result, dict) else "", + "evidence": result.get("evidence") if isinstance(result, dict) else {}, + } + + def _build_synthetic_claim( + self, + values: dict[str, Any], + manifest: dict[str, Any], + ) -> tuple[ExpenseClaim, list[dict[str, Any]]]: + claim = ExpenseClaim( + claim_no="TEST-RISK-RULE", + employee_name=str(values.get("claim.employee_name") or "测试员工"), + department_name=str(values.get("claim.department_name") or "测试部门"), + expense_type=str(values.get("item.item_type") or "差旅费"), + reason=str(values.get("claim.reason") or "测试报销事由"), + location=str(values.get("claim.location") or "北京"), + amount=self._to_decimal(values.get("claim.amount")), + currency="CNY", + invoice_count=1, + occurred_at=datetime.now(UTC), + status="draft", + ) + item = ExpenseClaimItem( + item_date=date.today(), + item_type=str(values.get("item.item_type") or "住宿费"), + item_reason=str(values.get("item.item_reason") or claim.reason), + item_location=str(values.get("item.item_location") or claim.location), + item_amount=self._to_decimal(values.get("item.item_amount") or claim.amount), + ) + claim.items = [item] + + attachment_fields = [] + document_info: dict[str, Any] = {"fields": attachment_fields} + for field in self._extract_manifest_fields(manifest): + key = field["key"] + if key not in values: + continue + value = self._coerce_sample_value(key, values.get(key)) + if key.startswith("claim."): + setattr(claim, key.removeprefix("claim."), value) + elif key.startswith("item."): + setattr(item, key.removeprefix("item."), value) + elif key.startswith("attachment."): + short_key = key.removeprefix("attachment.") + document_info[short_key] = value + attachment_fields.append( + {"key": short_key, "label": field["label"], "value": value} + ) + return claim, [ + { + "document_info": document_info, + "ocr_text": document_info.get("ocr_text", ""), + } + ] + + def _build_default_sample_cases( + self, + manifest: dict[str, Any], + ) -> list[AgentAssetRiskRuleSampleCase]: + fields = self._extract_manifest_fields(manifest) + severity = str((manifest.get("outcomes") or {}).get("fail", {}).get("severity") or "") + template_key = str(manifest.get("template_key") or "").strip() + hit_values = self._find_case_values_for_expected(manifest, fields, expected_hit=True) + pass_values = self._find_case_values_for_expected(manifest, fields, expected_hit=False) + cases = [ + AgentAssetRiskRuleSampleCase( + case_id="hit", + name="应该命中风险", + values=hit_values, + expected_hit=True, + expected_severity=severity, + note="验证规则能识别异常样本。", + ), + AgentAssetRiskRuleSampleCase( + case_id="pass", + name="应该不命中", + values=pass_values, + expected_hit=False, + expected_severity="none", + note="验证正常样本不会误触发。", + ), + ] + if template_key == "field_required_v1": + cases.append( + AgentAssetRiskRuleSampleCase( + case_id="missing", + name="关键字段缺失", + values={key: "" for key in hit_values}, + expected_hit=True, + expected_severity=severity, + note="验证缺字段时会进入复核。", + ) + ) + return cases + + def _find_case_values_for_expected( + self, + manifest: dict[str, Any], + fields: list[dict[str, str]], + *, + expected_hit: bool, + ) -> dict[str, Any]: + candidates = [ + self._build_case_values(manifest, fields, hit=expected_hit), + {field["key"]: self._default_value_for_field(field["key"]) for field in fields}, + { + field["key"]: ("上海" if index == 0 else "北京") + for index, field in enumerate(fields) + }, + {field["key"]: "北京" for field in fields}, + {field["key"]: "" for field in fields}, + ] + severity = str((manifest.get("outcomes") or {}).get("fail", {}).get("severity") or "") + for values in candidates: + probe = AgentAssetRiskRuleSampleCase( + name="默认样例探测", + values=values, + expected_hit=expected_hit, + expected_severity=severity if expected_hit else "none", + ) + result = self._run_sample_case(manifest, probe) + if bool(result["actual_hit"]) == expected_hit: + return values + return candidates[0] + + def _build_case_values( + self, + manifest: dict[str, Any], + fields: list[dict[str, str]], + *, + hit: bool, + ) -> dict[str, Any]: + values = {field["key"]: self._default_value_for_field(field["key"]) for field in fields} + template_key = str(manifest.get("template_key") or "").strip() + params = manifest.get("params") if isinstance(manifest.get("params"), dict) else {} + if template_key == "field_compare_v1": + condition = next( + (item for item in params.get("conditions", []) if isinstance(item, dict)), + {}, + ) + left = str(condition.get("left") or "").strip() + right = str(condition.get("right") or "").strip() + operator = str(condition.get("operator") or "overlap").strip() + if left and operator == "is_empty": + values[left] = "测试值" if hit else "" + elif left and right and operator in {"not_equals", "not_in", "not_overlap"}: + values[left] = "北京" if hit else "上海" + values[right] = "北京" + elif left and right: + values[left] = "上海" if hit else "北京" + values[right] = "北京" + elif template_key == "field_required_v1" and hit and fields: + values[fields[0]["key"]] = "" + elif template_key == "keyword_match_v1": + keywords = params.get("keywords") if isinstance(params.get("keywords"), list) else [] + keyword = str(next(iter(keywords), "咨询费") or "咨询费") + target_key = fields[0]["key"] if fields else "claim.reason" + values[target_key] = f"本次报销包含{keyword}" if hit else "正常差旅报销" + return values + + @staticmethod + def _default_value_for_field(field_key: str) -> Any: + if field_key.endswith("amount"): + return "100.00" + if field_key.endswith("issue_date"): + return date.today().isoformat() + if field_key.endswith("route_cities"): + return ["北京"] + if field_key.endswith("ocr_text"): + return "正常发票内容" + if "city" in field_key or "location" in field_key: + return "北京" + if field_key.endswith("item_type"): + return "住宿费" + return "测试值" + + def _query_expense_claim_samples(self, parsed_scope: dict[str, Any]) -> list[ExpenseClaim]: + days = int(parsed_scope.get("days") or 30) + limit = min(max(int(parsed_scope.get("limit") or 50), 1), 200) + since = datetime.now(UTC) - timedelta(days=days) + stmt = select(ExpenseClaim).where(ExpenseClaim.created_at >= since) + + expense_keyword = str(parsed_scope.get("expense_keyword") or "").strip() + if expense_keyword: + like_keyword = f"%{expense_keyword}%" + stmt = stmt.where( + or_( + ExpenseClaim.expense_type.ilike(like_keyword), + ExpenseClaim.reason.ilike(like_keyword), + ) + ) + + cities = [str(item or "").strip() for item in parsed_scope.get("cities", []) if item] + if cities: + city_filters = [] + for city in cities[:8]: + like_city = f"%{city}%" + city_filters.extend( + [ + ExpenseClaim.location.ilike(like_city), + ExpenseClaim.reason.ilike(like_city), + ] + ) + stmt = stmt.where(or_(*city_filters)) + + stmt = stmt.order_by(ExpenseClaim.created_at.desc()).limit(limit) + return list(self.db.scalars(stmt).all()) + + @staticmethod + def _parse_scenario_scope(intent: str, filters: dict[str, Any]) -> dict[str, Any]: + text = str(intent or "") + raw_days = filters.get("days") or filters.get("recent_days") + days = int(raw_days) if str(raw_days or "").isdigit() else 30 + match = re.search(r"最近\s*(\d{1,3})\s*天", text) + if match: + days = int(match.group(1)) + limit = filters.get("limit") if str(filters.get("limit") or "").isdigit() else 50 + expense_keyword = str(filters.get("expense_keyword") or "").strip() + if not expense_keyword and any(keyword in text for keyword in ("酒店", "住宿")): + expense_keyword = "住宿" + + city_candidates = ("北京", "上海", "广州", "深圳", "武汉", "杭州", "成都", "南京") + cities = [ + city + for city in city_candidates + if city in text or city in [str(item) for item in filters.get("cities", []) or []] + ] + return { + "business_domain": "expense", + "days": max(1, min(days, 365)), + "limit": max(1, min(int(limit), 200)), + "expense_keyword": expense_keyword, + "cities": cities, + "execution_mode": "dry_run", + } + + @staticmethod + def _extract_manifest_fields(manifest: dict[str, Any]) -> list[dict[str, str]]: + inputs = manifest.get("inputs") if isinstance(manifest.get("inputs"), dict) else {} + fields = inputs.get("fields") if isinstance(inputs.get("fields"), list) else [] + normalized = [] + for item in fields: + if not isinstance(item, dict): + continue + key = str(item.get("key") or "").strip() + if key: + normalized.append({"key": key, "label": str(item.get("label") or key).strip()}) + return normalized + + @staticmethod + def _coerce_sample_value(field_key: str, value: Any) -> Any: + if field_key.endswith("route_cities") and isinstance(value, str): + return [item.strip() for item in re.split(r"[,,、/ ]+", value) if item.strip()] + return value + + @staticmethod + def _to_decimal(value: Any) -> Decimal: + try: + return Decimal(str(value or "0")) + except (InvalidOperation, ValueError): + return Decimal("0") + + def _resolve_asset(self, asset_or_id: AgentAsset | str) -> AgentAsset: + if isinstance(asset_or_id, AgentAsset): + return asset_or_id + asset = self.repository.get(str(asset_or_id)) + if asset is None: + raise LookupError("Asset not found") + return asset + + @staticmethod + def _require_json_risk_asset(asset: AgentAsset) -> None: + config_json = asset.config_json if isinstance(asset.config_json, dict) else {} + if asset.asset_type != AgentAssetType.RULE.value: + raise ValueError("仅规则资产支持风险规则操作。") + if str(config_json.get("detail_mode") or "").strip().lower() != "json_risk": + raise ValueError("仅 JSON 风险规则支持该操作。") + + def _resolve_target_version(self, asset: AgentAsset, version: str | None) -> str: + target = str(version or self._resolve_working_version(asset) or "").strip() + if not target: + raise ValueError("当前规则尚未配置工作版本。") + return target + + def _delete_risk_rule_json_file(self, asset: AgentAsset) -> None: + try: + rule_library, file_name = self._resolve_json_risk_rule_document(asset) + target = self.rule_library_manager.resolve_rule_library_path( + library=rule_library, + file_name=file_name, + ) + target.unlink(missing_ok=True) + except (FileNotFoundError, ValueError): + return + + @staticmethod + def _serialize_test_run( + run: AgentAssetTestRun | None, + ) -> AgentAssetRiskRuleTestRunRead | None: + return AgentAssetRiskRuleTestRunRead.model_validate(run) if run is not None else None diff --git a/server/src/app/services/agent_assets.py b/server/src/app/services/agent_assets.py index b985f7f..d0195a0 100644 --- a/server/src/app/services/agent_assets.py +++ b/server/src/app/services/agent_assets.py @@ -4,6 +4,7 @@ import json from collections import defaultdict from datetime import UTC, datetime from typing import Any + from sqlalchemy.orm import Session from app.core.agent_enums import ( @@ -27,13 +28,14 @@ from app.schemas.agent_asset import ( ) from app.services.agent_asset_json_rules import AgentAssetJsonRuleMixin from app.services.agent_asset_onlyoffice import AgentAssetOnlyOfficeMixin +from app.services.agent_asset_risk_rule_simulation import AgentAssetRiskRuleSimulationMixin +from app.services.agent_asset_risk_rule_testing import AgentAssetRiskRuleTestingMixin from app.services.agent_asset_rule_library import AgentAssetRuleLibraryManager +from app.services.agent_asset_spreadsheet import AgentAssetSpreadsheetManager from app.services.agent_asset_spreadsheet_helpers import AgentAssetSpreadsheetHelperMixin from app.services.agent_asset_timeline import AgentAssetTimelineMixin -from app.services.agent_asset_spreadsheet import AgentAssetSpreadsheetManager from app.services.agent_foundation import AgentFoundationService from app.services.audit import AuditLogService -from app.services.settings import resolve_onlyoffice_settings logger = get_logger("app.services.agent_assets") @@ -41,6 +43,8 @@ logger = get_logger("app.services.agent_assets") class AgentAssetService( AgentAssetOnlyOfficeMixin, AgentAssetSpreadsheetHelperMixin, + AgentAssetRiskRuleTestingMixin, + AgentAssetRiskRuleSimulationMixin, AgentAssetTimelineMixin, AgentAssetJsonRuleMixin, ): @@ -66,10 +70,7 @@ class AgentAssetService( asset_type=asset_type, status=status, domain=domain, keyword=keyword ) version_stats = self._collect_version_stats(assets) - return [ - self._serialize_list_item(asset, version_stats.get(asset.id)) - for asset in assets - ] + return [self._serialize_list_item(asset, version_stats.get(asset.id)) for asset in assets] def get_asset(self, asset_id: str) -> AgentAssetRead | None: self._ensure_ready() @@ -88,9 +89,7 @@ class AgentAssetService( else next(iter(self.repository.list_reviews(asset_id, limit=1)), None) ) current_version = ( - self.repository.get_version(asset_id, working_version) - if working_version - else None + self.repository.get_version(asset_id, working_version) if working_version else None ) version_stats = self._collect_version_stats([asset]).get(asset.id) return AgentAssetRead( @@ -100,12 +99,14 @@ class AgentAssetService( else None, current_version_content_type=current_version.content_type if current_version else None, current_version_change_note=current_version.change_note if current_version else None, - recent_versions=[ - self._serialize_version(item, asset) for item in recent_versions - ], + recent_versions=[self._serialize_version(item, asset) for item in recent_versions], latest_review=AgentAssetReviewRead.model_validate(latest_review) if latest_review else None, + latest_test_summary=self.get_latest_risk_rule_test_summary(asset) + if str((asset.config_json or {}).get("detail_mode") or "").strip().lower() + == "json_risk" + else None, ) def create_asset( @@ -301,6 +302,13 @@ class AgentAssetService( if self.repository.get_version(asset_id, payload.version) is None: raise LookupError(f"版本 {payload.version} 不存在") if asset.asset_type == AgentAssetType.RULE.value: + if ( + str((asset.config_json or {}).get("detail_mode") or "").strip().lower() + == "json_risk" + and payload.review_status == AgentReviewStatus.PENDING + and not self.get_latest_risk_rule_test_summary(asset).test_passed + ): + raise PermissionError("当前规则版本尚未完成测试通过确认,不能提交审核。") working_version = self._resolve_working_version(asset) if payload.version != working_version: raise ValueError("只能对当前工作版本发起审核。") @@ -594,11 +602,10 @@ class AgentAssetService( ), ) - def _collect_version_stats( - self, assets: list[AgentAsset] - ) -> dict[str, dict[str, int | str | None]]: + def _collect_version_stats(self, assets: list[AgentAsset]) -> dict[str, dict[str, Any]]: asset_ids = [item.id for item in assets] versions = self.repository.list_versions_for_assets(asset_ids) + reviews = self.repository.list_reviews_for_assets(asset_ids) spreadsheet_logs = self.audit_service.repository.list_for_resources( resource_type=AgentAssetType.RULE.value, resource_ids=[ @@ -610,23 +617,33 @@ class AgentAssetService( ], action="edit_rule_spreadsheet", ) - working_versions = { - item.id: self._resolve_working_version(item) for item in assets - } + working_versions = {item.id: self._resolve_working_version(item) for item in assets} version_counts: dict[str, int] = defaultdict(int) modified_by: dict[str, str | None] = {item.id: None for item in assets} + published_versions = {item.id: self._resolve_published_version(item) for item in assets} + published_by: dict[str, str | None] = {} + published_at: dict[str, datetime | None] = {} spreadsheet_edit_counts: dict[str, int] = defaultdict(int) spreadsheet_last_actor: dict[str, str | None] = {} spreadsheet_last_changed_at: dict[str, datetime] = {} for version in versions: version_counts[version.asset_id] += 1 - if ( - modified_by.get(version.asset_id) is None - and version.version == working_versions.get(version.asset_id) - ): + if modified_by.get( + version.asset_id + ) is None and version.version == working_versions.get(version.asset_id): modified_by[version.asset_id] = version.created_by + for review in reviews: + if review.asset_id in published_at: + continue + if review.version != published_versions.get(review.asset_id): + continue + if review.review_status != AgentReviewStatus.APPROVED.value: + continue + published_by[review.asset_id] = review.reviewer + published_at[review.asset_id] = review.reviewed_at or review.created_at + for log in spreadsheet_logs: spreadsheet_edit_counts[log.resource_id] += 1 last_changed_at = spreadsheet_last_changed_at.get(log.resource_id) @@ -652,6 +669,8 @@ class AgentAssetService( and spreadsheet_last_actor.get(item.id) else modified_by.get(item.id) ), + "published_by": published_by.get(item.id), + "published_at": published_at.get(item.id), } for item in assets } @@ -663,9 +682,11 @@ class AgentAssetService( ) -> AgentAssetListItem: payload = AgentAssetListItem.model_validate(asset).model_dump() payload["change_count"] = int((version_stats or {}).get("change_count") or 0) - payload["modified_by"] = ( - str((version_stats or {}).get("modified_by") or "").strip() or None + payload["modified_by"] = str((version_stats or {}).get("modified_by") or "").strip() or None + payload["published_by"] = ( + str((version_stats or {}).get("published_by") or "").strip() or None ) + payload["published_at"] = (version_stats or {}).get("published_at") return AgentAssetListItem.model_validate(payload) @staticmethod diff --git a/server/src/app/services/agent_foundation.py b/server/src/app/services/agent_foundation.py index 60ed81b..32cbd12 100644 --- a/server/src/app/services/agent_foundation.py +++ b/server/src/app/services/agent_foundation.py @@ -2,7 +2,7 @@ from __future__ import annotations import threading -from sqlalchemy import select +from sqlalchemy import inspect, select, text from sqlalchemy.orm import Session from app.core.config import get_settings @@ -75,6 +75,7 @@ class AgentFoundationService( try: Base.metadata.create_all(bind=self.db.get_bind()) self._ensure_agent_asset_schema() + self._ensure_financial_record_schema() self._seed_agent_assets() self._sync_demo_financial_records() self._seed_runs_and_logs() @@ -88,6 +89,36 @@ class AgentFoundationService( bind = self.db.get_bind() return str(getattr(bind, "url", "") or id(bind)) + def _ensure_financial_record_schema(self) -> None: + bind = self.db.get_bind() + inspector = inspect(bind) + if "expense_claims" not in inspector.get_table_names(): + return + + column_names = {column["name"] for column in inspector.get_columns("expense_claims")} + dialect_name = bind.dialect.name + timestamp_type = "TIMESTAMP WITH TIME ZONE" if dialect_name == "postgresql" else "DATETIME" + boolean_default = "FALSE" if dialect_name == "postgresql" else "0" + + if "hermes_scanned_at" not in column_names: + self.db.execute( + text(f"ALTER TABLE expense_claims ADD COLUMN hermes_scanned_at {timestamp_type}") + ) + if "hermes_risk_flag" not in column_names: + self.db.execute( + text( + "ALTER TABLE expense_claims " + f"ADD COLUMN hermes_risk_flag BOOLEAN DEFAULT {boolean_default} NOT NULL" + ) + ) + self.db.execute( + text( + "CREATE INDEX IF NOT EXISTS ix_expense_claims_hermes_risk_flag " + "ON expense_claims (hermes_risk_flag)" + ) + ) + self.db.flush() + def _sync_demo_financial_records(self) -> None: if get_settings().seed_demo_financial_records: self._seed_financial_records() diff --git a/server/src/app/services/employee.py b/server/src/app/services/employee.py index c313416..44f1a8c 100644 --- a/server/src/app/services/employee.py +++ b/server/src/app/services/employee.py @@ -651,7 +651,11 @@ class EmployeeService: column_names = {column["name"] for column in inspector.get_columns("employees")} if "password_hash" not in column_names: self.db.execute(text("ALTER TABLE employees ADD COLUMN password_hash VARCHAR(255)")) - self.db.flush() + if "compliance_score" not in column_names: + self.db.execute( + text("ALTER TABLE employees ADD COLUMN compliance_score INTEGER DEFAULT 100 NOT NULL") + ) + self.db.flush() def _seed_employee_history(self, employee: Employee, definition: dict[str, Any]) -> None: existing_keys = { diff --git a/server/src/app/services/expense_type_keywords.py b/server/src/app/services/expense_type_keywords.py index 657ff53..006fc27 100644 --- a/server/src/app/services/expense_type_keywords.py +++ b/server/src/app/services/expense_type_keywords.py @@ -141,6 +141,10 @@ EXPENSE_TYPE_KEYWORD_GROUPS: tuple[tuple[str, str, tuple[str, ...]], ...] = ( "办公用品", "办公耗材", "办公设备", + "采购", + "集中采购", + "物资采购", + "办公采购", "办公", "文具", "耗材", diff --git a/server/src/app/services/hermes_expense_report.py b/server/src/app/services/hermes_expense_report.py new file mode 100644 index 0000000..1b2d0f3 --- /dev/null +++ b/server/src/app/services/hermes_expense_report.py @@ -0,0 +1,104 @@ +from __future__ import annotations + +import json +from datetime import datetime, timedelta, timezone +from typing import Any + +from sqlalchemy import func, select +from sqlalchemy.orm import Session + +from app.core.logging import get_logger +from app.models.financial_record import ExpenseClaim +from app.services.runtime_chat import RuntimeChatService + +logger = get_logger("app.services.hermes_expense_report") + + +class HermesExpenseReportService: + def __init__(self, db: Session) -> None: + self.db = db + self.chat_service = RuntimeChatService(db) + + def generate_weekly_report(self, log_id: str | None = None) -> None: + logger.info("Starting Hermes weekly expense report generation...") + + # 1. 聚合数据 + aggregated_data = self._aggregate_recent_expenses(days=7) + if not aggregated_data.get("total_amount"): + logger.info("No expense data in the last 7 days. Skipping report.") + return + + # 2. 传入大模型分析 + report_markdown = self._generate_insights_with_llm(aggregated_data) + + if not report_markdown: + logger.warning("Failed to generate expense report from LLM.") + return + + # 3. 模拟发送报告 + self._deliver_report(report_markdown, log_id) + logger.info("Hermes weekly expense report generation completed.") + + def _aggregate_recent_expenses(self, days: int = 7) -> dict[str, Any]: + target_date = datetime.now(timezone.utc) - timedelta(days=days) + + # 基础过滤:最近N天且不是驳回状态的单据 + base_filter = [ + ExpenseClaim.occurred_at >= target_date, + ExpenseClaim.status != "rejected" + ] + + # 1. 按部门汇总 + dept_stmt = select( + ExpenseClaim.department_name, + func.sum(ExpenseClaim.amount).label("total") + ).where(*base_filter).group_by(ExpenseClaim.department_name) + + dept_results = self.db.execute(dept_stmt).all() + by_department = {row.department_name or "Unknown": float(row.total or 0) for row in dept_results} + + # 2. 按类目汇总 + type_stmt = select( + ExpenseClaim.expense_type, + func.sum(ExpenseClaim.amount).label("total") + ).where(*base_filter).group_by(ExpenseClaim.expense_type) + + type_results = self.db.execute(type_stmt).all() + by_expense_type = {row.expense_type or "Unknown": float(row.total or 0) for row in type_results} + + # 3. 总花费 + total_amount = sum(by_department.values()) + + return { + "period": f"Last {days} days", + "total_amount": total_amount, + "by_department": by_department, + "by_expense_type": by_expense_type + } + + def _generate_insights_with_llm(self, data: dict[str, Any]) -> str | None: + system_prompt = ( + "你是公司的财务分析专家。请根据提供的最近期业务开销数据,撰写一份简洁有力的【高管费控洞察周报】。\n" + "要求:\n" + "1. 不要机械地罗列数字,要像人一样指出异常(例如:哪个部门花钱最多?打车费是不是异常高?)。\n" + "2. 给出 1 条削减成本的实操建议。\n" + "3. 纯 Markdown 格式输出,不超过 300 字。" + ) + + messages = [ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": f"开销统计数据:\n{json.dumps(data, ensure_ascii=False, indent=2)}"} + ] + + response = self.chat_service.complete( + messages, + max_tokens=800, + temperature=0.4 + ) + return response + + def _deliver_report(self, report_markdown: str, log_id: str | None) -> None: + # TODO: 未来在这里接入企微/钉钉机器人或邮件发送接口 + logger.info(f"\n================ Hermes Weekly Report [LogID: {log_id}] ================\n" + f"{report_markdown}\n" + f"==========================================================================") diff --git a/server/src/app/services/hermes_risk_scanner.py b/server/src/app/services/hermes_risk_scanner.py new file mode 100644 index 0000000..5b78f77 --- /dev/null +++ b/server/src/app/services/hermes_risk_scanner.py @@ -0,0 +1,135 @@ +from __future__ import annotations + +import json +from datetime import datetime, timezone +from typing import Any + +from sqlalchemy import or_, select +from sqlalchemy.orm import Session + +from app.core.logging import get_logger +from app.models.financial_record import ExpenseClaim +from app.models.hermes_config import HermesTaskExecutionLog +from app.models.hermes_report import HermesRiskReport +from app.services.runtime_chat import RuntimeChatService + +logger = get_logger("app.services.hermes_risk_scanner") + +class HermesRiskScannerService: + def __init__(self, db: Session) -> None: + self.db = db + self.chat_service = RuntimeChatService(db) + + def scan_global_risks(self, log_id: str | None = None) -> None: + logger.info("Starting global risk scan for Hermes...") + + # 1. Fetch unscanned claims + claims = self._fetch_unscanned_claims() + if not claims: + logger.info("No unscanned claims found. Aborting scan.") + return + + logger.info(f"Fetched {len(claims)} claims to analyze.") + + # 2. Extract context for LLM + claims_context = [] + for c in claims: + claims_context.append({ + "claim_id": c.id, + "claim_no": c.claim_no, + "employee_name": c.employee_name, + "department_name": c.department_name, + "expense_type": c.expense_type, + "location": c.location, + "amount": float(c.amount), + "occurred_at": str(c.occurred_at) if c.occurred_at else None, + "reason": c.reason, + }) + + # 3. Analyze with LLM + risk_results = self._analyze_claims_with_llm(claims_context) + + # 4. Process and persist results + detected_risk_count = 0 + if risk_results: + for risk in risk_results: + claim_ids = risk.get("claim_ids", []) + if not claim_ids: + continue + + detected_risk_count += 1 + for cid in claim_ids: + report = HermesRiskReport( + claim_id=cid, + execution_log_id=log_id, + risk_level=risk.get("risk_level", "medium"), + risk_type=risk.get("risk_type", "unknown"), + risk_description=risk.get("description", "No description provided"), + related_claim_ids=claim_ids, + ) + self.db.add(report) + + # Update claim flags + claim_obj = next((c for c in claims if c.id == cid), None) + if claim_obj: + claim_obj.hermes_risk_flag = True + + # 5. Mark all as scanned + now = datetime.now(timezone.utc) + for c in claims: + c.hermes_scanned_at = now + + self.db.commit() + logger.info(f"Hermes risk scan completed. Found {detected_risk_count} risks.") + + def _fetch_unscanned_claims(self) -> list[ExpenseClaim]: + stmt = select(ExpenseClaim).where( + ExpenseClaim.status.in_(["draft", "submitted", "review"]), + or_( + ExpenseClaim.hermes_scanned_at.is_(None), + ExpenseClaim.hermes_risk_flag.is_(False) # only rescan if it has no flags yet + ) + ).limit(50) # Batch size to prevent Token overflow + + return list(self.db.scalars(stmt).all()) + + def _analyze_claims_with_llm(self, claims_context: list[dict[str, Any]]) -> list[dict[str, Any]]: + system_prompt = ( + "你是 X-Financial 的 Hermes 内控审计智能体。请分析以下近期的报销单数据集合,寻找以下潜在风险:\n" + "1. 拆单行为 (split_billing):同一人在相邻日期针对同一类目/商户提交多笔恰好贴近免审额度的小额单据。\n" + "2. 群体合谋 (collusion):不同部门的员工在同一天去同一家非标准酒店类偏僻商户高额消费。\n" + "3. 异常频次 (frequency_anomaly):某员工在短时间内的打车或招待频次极度不合理。\n" + "请严格以 JSON 数组格式返回结果,如果没有风险返回空数组 `[]`。\n" + "JSON 格式要求:\n" + "[\n" + " {\n" + ' "risk_type": "split_billing",\n' + ' "risk_level": "high",\n' + ' "claim_ids": ["uuid-1", "uuid-2"],\n' + ' "description": "详细推理过程,为什么判定为拆单。"\n' + " }\n" + "]\n" + ) + + messages = [ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": json.dumps(claims_context, ensure_ascii=False, indent=2)} + ] + + response_text = self.chat_service.complete( + messages, + max_tokens=1500, + temperature=0.1 + ) + + if not response_text: + logger.warning("LLM returned empty response for risk scan.") + return [] + + # Clean markdown formatting if present + cleaned_text = response_text.replace("```json", "").replace("```", "").strip() + try: + return json.loads(cleaned_text) + except json.JSONDecodeError as e: + logger.error(f"Failed to parse LLM risk scan response as JSON: {e}\nResponse: {response_text}") + return [] diff --git a/server/src/app/services/hermes_scheduler.py b/server/src/app/services/hermes_scheduler.py new file mode 100644 index 0000000..bc70c96 --- /dev/null +++ b/server/src/app/services/hermes_scheduler.py @@ -0,0 +1,131 @@ +import logging +import threading +import time +from datetime import datetime, timezone +import traceback + +from sqlalchemy import select +from sqlalchemy.orm import Session + +from app.core.logging import get_logger +from app.db.session import get_session_factory +from app.models.hermes_config import HermesTaskConfig, HermesTaskExecutionLog +from app.services.hermes_risk_scanner import HermesRiskScannerService +from app.services.hermes_expense_report import HermesExpenseReportService + +logger = get_logger("app.services.hermes_scheduler") + + +class HermesScheduler: + def __init__(self) -> None: + self._stop_event = threading.Event() + self._thread: threading.Thread | None = None + self._lock = threading.Lock() + self.session_factory = get_session_factory() + + def start(self) -> None: + with self._lock: + if self._thread is not None and self._thread.is_alive(): + return + self._stop_event.clear() + self._thread = threading.Thread( + target=self._run_loop, + name="hermes-agent-scheduler", + daemon=True, + ) + self._thread.start() + logger.info("Hermes Agent Scheduler started.") + + def shutdown(self) -> None: + with self._lock: + thread = self._thread + self._thread = None + self._stop_event.set() + if thread is not None and thread.is_alive(): + thread.join(timeout=3) + logger.info("Hermes Agent Scheduler stopped.") + + def _run_loop(self) -> None: + logger.info("Hermes background loop is now active. Polling interval: 60s.") + while not self._stop_event.is_set(): + try: + self._check_and_run_tasks() + except Exception as e: + logger.error(f"Error in Hermes run loop: {e}", exc_info=True) + + # 睡眠一分钟,每分钟轮询一次 + if self._stop_event.wait(60.0): + break + + def _check_and_run_tasks(self) -> None: + db = self.session_factory() + try: + # 获取所有启用的任务配置 + stmt = select(HermesTaskConfig).where(HermesTaskConfig.is_enabled == True) + configs = db.scalars(stmt).all() + + for config in configs: + if self._should_run_now(db, config): + self._execute_task(db, config) + + finally: + db.close() + + def _should_run_now(self, db: Session, config: HermesTaskConfig) -> bool: + # 简单策略:检查是否在过去24小时内运行过。 + # 如果没有 croniter 库,我们暂时采用按天执行的简化逻辑 + stmt = select(HermesTaskExecutionLog).where( + HermesTaskExecutionLog.config_id == config.id, + HermesTaskExecutionLog.status.in_(["success", "running"]) + ).order_by(HermesTaskExecutionLog.started_at.desc()).limit(1) + + last_log = db.scalars(stmt).first() + + if not last_log: + return True # 从未执行过,立即执行 + + now = datetime.now(timezone.utc) + elapsed_hours = (now - last_log.started_at).total_seconds() / 3600 + + # 简化:只要距离上次成功执行超过了 23.5 小时,就认为该跑了(模拟每天跑一次) + if elapsed_hours >= 23.5: + return True + + return False + + def _execute_task(self, db: Session, config: HermesTaskConfig) -> None: + logger.info(f"Triggering Hermes task: {config.task_type} (Config ID: {config.id})") + + # 创建执行日志,标记为 running + log_record = HermesTaskExecutionLog( + config_id=config.id, + status="running" + ) + db.add(log_record) + db.commit() + db.refresh(log_record) + + try: + if config.task_type == "global_risk_scan": + scanner = HermesRiskScannerService(db) + scanner.scan_global_risks(log_id=log_record.id) + elif config.task_type == "weekly_expense_report": + reporter = HermesExpenseReportService(db) + reporter.generate_weekly_report(log_id=log_record.id) + + log_record.status = "success" + log_record.completed_at = datetime.now(timezone.utc) + log_record.result_summary = "Task executed successfully." + + except Exception as e: + logger.error(f"Failed to execute Hermes task {config.task_type}: {e}") + log_record.status = "failed" + log_record.completed_at = datetime.now(timezone.utc) + log_record.error_trace = traceback.format_exc() + + finally: + db.commit() + + +# 全局单例 +hermes_scheduler = HermesScheduler() diff --git a/server/src/app/services/knowledge_document_extractors.py b/server/src/app/services/knowledge_document_extractors.py index 8c1fcd7..f95de52 100644 --- a/server/src/app/services/knowledge_document_extractors.py +++ b/server/src/app/services/knowledge_document_extractors.py @@ -34,10 +34,104 @@ def _extract_docx_text(file_path: Path) -> str: return "当前 Word 文件解析失败。" root = ElementTree.fromstring(xml_content) + body = next((node for node in root.iter() if node.tag.endswith("}body")), root) + blocks: list[str] = [] + + for child in body: + if child.tag.endswith("}p"): + paragraph = _extract_docx_paragraph_text(child) + if paragraph: + blocks.append(paragraph) + continue + if child.tag.endswith("}tbl"): + table = _extract_docx_table_rows(child) + rendered = _build_docx_table_markdown(table) + if rendered: + blocks.append(rendered) + + if blocks: + return "\n\n".join(blocks) + texts = [node.text.strip() for node in root.iter() if node.tag.endswith("}t") and node.text] return "\n".join(texts) +def _extract_docx_paragraph_text(node: ElementTree.Element) -> str: + parts: list[str] = [] + for child in node.iter(): + if child.tag.endswith("}t") and child.text: + parts.append(child.text) + elif child.tag.endswith("}tab"): + parts.append("\t") + elif child.tag.endswith("}br"): + parts.append("\n") + return _normalize_docx_cell_text("".join(parts)) + + +def _extract_docx_table_rows(table_node: ElementTree.Element) -> list[list[str]]: + rows: list[list[str]] = [] + for row_node in table_node: + if not row_node.tag.endswith("}tr"): + continue + + row: list[str] = [] + for cell_node in row_node: + if not cell_node.tag.endswith("}tc"): + continue + + cell_parts = [ + _extract_docx_paragraph_text(paragraph) + for paragraph in cell_node + if paragraph.tag.endswith("}p") + ] + row.append(_normalize_docx_cell_text(" ".join(part for part in cell_parts if part))) + + if any(row): + rows.append(row) + return rows + + +def _build_docx_table_markdown(rows: list[list[str]]) -> str: + visible_rows = [ + [_escape_markdown_cell(cell) for cell in row] + for row in rows + if any(str(cell or "").strip() for cell in row) + ] + if len(visible_rows) < 2: + return "" + + column_count = max(len(row) for row in visible_rows) + normalized_rows = [row + [""] * (column_count - len(row)) for row in visible_rows] + header = [ + cell or f"列{column_index + 1}" for column_index, cell in enumerate(normalized_rows[0]) + ] + body_rows = normalized_rows[1:] + parts = [_format_markdown_table(header, body_rows)] + + row_clues: list[str] = [] + for row_number, row in enumerate(body_rows, start=2): + pairs = [ + f"{header[column_index]}={value}" + for column_index, value in enumerate(row) + if value + ] + if pairs: + row_clues.append(f"- 表格第 {row_number} 行:" + ";".join(pairs)) + + if row_clues: + parts.append("### 表格行级检索线索") + parts.extend(row_clues) + + return "\n\n".join(parts) + + +def _normalize_docx_cell_text(value: str) -> str: + normalized = str(value or "").replace("\r\n", "\n").replace("\r", "\n") + normalized = re.sub(r"[ \t]*\n[ \t]*", " ", normalized) + normalized = re.sub(r"\s+", " ", normalized) + return normalized.strip() + + def _extract_document_text_from_path( *, file_path: Path, diff --git a/server/src/app/services/knowledge_normalizer.py b/server/src/app/services/knowledge_normalizer.py index 51cc607..194e524 100644 --- a/server/src/app/services/knowledge_normalizer.py +++ b/server/src/app/services/knowledge_normalizer.py @@ -12,7 +12,7 @@ logger = get_logger("app.services.knowledge_normalizer") TABLE_MARKER_PATTERN = re.compile(r"表\s*(\d+)") SECTION_HEADING_PATTERN = re.compile( - r"^(第[一二三四五六七八九十百零0-9]+[章节]\s*.*|[一二三四五六七八九十]+、.*|([一二三四五六七八九十]+).*|\([一二三四五六七八九十]+\).*)$" + r"^(第[一二三四五六七八九十百零0-9]+[部分章节]\s*.*|[一二三四五六七八九十]+、.*|([一二三四五六七八九十]+).*|\([一二三四五六七八九十]+\).*)$" ) LIST_ITEM_PATTERN = re.compile(r"^[-*•]\s+.+$") NUMBERED_ITEM_PATTERN = re.compile(r"^(?:\d+[.)、]|[①②③④⑤⑥⑦⑧⑨⑩])\s*.+$") diff --git a/server/src/app/services/knowledge_rag.py b/server/src/app/services/knowledge_rag.py index 5ab05a3..684aaf7 100644 --- a/server/src/app/services/knowledge_rag.py +++ b/server/src/app/services/knowledge_rag.py @@ -50,6 +50,12 @@ QUERY_TERM_STOPWORDS = { "哪些人", } TABLE_OR_STANDARD_QUERY_HINTS = ( + "表", + "表格", + "清单", + "明细", + "目录", + "科目", "标准", "金额", "限额", @@ -61,6 +67,20 @@ TABLE_OR_STANDARD_QUERY_HINTS = ( "档位", "额度", ) +QUERY_ANCHOR_TERMS = ( + "财务基础知识手册", + "基础知识手册", + "会计科目", + "常用会计科目", + "财务报表", + "主要税种", + "税种", + "标准", + "清单", + "明细", + "流程", +) +GENERIC_TITLE_TERMS = {"远光软件", "股份有限", "有限公司"} STRUCTURED_APPENDIX_LEADING_MARKERS = ( "# 章节导航", "# 重点章节摘录", @@ -96,6 +116,10 @@ class KnowledgeRagService: "message": "请先输入要检索的知识库问题。", } + rewritten_query = normalized_query + if conversation_history: + rewritten_query = self._rewrite_query(normalized_query, conversation_history) + workspace = ( os.environ.get("LIGHTRAG_WORKSPACE", DEFAULT_LIGHTRAG_WORKSPACE).strip() or DEFAULT_LIGHTRAG_WORKSPACE @@ -103,81 +127,102 @@ class KnowledgeRagService: local_result = query_local_text_chunks( lightrag_root=(self.storage_root / "knowledge" / ".lightrag").resolve(), workspace=workspace, - query=normalized_query, + query=rewritten_query, limit=limit, ) - if local_result.confident: - return { - "result_type": "knowledge_search", - "query": normalized_query, - "record_count": len(local_result.hits), - "hits": local_result.hits, - "references": [ - str(item.get("code") or "").strip() - for item in local_result.hits - if str(item.get("code") or "").strip() - ], - "raw_references": [], - "metadata": { - "retrieval_strategy": "local_text_chunks", - "elapsed_seconds": round(local_result.elapsed_seconds, 4), - "total_chunks": local_result.total_chunks, - "best_score": local_result.best_score, - }, - "message": f"已从本地知识块中检索到 {len(local_result.hits)} 条相关内容。", - } + runtime_hits: list[dict[str, Any]] = [] + runtime_references: list[str] = [] try: runtime = self._get_runtime() - raw = runtime.query_data(normalized_query, conversation_history=conversation_history) + raw = runtime.query_data(rewritten_query, conversation_history=conversation_history) + data = raw.get("data") if isinstance(raw, dict) else {} + chunks = list(data.get("chunks") or []) if isinstance(data, dict) else [] + entities = list(data.get("entities") or []) if isinstance(data, dict) else [] + runtime_references = list(data.get("references") or []) if isinstance(data, dict) else [] + runtime_hits = self._build_hits_from_query_data( + query=rewritten_query, + chunks=chunks, + entities=entities, + limit=limit, + ) except Exception as exc: logger.warning("Knowledge query failed: %s", exc) + + all_hits: dict[str, dict[str, Any]] = {} + for hit in local_result.hits: + hit["score"] = int(hit.get("score") or 0) + all_hits[hit["code"]] = hit + + for hit in runtime_hits: + code = hit["code"] + if code in all_hits: + all_hits[code]["score"] = max(all_hits[code]["score"], int(hit.get("score") or 0) + 20) + if not all_hits[code].get("tags") and hit.get("tags"): + all_hits[code]["tags"] = hit["tags"] + else: + hit["score"] = int(hit.get("score") or 0) + all_hits[code] = hit + + merged_hits = sorted(all_hits.values(), key=lambda x: int(x.get("score") or 0), reverse=True)[:max(1, limit)] + + if not merged_hits: return { "result_type": "knowledge_search", - "query": normalized_query, + "query": rewritten_query, "record_count": 0, "hits": [], "references": [], - "message": f"知识库检索暂不可用:{exc}", - } - - data = raw.get("data") if isinstance(raw, dict) else {} - chunks = list(data.get("chunks") or []) if isinstance(data, dict) else [] - entities = list(data.get("entities") or []) if isinstance(data, dict) else [] - references = list(data.get("references") or []) if isinstance(data, dict) else [] - hits = self._build_hits_from_query_data( - query=normalized_query, - chunks=chunks, - entities=entities, - limit=limit, - ) - - if not hits: - return { - "result_type": "knowledge_search", - "query": normalized_query, - "record_count": 0, - "hits": [], - "references": [], - "raw_references": references, + "raw_references": runtime_references, "message": "当前知识库中没有检索到与本次问题直接匹配的内容。", } return { "result_type": "knowledge_search", - "query": normalized_query, - "record_count": len(hits), - "hits": hits, + "query": rewritten_query, + "record_count": len(merged_hits), + "hits": merged_hits, "references": [ str(item.get("code") or "").strip() - for item in hits + for item in merged_hits if str(item.get("code") or "").strip() ], - "raw_references": references, - "metadata": raw.get("metadata") if isinstance(raw, dict) else {}, - "message": f"已从知识库中检索到 {len(hits)} 条相关内容。", + "raw_references": runtime_references, + "metadata": { + "retrieval_strategy": "fusion", + "local_total_chunks": local_result.total_chunks, + "local_best_score": local_result.best_score, + }, + "message": f"已从知识库中联合检索到 {len(merged_hits)} 条相关内容。", } + def _rewrite_query(self, query: str, conversation_history: list[dict[str, str]]) -> str: + if not self.db: + return query + + from app.services.runtime_chat import RuntimeChatService + try: + chat_service = RuntimeChatService(self.db) + messages: list[dict[str, Any]] = [{"role": "system", "content": "你是一个查询重写助手。你的任务是根据用户的多轮对话历史,将用户的最后一次提问重写为一句独立、完整的查询语句,以便于在知识库中进行向量检索。只输出重写后的句子,不要任何解释。"}] + for msg in conversation_history[-6:]: + messages.append({"role": msg.get("role", "user"), "content": msg.get("content", "")}) + messages.append({"role": "user", "content": f"当前提问:{query}\n\n请重写当前提问。"}) + + rewritten = chat_service.complete( + messages, + max_tokens=60, + temperature=0.1, + timeout_seconds=10, + ) + + if rewritten and len(rewritten) > 2 and len(rewritten) < 80: + logger.info("Query rewritten: '%s' -> '%s'", query, rewritten) + return rewritten + except Exception as exc: + logger.warning("Query rewrite failed: %s", exc) + + return query + def index_documents( self, *, @@ -686,6 +731,24 @@ def _extract_query_terms(query: str) -> list[str]: remember(item) for block in re.findall(r"[\u4e00-\u9fff]{2,20}", normalized_query): + for marker in ("标准", "金额", "限额", "额度"): + marker_index = block.find(marker) + if marker_index <= 0: + continue + subject = block[:marker_index] + for width in (6, 4, 3, 2): + remember(subject[-width:]) + for anchor in QUERY_ANCHOR_TERMS: + if anchor in block: + remember(anchor) + tail = block[-14:] + for size in (8, 7, 6, 5, 4): + for start in range(0, len(tail) - size + 1): + piece = tail[start : start + size] + if any(anchor in piece for anchor in QUERY_ANCHOR_TERMS): + remember(piece) + if len(terms) >= MAX_QUERY_TERMS: + return terms if len(block) <= 4: remember(block) continue @@ -715,6 +778,11 @@ def _score_knowledge_hit( matched_terms = [term for term in query_terms if term in haystack] score += len(matched_terms) * 8 score += sum(1 for term in matched_terms if term in title) * 6 + score += sum( + (len(term) - 3) * 12 + for term in matched_terms + if len(term) >= 4 and term in title and term not in GENERIC_TITLE_TERMS + ) leading_appendix_marker = _leading_structured_appendix_marker(content) if leading_appendix_marker == "# 章节导航": diff --git a/server/src/app/services/knowledge_rag_local.py b/server/src/app/services/knowledge_rag_local.py index 9e601be..089997a 100644 --- a/server/src/app/services/knowledge_rag_local.py +++ b/server/src/app/services/knowledge_rag_local.py @@ -42,6 +42,12 @@ LOCAL_QUERY_STOPWORDS = { "问题", } LOCAL_TABLE_QUERY_HINTS = ( + "表", + "表格", + "清单", + "明细", + "目录", + "科目", "标准", "金额", "限额", @@ -53,6 +59,20 @@ LOCAL_TABLE_QUERY_HINTS = ( "档位", "额度", ) +LOCAL_QUERY_ANCHOR_TERMS = ( + "财务基础知识手册", + "基础知识手册", + "会计科目", + "常用会计科目", + "财务报表", + "主要税种", + "税种", + "标准", + "清单", + "明细", + "流程", +) +LOCAL_GENERIC_TITLE_TERMS = {"远光软件", "股份有限", "有限公司"} LOCAL_DOMAIN_TERMS = ( "报销", "费用", @@ -253,6 +273,8 @@ def _score_local_chunk( score += weight if term in lowered_title: score += max(4, weight) + if len(term) >= 4 and term not in LOCAL_GENERIC_TITLE_TERMS: + score += (len(term) - 3) * 12 occurrences = lowered_content.count(term) if occurrences > 1: score += min(8, occurrences * 2) @@ -299,6 +321,24 @@ def _extract_local_query_terms(query: str) -> list[str]: remember(item) for block in re.findall(r"[\u4e00-\u9fff]{2,24}", normalized_query): + for marker in ("标准", "金额", "限额", "额度"): + marker_index = block.find(marker) + if marker_index <= 0: + continue + subject = block[:marker_index] + for width in (6, 4, 3, 2): + remember(subject[-width:]) + for anchor in LOCAL_QUERY_ANCHOR_TERMS: + if anchor in block: + remember(anchor) + tail = block[-14:] + for size in (8, 7, 6, 5, 4): + for start in range(0, len(tail) - size + 1): + piece = tail[start : start + size] + if any(anchor in piece for anchor in LOCAL_QUERY_ANCHOR_TERMS): + remember(piece) + if len(terms) >= MAX_LOCAL_QUERY_TERMS: + return terms if len(block) <= 4: remember(block) continue diff --git a/server/src/app/services/ontology.py b/server/src/app/services/ontology.py index a695ed6..1201989 100644 --- a/server/src/app/services/ontology.py +++ b/server/src/app/services/ontology.py @@ -102,7 +102,7 @@ class SemanticOntologyService( context_json = payload.context_json or {} reference = self._load_reference_catalog() compact_query = self._compact(query) - entities = self._extract_entities(query, compact_query, reference) + entities = self._extract_entities(query, compact_query, reference, context_json=context_json) rule_scenario, scenario_score = self._detect_scenario(compact_query) time_range, _time_score = self._extract_time_range( query, @@ -111,9 +111,14 @@ class SemanticOntologyService( ) session_scenario = self._resolve_session_type_scenario(context_json) context_scenario = self._resolve_context_scenario(context_json) + application_context = self._is_expense_application_context(context_json) + application_query = self._looks_like_expense_application(compact_query) if session_scenario == "knowledge": rule_scenario = "knowledge" scenario_score = max(scenario_score, 0.34) + if session_scenario != "knowledge" and (application_context or application_query): + rule_scenario = "expense" + scenario_score = max(scenario_score, 0.22) if rule_scenario == "unknown" and context_scenario is not None: rule_scenario = context_scenario scenario_score = max(scenario_score, 0.14) @@ -138,6 +143,9 @@ class SemanticOntologyService( entities=entities, time_range=time_range, ) + if session_scenario != "knowledge" and (application_context or application_query): + rule_intent = "draft" + intent_score = max(intent_score, 0.22) if session_scenario != "knowledge" and self._should_inherit_expense_draft( compact_query, scenario=rule_scenario, diff --git a/server/src/app/services/ontology_detection.py b/server/src/app/services/ontology_detection.py index 4443035..d91d348 100644 --- a/server/src/app/services/ontology_detection.py +++ b/server/src/app/services/ontology_detection.py @@ -20,6 +20,8 @@ from app.services.ontology_rules import ( COMPARE_KEYWORDS, DRAFT_FOLLOW_UP_KEYWORDS, DRAFT_KEYWORDS, + EXPENSE_APPLICATION_CONTEXT_TYPES, + EXPENSE_APPLICATION_KEYWORDS, EXPENSE_NARRATIVE_KEYWORDS, EXPENSE_REVIEW_ACTIONS, EXPLAIN_KEYWORDS, @@ -71,6 +73,21 @@ EXPLICIT_ENTERTAINMENT_KEYWORDS = ( class OntologyDetectionMixin: + @staticmethod + def _is_expense_application_context(context_json: dict[str, Any]) -> bool: + document_type = str(context_json.get("document_type") or "").strip() + application_stage = str(context_json.get("application_stage") or "").strip() + entry_source = str(context_json.get("entry_source") or "").strip() + return ( + document_type in EXPENSE_APPLICATION_CONTEXT_TYPES + or application_stage in EXPENSE_APPLICATION_CONTEXT_TYPES + or entry_source in {"documents_application", "expense_application"} + ) + + @staticmethod + def _looks_like_expense_application(compact_query: str) -> bool: + return any(keyword in compact_query for keyword in EXPENSE_APPLICATION_KEYWORDS) + def _detect_scenario(self, compact_query: str) -> tuple[str, float]: scores = {key: 0.0 for key in SCENARIO_KEYWORDS} for scenario, keywords in SCENARIO_KEYWORDS.items(): @@ -341,6 +358,9 @@ class OntologyDetectionMixin: "conversation_id": payload.context_json.get("conversation_id"), "conversation_scenario": payload.context_json.get("conversation_scenario"), "conversation_intent": payload.context_json.get("conversation_intent"), + "document_type": payload.context_json.get("document_type"), + "application_stage": payload.context_json.get("application_stage"), + "application_fields": payload.context_json.get("application_fields"), "draft_claim_id": payload.context_json.get("draft_claim_id"), "review_action": payload.context_json.get("review_action"), "review_form_values": payload.context_json.get("review_form_values"), diff --git a/server/src/app/services/ontology_extraction.py b/server/src/app/services/ontology_extraction.py index 2f5bad5..219761e 100644 --- a/server/src/app/services/ontology_extraction.py +++ b/server/src/app/services/ontology_extraction.py @@ -18,7 +18,12 @@ from app.services.ontology_rules import ( DATE_RANGE_PATTERN, EXPLICIT_DATE_PATTERN, EXPLICIT_MONTH_PATTERN, + EXPENSE_APPLICATION_ATTACHMENT_REQUIRED_TYPES, + EXPENSE_APPLICATION_CONTEXT_TYPES, + EXPENSE_APPLICATION_KEYWORDS, + EXPENSE_APPLICATION_REQUIRED_SLOT_KEYS, EXPENSE_TYPE_KEYWORDS, + GENERIC_EXPENSE_APPLICATION_PROMPTS, GENERIC_EXPENSE_PROMPTS, LOCATION_KEYWORDS, MONTH_DAY_PATTERN, @@ -30,6 +35,21 @@ from app.services.ontology_rules import ( class OntologyExtractionMixin: + @staticmethod + def _is_expense_application_context_value(context_json: dict[str, Any]) -> bool: + document_type = str(context_json.get("document_type") or "").strip() + application_stage = str(context_json.get("application_stage") or "").strip() + entry_source = str(context_json.get("entry_source") or "").strip() + return ( + document_type in EXPENSE_APPLICATION_CONTEXT_TYPES + or application_stage in EXPENSE_APPLICATION_CONTEXT_TYPES + or entry_source in {"documents_application", "expense_application"} + ) + + @staticmethod + def _has_expense_application_signal(compact_query: str) -> bool: + return any(keyword in compact_query for keyword in EXPENSE_APPLICATION_KEYWORDS) + def _infer_default_missing_slots( self, compact_query: str, @@ -46,6 +66,44 @@ class OntologyExtractionMixin: entity_types = {item.type for item in entities} attachment_count = int(context_json.get("attachment_count") or 0) missing_slots: list[str] = [] + application_mode = ( + self._is_expense_application_context_value(context_json) + or self._has_expense_application_signal(compact_query) + or any( + item.type == "document_type" and item.normalized_value == "expense_application" + for item in entities + ) + ) + + if application_mode: + form_values = context_json.get("review_form_values") + if not isinstance(form_values, dict): + form_values = {} + expense_type_codes = { + str(item.normalized_value or item.value or "").strip() + for item in entities + if item.type == "expense_type" + } + if "expense_type" not in entity_types and not str(form_values.get("expense_type") or "").strip(): + missing_slots.append("expense_type") + if "amount" not in entity_types and not str(form_values.get("amount") or "").strip(): + missing_slots.append("amount") + if not time_range.start_date and not ( + str(form_values.get("time_range") or form_values.get("business_time") or "").strip() + ): + missing_slots.append("time_range") + reason_value = str( + form_values.get("reason") + or form_values.get("business_reason") + or form_values.get("reason_value") + or "" + ).strip() + if not reason_value and compact_query in GENERIC_EXPENSE_APPLICATION_PROMPTS: + missing_slots.append("reason") + if attachment_count <= 0 and expense_type_codes & EXPENSE_APPLICATION_ATTACHMENT_REQUIRED_TYPES: + missing_slots.append("attachments") + ordered_keys = [*EXPENSE_APPLICATION_REQUIRED_SLOT_KEYS, "attachments"] + return [item for item in ordered_keys if item in missing_slots] if self._is_generic_expense_prompt(compact_query): if "expense_type" not in entity_types: @@ -98,14 +156,40 @@ class OntologyExtractionMixin: query: str, compact_query: str, reference: ReferenceCatalog, + *, + context_json: dict[str, Any] | None = None, ) -> list[OntologyEntity]: entities: dict[tuple[str, str], OntologyEntity] = {} + context_json = context_json or {} def upsert(entity: OntologyEntity) -> None: key = (entity.type, entity.normalized_value) if key not in entities: entities[key] = entity + if ( + self._is_expense_application_context_value(context_json) + or self._has_expense_application_signal(compact_query) + ): + upsert( + self._make_entity( + "document_type", + "费用申请", + "expense_application", + role="target", + confidence=0.94, + ) + ) + upsert( + self._make_entity( + "workflow_stage", + "前置申请", + "pre_approval", + role="target", + confidence=0.9, + ) + ) + for match in re.finditer(r"客户\s*([A-Za-z0-9一二三四五六七八九十]+)", query): suffix = match.group(1).strip() normalized = f"客户{suffix}".replace(" ", "") @@ -510,6 +594,8 @@ class OntologyExtractionMixin: "project", "location", "expense_type", + "document_type", + "workflow_stage", }: upsert( OntologyConstraint( diff --git a/server/src/app/services/ontology_rules.py b/server/src/app/services/ontology_rules.py index 72d7865..1347c30 100644 --- a/server/src/app/services/ontology_rules.py +++ b/server/src/app/services/ontology_rules.py @@ -173,6 +173,49 @@ GENERIC_EXPENSE_PROMPTS = { "发起报销", "提交报销", } +EXPENSE_APPLICATION_CONTEXT_TYPES = { + "expense_application", + "application", + "pre_approval", + "preapproval", +} +EXPENSE_APPLICATION_KEYWORDS = ( + "费用申请", + "申请单", + "发起申请", + "提交申请", + "提出申请", + "前置申请", + "报销申请", + "申请报销", + "差旅申请", + "出差申请", + "会务申请", + "会议申请", + "采购申请", + "培训申请", + "预算申请", +) +GENERIC_EXPENSE_APPLICATION_PROMPTS = { + "申请", + "费用申请", + "发起申请", + "提交申请", + "提出申请", + "申请报销", + "报销申请", +} +EXPENSE_APPLICATION_REQUIRED_SLOT_KEYS = ( + "expense_type", + "amount", + "time_range", + "reason", +) +EXPENSE_APPLICATION_ATTACHMENT_REQUIRED_TYPES = { + "meeting", + "office", + "training", +} MISSING_SLOT_LABELS = { "expense_type": "费用类型", "amount": "金额", diff --git a/server/src/app/services/risk_rule_generation.py b/server/src/app/services/risk_rule_generation.py index 6cc51ac..12aa262 100644 --- a/server/src/app/services/risk_rule_generation.py +++ b/server/src/app/services/risk_rule_generation.py @@ -14,6 +14,7 @@ from app.schemas.agent_asset import AgentAssetRiskRuleGenerateRequest from app.services.agent_asset_rule_library import AgentAssetRuleLibraryManager from app.services.agent_asset_spreadsheet import RISK_RULES_LIBRARY from app.services.audit import AuditLogService +from app.services.expense_type_keywords import EXPENSE_TYPE_LABEL_BY_CODE from app.services.risk_rule_flow_diagram import ( RiskRuleFlowDiagramField, RiskRuleFlowDiagramRenderer, @@ -43,6 +44,24 @@ RISK_LEVEL_LABELS: dict[str, str] = { "high": "高风险", } +EXPENSE_RISK_CATEGORY_CODES: tuple[str, ...] = ( + "travel", + "hotel", + "transport", + "meal", + "meeting", + "office", + "training", + "communication", + "welfare", +) +EXPENSE_RISK_CATEGORY_LABELS: dict[str, str] = { + code: EXPENSE_TYPE_LABEL_BY_CODE[code] for code in EXPENSE_RISK_CATEGORY_CODES +} +EXPENSE_RISK_CATEGORY_ALIASES = { + "entertainment": "meal", +} + FIELD_ONTOLOGY: tuple[RiskRuleField, ...] = ( RiskRuleField("claim.reason", "报销事由", "text", "claim", ("事由", "说明", "理由", "用途")), RiskRuleField( @@ -156,17 +175,23 @@ class RiskRuleGenerationService: risk_level = str(body.risk_level or "medium").strip().lower() if risk_level not in RISK_LEVEL_LABELS: raise ValueError("风险等级仅支持 low、medium、high。") + requires_attachment = bool(body.requires_attachment) + expense_category = self._normalize_expense_category(body.expense_category, domain) + expense_category_label = EXPENSE_RISK_CATEGORY_LABELS.get(expense_category or "", "") created_at = datetime.now(UTC) fields = self._resolve_fields(natural_language, domain=domain) draft = self._compile_with_model( natural_language=natural_language, domain=domain, + expense_category=expense_category, + expense_category_label=expense_category_label, risk_level=risk_level, fields=fields, ) or self._build_fallback_draft( natural_language=natural_language, domain=domain, + expense_category_label=expense_category_label, risk_level=risk_level, fields=fields, ) @@ -179,10 +204,13 @@ class RiskRuleGenerationService: draft, natural_language=natural_language, domain=domain, + expense_category=expense_category, + expense_category_label=expense_category_label, risk_level=risk_level, fields=fields, created_at=created_at, actor=actor, + requires_attachment=requires_attachment, ) rule_code = str(payload["rule_code"]) file_name = f"{rule_code}.json" @@ -209,8 +237,11 @@ class RiskRuleGenerationService: config_json={ "severity": risk_level, "enabled": True, + "requires_attachment": requires_attachment, "tag": "风险规则", "detail_mode": "json_risk", + "expense_category": expense_category, + "expense_category_label": expense_category_label, "risk_category": payload.get("risk_category"), "rule_library": RISK_RULES_LIBRARY, "rule_document": { @@ -241,7 +272,13 @@ class RiskRuleGenerationService: resource_type=AgentAssetType.RULE.value, resource_id=asset.id, before_json=None, - after_json={"rule_code": rule_code, "risk_level": risk_level, "domain": domain}, + after_json={ + "rule_code": rule_code, + "risk_level": risk_level, + "domain": domain, + "expense_category": expense_category, + "requires_attachment": requires_attachment, + }, request_id=request_id, ) self.db.refresh(asset) @@ -252,6 +289,8 @@ class RiskRuleGenerationService: *, natural_language: str, domain: str, + expense_category: str | None, + expense_category_label: str, risk_level: str, fields: list[RiskRuleField], ) -> dict[str, Any] | None: @@ -279,6 +318,8 @@ class RiskRuleGenerationService: { "business_domain": domain, "business_domain_label": BUSINESS_DOMAIN_LABELS[domain], + "expense_category": expense_category, + "expense_category_label": expense_category_label, "risk_level": risk_level, "risk_level_label": RISK_LEVEL_LABELS[risk_level], "natural_language": natural_language, @@ -370,6 +411,7 @@ class RiskRuleGenerationService: *, natural_language: str, domain: str, + expense_category_label: str, risk_level: str, fields: list[RiskRuleField], ) -> dict[str, Any]: @@ -381,8 +423,9 @@ class RiskRuleGenerationService: fields=fields, ) name = self._infer_rule_name(natural_language) + business_label = expense_category_label or BUSINESS_DOMAIN_LABELS[domain] description = ( - f"当{BUSINESS_DOMAIN_LABELS[domain]}业务满足“{natural_language}”时,系统会按" + f"当{business_label}业务满足“{natural_language}”时,系统会按" f"{RISK_LEVEL_LABELS[risk_level]}进行提示,并要求经办人或审核人补充核对依据。" ) return { @@ -393,7 +436,7 @@ class RiskRuleGenerationService: "condition_summary": condition_summary, "keywords": self._infer_keywords(natural_language), "flow": { - "start": f"{BUSINESS_DOMAIN_LABELS[domain]}单据提交", + "start": f"{business_label}单据提交", "evidence": "读取" + "、".join(item.label for item in fields[:3]), "decision": condition_summary, "pass": "未命中风险,继续业务流转", @@ -407,14 +450,18 @@ class RiskRuleGenerationService: *, natural_language: str, domain: str, + expense_category: str | None, + expense_category_label: str, risk_level: str, fields: list[RiskRuleField], created_at: datetime, actor: str, + requires_attachment: bool, ) -> dict[str, Any]: - created_stamp = created_at.strftime("%Y%m%d%H%M%S") + created_stamp = created_at.strftime("%Y%m%d%H%M%S%f") domain_slug = {"expense": "expense", "ar": "ar", "ap": "ap"}[domain] - rule_code = f"risk.{domain_slug}.generated_{created_stamp}" + category_slug = f".{expense_category}" if expense_category else "" + rule_code = f"risk.{domain_slug}{category_slug}.generated_{created_stamp}" template_key = str(draft.get("template_key") or "field_required_v1").strip() field_keys = [ str(item or "").strip() @@ -424,7 +471,7 @@ class RiskRuleGenerationService: condition_summary = ( self._clean_text(draft.get("condition_summary")) or "判断是否符合自然语言规则描述" ) - risk_category = BUSINESS_DOMAIN_LABELS[domain] + risk_category = expense_category_label or BUSINESS_DOMAIN_LABELS[domain] keywords = list(draft.get("keywords") or []) field_by_key = {item.key: item for item in fields} params: dict[str, Any] = { @@ -440,6 +487,9 @@ class RiskRuleGenerationService: if template_key == "keyword_match_v1": params["keywords"] = keywords params["search_fields"] = field_keys + applies_to: dict[str, Any] = {"domains": [domain]} + if expense_category: + applies_to["expense_categories"] = [expense_category] payload = { "schema_version": "2.0", @@ -447,12 +497,13 @@ class RiskRuleGenerationService: "name": self._clean_text(draft.get("name")) or self._infer_rule_name(natural_language), "description": self._clean_text(draft.get("description")) or natural_language, "enabled": True, + "requires_attachment": requires_attachment, "risk_dimension": "natural_language_rule", "risk_category": risk_category, "ontology_signal": "natural_language_risk", "evaluator": "template_rule", "template_key": template_key, - "applies_to": {"domains": [domain]}, + "applies_to": applies_to, "inputs": { "fields": [ { @@ -478,6 +529,9 @@ class RiskRuleGenerationService: "source_ref": "自然语言风险规则", "created_at": created_at.isoformat(), "created_by": actor, + "requires_attachment": requires_attachment, + "expense_category": expense_category, + "expense_category_label": expense_category_label, "natural_language": natural_language, "business_explanation": self._clean_text(draft.get("description")), "condition_summary": condition_summary, @@ -488,6 +542,7 @@ class RiskRuleGenerationService: payload, fields=[field_by_key[key] for key in field_keys if key in field_by_key], domain=domain, + domain_label=risk_category, risk_level=risk_level, ) return payload @@ -498,6 +553,7 @@ class RiskRuleGenerationService: *, fields: list[RiskRuleField], domain: str, + domain_label: str | None = None, risk_level: str, ) -> str: metadata = payload.get("metadata") if isinstance(payload.get("metadata"), dict) else {} @@ -506,7 +562,7 @@ class RiskRuleGenerationService: return self.flow_diagram_renderer.render( RiskRuleFlowDiagramSpec( title=self._clean_text(payload.get("name")) or "风险规则判断流程", - domain_label=BUSINESS_DOMAIN_LABELS.get(domain, "业务"), + domain_label=domain_label or BUSINESS_DOMAIN_LABELS.get(domain, "业务"), severity=risk_level, severity_label=RISK_LEVEL_LABELS.get(risk_level, "中风险"), fields=tuple( @@ -528,6 +584,21 @@ class RiskRuleGenerationService: ) ) + @staticmethod + def _normalize_expense_category(value: str | None, domain: str) -> str | None: + if domain != AgentAssetDomain.EXPENSE.value: + return None + + normalized = str(value or "").strip().lower() + if not normalized: + return None + + normalized = EXPENSE_RISK_CATEGORY_ALIASES.get(normalized, normalized) + if normalized not in EXPENSE_RISK_CATEGORY_LABELS: + allowed = "、".join(EXPENSE_RISK_CATEGORY_LABELS.values()) + raise ValueError(f"费用领域仅支持:{allowed}。") + return normalized + def _resolve_fields(self, text: str, *, domain: str) -> list[RiskRuleField]: prefixes = DOMAIN_FIELD_PREFIXES.get(domain, ()) candidates = [field for field in FIELD_ONTOLOGY if field.key.startswith(prefixes)] diff --git a/server/src/app/services/risk_rule_template_executor.py b/server/src/app/services/risk_rule_template_executor.py index dd1ed44..bb29569 100644 --- a/server/src/app/services/risk_rule_template_executor.py +++ b/server/src/app/services/risk_rule_template_executor.py @@ -172,8 +172,12 @@ class RiskRuleTemplateExecutor: if field_key == "ocr_text": values.extend([context.get("ocr_text"), context.get("ocr_summary")]) if field_key in {"hotel_city", "route_cities"}: - values.extend(self._scan_document_values(document_info, field_key)) - values.extend(self._scan_document_values(document_info, "city")) + specific_values = self._scan_document_values(document_info, field_key) + values.extend( + specific_values + if specific_values + else self._scan_document_values(document_info, "city") + ) else: values.extend(self._scan_document_values(document_info, field_key)) return self._normalize_values(values) @@ -203,8 +207,8 @@ class RiskRuleTemplateExecutor: "buyer_name": ("购买方", "抬头", "买方"), "goods_name": ("品名", "商品", "服务名称"), "issue_date": ("日期", "开票日期", "发票日期"), - "hotel_city": ("住宿城市", "酒店城市", "酒店地点"), - "route_cities": ("行程", "路线", "城市"), + "hotel_city": ("住宿城市", "酒店城市", "酒店地点", "住宿", "酒店"), + "route_cities": ("行程", "路线", "目的地", "出差城市"), "city": ("城市", "地点"), } return any(item in label for item in label_map.get(field_key, ())) diff --git a/server/src/app/services/settings.py b/server/src/app/services/settings.py index 1763e21..c5131a9 100644 --- a/server/src/app/services/settings.py +++ b/server/src/app/services/settings.py @@ -16,6 +16,7 @@ from app.db.session import get_session_factory from app.models.system_model_setting import SystemModelSetting from app.models.system_setting import SystemSetting from app.models.system_setting_secret import SystemSettingSecret +from app.models.hermes_config import HermesTaskConfig from app.repositories.settings import SETTINGS_ROW_ID, SettingsRepository from app.schemas.settings import SettingsRead, SettingsWrite from app.services.hermes_sync import ( @@ -183,28 +184,30 @@ class SettingsService: capability=config.capability, priority=config.priority, enabled=True, - api_key_encrypted=str(getattr(secrets_row, config.legacy_secret_attr, "") or ""), - ) - self.db.add(model_row) - model_rows[slot] = model_row - should_commit = True - - if should_commit: - self.db.commit() - for model_row in model_rows.values(): - self.db.refresh(model_row) - - return model_rows - - def get_settings_snapshot(self) -> SettingsRead: - settings_row, secrets_row = self.ensure_settings_ready() - model_rows = self.ensure_model_settings_ready(settings_row, secrets_row) - return self._serialize(settings_row, secrets_row, model_rows) - + + + api_key_encrypted=str(getattr(secrets_row, config.legacy_secret_attr, "") or ""), + ) + self.db.add(model_row) + model_rows[slot] = model_row + should_commit = True + + if should_commit: + self.db.commit() + for model_row in model_rows.values(): + self.db.refresh(model_row) + + return model_rows + + def get_settings_snapshot(self) -> SettingsRead: + settings_row, secrets_row = self.ensure_settings_ready() + model_rows = self.ensure_model_settings_ready(settings_row, secrets_row) + hermes_form = self._build_hermes_form_snapshot() + return self._serialize(settings_row, secrets_row, model_rows, hermes_form) + def save_settings_snapshot(self, payload: SettingsWrite) -> SettingsRead: settings_row, secrets_row = self.ensure_settings_ready() model_rows = self.ensure_model_settings_ready(settings_row, secrets_row) - if payload.adminForm.newPassword: if len(payload.adminForm.newPassword) < 5: raise ValueError("管理员密码至少需要 5 位。") @@ -308,6 +311,8 @@ class SettingsService: self._replace_secret_if_present(secrets_row, "smtp_password_encrypted", payload.mailForm.password) hermes_snapshot = capture_hermes_config_snapshot() + + self._save_hermes_form_snapshot(payload.hermesForm) try: sync_hermes_model_settings( @@ -642,46 +647,107 @@ class SettingsService: return should_commit + def _build_hermes_form_snapshot(self) -> dict: + configs = self.db.query(HermesTaskConfig).all() + capabilities = {} + schedules = {} + master_enabled = True # 这里假设只要有一个开启,主开关就是开启的(为简单起见) + + for config in configs: + task_type = config.task_type + capabilities[task_type] = config.is_enabled + + # 简化解析 cron_expression 到 time (假设 cron 为 "0 9 * * 1" 这种形式) + time_str = "00:00" + if config.cron_expression: + parts = config.cron_expression.split(" ") + if len(parts) >= 2: + minute, hour = parts[0], parts[1] + try: + time_str = f"{int(hour):02d}:{int(minute):02d}" + except ValueError: + pass + + schedules[task_type] = { + "enabled": config.is_enabled, + "time": time_str + } + + return { + "masterEnabled": master_enabled, + "notifyOnFailure": True, + "capabilities": capabilities, + "schedules": schedules + } + + def _save_hermes_form_snapshot(self, hermes_form: dict) -> None: + if not hermes_form: + return + + schedules = hermes_form.get("schedules", {}) + capabilities = hermes_form.get("capabilities", {}) + master_enabled = hermes_form.get("masterEnabled", True) + + for task_type, schedule in schedules.items(): + config = self.db.query(HermesTaskConfig).filter_by(task_type=task_type).first() + if not config: + config = HermesTaskConfig(task_type=task_type) + self.db.add(config) + + task_enabled = schedule.get("enabled", False) and capabilities.get(task_type, False) and master_enabled + config.is_enabled = task_enabled + + # 从 time 构建简单的 cron expression + time_str = schedule.get("time", "00:00") + parts = time_str.split(":") + if len(parts) == 2: + # 简单映射:把时分放进去,后面保留为 * * * (或者保留旧的后半段) + # 这里偷个懒,风险扫描每天跑,周报每周一跑 + if task_type == "global_risk_scan": + config.cron_expression = f"{int(parts[1])} {int(parts[0])} * * *" + elif task_type == "weekly_expense_report": + config.cron_expression = f"{int(parts[1])} {int(parts[0])} * * 1" + else: + config.cron_expression = f"{int(parts[1])} {int(parts[0])} * * *" + @staticmethod def _serialize( settings_row: SystemSetting, secrets_row: SystemSettingSecret, model_rows: dict[str, SystemModelSetting], + hermes_form: dict, ) -> SettingsRead: main_model = model_rows["main"] backup_model = model_rows["backup"] embedding_model = model_rows["embedding"] reranker_model = model_rows["reranker"] - - return SettingsRead( - companyForm={ - "companyName": settings_row.company_name, - "displayName": settings_row.display_name, - "companyCode": settings_row.company_code, - "recordNumber": settings_row.record_number, - "copyright": settings_row.copyright_text, - }, + + return SettingsRead( + companyForm={ + "companyName": settings_row.company_name, + "displayName": settings_row.display_name, + "companyCode": settings_row.company_code, + "recordNumber": settings_row.record_number, + "copyright": settings_row.copyright_text, + }, adminForm={ "adminAccount": settings_row.admin_account, "adminEmail": settings_row.admin_email, "newPassword": "", "confirmPassword": "", - "sessionTimeout": settings_row.session_timeout, - "noticeEmail": settings_row.notice_email, - "mfaEnabled": settings_row.mfa_enabled, - "strongPassword": settings_row.strong_password, + "sessionTimeout": settings_row.session_timeout, + "noticeEmail": settings_row.notice_email, + "mfaEnabled": settings_row.mfa_enabled, + "strongPassword": settings_row.strong_password, "loginAlertEnabled": settings_row.login_alert_enabled, "adminPasswordConfigured": bool(secrets_row.admin_password_hash), }, sessionForm={ "conversationRetentionDays": settings_row.conversation_retention_days, }, + hermesForm=hermes_form, llmForm={ "mainProvider": main_model.provider, - "mainModel": main_model.model_name, - "mainEndpoint": main_model.endpoint, - "mainApiKey": "", - "mainApiKeyConfigured": bool(main_model.api_key_encrypted), "backupProvider": backup_model.provider, "backupModel": backup_model.model_name, "backupEndpoint": backup_model.endpoint, diff --git a/server/src/app/services/user_agent_constants.py b/server/src/app/services/user_agent_constants.py index 178ea51..ea9f9b7 100644 --- a/server/src/app/services/user_agent_constants.py +++ b/server/src/app/services/user_agent_constants.py @@ -71,8 +71,8 @@ EXPENSE_SCENE_SELECTION_OPTIONS = ( ("other", "其他费用", "暂不属于以上分类的报销场景。"), ) -KNOWLEDGE_MODEL_MAIN_TIMEOUT_SECONDS = 3 -KNOWLEDGE_MODEL_BACKUP_TIMEOUT_SECONDS = 5 +KNOWLEDGE_MODEL_MAIN_TIMEOUT_SECONDS = 20 +KNOWLEDGE_MODEL_BACKUP_TIMEOUT_SECONDS = 30 KNOWLEDGE_MODEL_TIMEOUT_SECONDS = KNOWLEDGE_MODEL_BACKUP_TIMEOUT_SECONDS EXPENSE_STATUS_LABELS = { diff --git a/server/src/app/services/user_agent_knowledge.py b/server/src/app/services/user_agent_knowledge.py index a4006e0..f338688 100644 --- a/server/src/app/services/user_agent_knowledge.py +++ b/server/src/app/services/user_agent_knowledge.py @@ -86,6 +86,7 @@ class UserAgentKnowledgeMixin(UserAgentKnowledgeHelpersMixin): *, citations: list[UserAgentCitation], ) -> str | None: + return None if payload.ontology.scenario != "knowledge": return None if str(payload.tool_payload.get("result_type") or "").strip() != "knowledge_search": @@ -583,20 +584,23 @@ class UserAgentKnowledgeMixin(UserAgentKnowledgeHelpersMixin): evidence_lines: list[str] = [] for item in evidence_items[:3]: heading = str(item.get("heading") or "").strip() - heading_text = f" > {heading}" if heading else "" + if "表格行级检索线索" in heading: + heading = heading.replace("表格行级检索线索", "").strip(" >") + heading_text = f"({heading})" if heading else "" + item_title = item.get("title") or title if str(item.get("kind") or "") == "table": preview = self._extract_relevant_table_preview( str(item.get("content") or ""), self._extract_knowledge_query_terms(self._resolve_knowledge_question(payload)), ) - evidence_lines.append(f"- 《{item.get('title') or title}》{heading_text}:\n{preview}") + evidence_lines.append(f"- **《{item_title}》** {heading_text}\n{preview}") continue rendered = self._render_knowledge_evidence_text(item) if rendered: if "\n" in rendered: - evidence_lines.append(f"- 《{item.get('title') or title}》{heading_text}:\n{rendered}") + evidence_lines.append(f"- **《{item_title}》** {heading_text}\n{rendered}") else: - evidence_lines.append(f"- 《{item.get('title') or title}》{heading_text}:{rendered}") + evidence_lines.append(f"- **《{item_title}》** {heading_text}\n {rendered}") if not evidence_lines: for item in hits[:2]: @@ -607,21 +611,22 @@ class UserAgentKnowledgeMixin(UserAgentKnowledgeHelpersMixin): ) if not excerpt: continue - evidence_lines.append(f"- 《{item_title}》:{excerpt}") + evidence_lines.append(f"- **《{item_title}》**:{excerpt}") if not evidence_lines: return ( - f"{prefix}我已经从《{title}》中检索到与你这次问题相关的制度依据," - "但本次答案生成环节暂时没有成功返回。请稍后重试一次;如果仍然失败," - "建议先检查主对话模型的连通性。" + f"{prefix}当前《{title}》里可用于回答的关键条款还不够明确。" + "请补充费用类型、适用地区、职级或具体业务场景,我再继续帮你缩小范围。" ) return "\n".join( [ - f"{prefix}我已经命中与你这次问题最相关的制度依据,但答案整理阶段本轮没有及时返回。", - "先给你当前最直接的依据:", + f"{prefix}我先根据当前制度依据给出可以确认的部分。", + "", + "**依据**:", *evidence_lines, - "如果你希望我继续把这些依据整理成更完整的结论、步骤或对比说明,可以继续缩小问题范围后再问一次。", + "", + "**说明**:以上只使用当前命中的知识库证据;没有在证据中出现的适用条件或金额,我不会替你默认补齐。", ] ).strip() diff --git a/server/src/app/services/user_agent_knowledge_constants.py b/server/src/app/services/user_agent_knowledge_constants.py index 72c46ac..1d5f085 100644 --- a/server/src/app/services/user_agent_knowledge_constants.py +++ b/server/src/app/services/user_agent_knowledge_constants.py @@ -4,6 +4,9 @@ import re KNOWLEDGE_DIRECT_ANSWER_HINTS = ( "是什么", + "介绍", + "说明", + "概述", "标准", "限额", "流程", @@ -45,7 +48,7 @@ MAX_KNOWLEDGE_QUERY_TERMS = 12 MAX_KNOWLEDGE_DIRECT_EVIDENCE = 4 MAX_KNOWLEDGE_MODEL_HITS = 5 KNOWLEDGE_SECTION_HEADING_PATTERN = re.compile( - r"^(#\s*.+|##\s*.+|###\s*.+|第[一二三四五六七八九十百零0-9]+[章节条]\s*.*|[一二三四五六七八九十]+、.*|([一二三四五六七八九十]+).*|\([一二三四五六七八九十]+\).*)$" + r"^(#\s*.+|##\s*.+|###\s*.+|第[一二三四五六七八九十百零0-9]+[部分章节条]\s*.*|[一二三四五六七八九十]+、.*|([一二三四五六七八九十]+).*|\([一二三四五六七八九十]+\).*)$" ) KNOWLEDGE_LIST_ITEM_PATTERN = re.compile(r"^[-*•]\s+.+$") KNOWLEDGE_NUMBERED_ITEM_PATTERN = re.compile( diff --git a/server/src/app/services/user_agent_knowledge_helpers.py b/server/src/app/services/user_agent_knowledge_helpers.py index b629541..657f9bb 100644 --- a/server/src/app/services/user_agent_knowledge_helpers.py +++ b/server/src/app/services/user_agent_knowledge_helpers.py @@ -15,6 +15,20 @@ from app.services.user_agent_knowledge_constants import ( class UserAgentKnowledgeHelpersMixin: + GENERIC_KNOWLEDGE_TITLE_TERMS = {"远光软件", "股份有限", "有限公司"} + KNOWLEDGE_QUERY_ANCHOR_TERMS = ( + "财务基础知识手册", + "基础知识手册", + "会计科目", + "常用会计科目", + "财务报表", + "主要税种", + "税种", + "标准", + "清单", + "明细", + "流程", + ) @staticmethod def _select_knowledge_model_hits( @@ -26,7 +40,7 @@ class UserAgentKnowledgeHelpersMixin: item for item in list(tool_payload.get("hits") or []) if isinstance(item, dict) - ][: max(MAX_KNOWLEDGE_MODEL_HITS + 1, 6)] + ][: max(MAX_KNOWLEDGE_MODEL_HITS + 3, 8)] if not raw_hits: return [] @@ -64,7 +78,16 @@ class UserAgentKnowledgeHelpersMixin: matched_terms = [term for term in query_terms if term in haystack] score = max(1, 48 - rank_index * 4) score += len(matched_terms) * 10 + score += sum(max(0, len(term) - 4) * 8 for term in matched_terms) score += sum(1 for term in matched_terms if term in title) * 8 + score += sum(max(0, len(term) - 4) * 6 for term in matched_terms if term in title) + score += sum( + (len(term) - 3) * 10 + for term in matched_terms + if len(term) >= 4 + and term in title + and term not in UserAgentKnowledgeHelpersMixin.GENERIC_KNOWLEDGE_TITLE_TERMS + ) leading_marker = UserAgentKnowledgeHelpersMixin._leading_knowledge_appendix_marker(content) if leading_marker == "# 章节导航": @@ -149,6 +172,40 @@ class UserAgentKnowledgeHelpersMixin: return "" + @staticmethod + def _knowledge_list_marker_sort_key(content: str) -> int: + normalized = str(content or "").strip() + match = re.match(r"^[((]([一二三四五六七八九十百零0-9]+)[))]", normalized) + if not match: + return 999 + marker = match.group(1) + if marker.isdigit(): + return int(marker) + values = { + "零": 0, + "一": 1, + "二": 2, + "三": 3, + "四": 4, + "五": 5, + "六": 6, + "七": 7, + "八": 8, + "九": 9, + "十": 10, + } + if marker in values: + return values[marker] + if marker.startswith("十") and len(marker) == 2: + return 10 + values.get(marker[1], 0) + if marker.endswith("十") and len(marker) == 2: + return values.get(marker[0], 0) * 10 + if "十" in marker: + left, right = marker.split("十", 1) + return values.get(left, 1) * 10 + values.get(right, 0) + return 999 + + @staticmethod def _format_knowledge_heading_label(heading: str) -> str: @@ -156,6 +213,169 @@ class UserAgentKnowledgeHelpersMixin: return " / ".join(parts) + @staticmethod + def _has_inline_numbered_knowledge_items(content: str) -> bool: + return len( + re.findall( + r"[((][一二三四五六七八九十百零0-9]+[))]", + str(content or ""), + ) + ) >= 2 + + + @staticmethod + def _split_inline_numbered_knowledge_items(content: str) -> list[str]: + normalized = str(content or "").strip() + if not UserAgentKnowledgeHelpersMixin._has_inline_numbered_knowledge_items(normalized): + return [normalized] if normalized else [] + + marker_pattern = r"[((][一二三四五六七八九十百零0-9]+[))]" + first_marker = re.search(marker_pattern, normalized) + if first_marker is None: + return [normalized] if normalized else [] + + prefix = normalized[: first_marker.start()].strip(" ::") + tail = normalized[first_marker.start() :].strip() + item_pattern = ( + r"([((][一二三四五六七八九十百零0-9]+[))]\s*.*?" + r"(?=\s*[((][一二三四五六七八九十百零0-9]+[))]|\s*$))" + ) + items = [item.strip() for item in re.findall(item_pattern, tail) if item.strip()] + if prefix: + return [prefix, *items] + return items or [normalized] + + + @staticmethod + def _focus_knowledge_segment_content(content: str, query_terms: list[str]) -> str: + normalized = re.sub(r"\s+", " ", str(content or "").strip()) + if not normalized: + return "" + + anchor_terms = sorted( + { + str(term or "").strip() + for term in query_terms + if len(str(term or "").strip()) >= 3 + }, + key=len, + reverse=True, + ) + anchor_index = -1 + for term in anchor_terms: + anchor_index = normalized.lower().find(term.lower()) + if anchor_index >= 0: + break + if anchor_index < 0: + return normalized + + prefix_window = normalized[max(0, anchor_index - 40) : anchor_index] + marker_match = None + for match in re.finditer( + r"(?:第[一二三四五六七八九十百零0-9]+[部分章节条]|[一二三四五六七八九十]+、|[((][一二三四五六七八九十百零0-9]+[))])", + prefix_window, + ): + marker_match = match + start = anchor_index + if marker_match is not None: + start = max(0, anchor_index - len(prefix_window) + marker_match.start()) + + return normalized[start : start + 700].strip() + + + @staticmethod + def _split_markdown_table_cells(line: str) -> list[str]: + stripped = str(line or "").strip() + if stripped.startswith("|"): + stripped = stripped[1:] + if stripped.endswith("|"): + stripped = stripped[:-1] + return [ + re.sub(r"\s+", " ", cell.replace("**", "").strip()) + for cell in stripped.split("|") + ] + + + @classmethod + def _summarize_knowledge_table_preview(cls, preview: str) -> str: + rows: list[list[str]] = [] + for line in str(preview or "").splitlines(): + if line.count("|") < 2: + continue + cells = cls._split_markdown_table_cells(line) + if not cells or all(re.fullmatch(r":?-{2,}:?", cell.replace(" ", "")) for cell in cells): + continue + rows.append(cells) + + if len(rows) < 2: + return "可直接参考的标准表如下。" + + header = rows[0] + data_rows = [row for row in rows[1:] if len(row) == len(header)] + if len(data_rows) == 1 and len(header) >= 2: + row = data_rows[0] + subject = row[0] or "该项目" + pairs = [ + f"{label}:{value}" + for label, value in zip(header[1:], row[1:]) + if label and value and value not in {"-", "—"} + ] + if pairs: + return f"{subject}的标准为:{';'.join(pairs)}。" + + return "相关标准项如下,请按表头和行内容对应使用。" + + + def _summarize_knowledge_lines_conclusion( + self, + lines: list[str], + *, + heading: str = "", + ) -> str: + clean_lines = [ + self._clean_knowledge_segment_text(line) + for line in lines + if self._clean_knowledge_segment_text(line) + ] + if not clean_lines: + return "" + + clean_heading = str(heading or "").strip() + if not clean_heading and clean_lines and ":" not in clean_lines[0] and ":" not in clean_lines[0]: + clean_heading = clean_lines[0] + clean_heading = re.sub( + r"^[一二三四五六七八九十百零0-9]+、\s*", + "", + clean_heading, + ) + item_labels: list[str] = [] + for line in clean_lines: + if ":" not in line and ":" not in line: + continue + label = re.split(r"[::]", line, maxsplit=1)[0].strip() + if 1 <= len(label) <= 24: + item_labels.append(label) + + if clean_heading and len(item_labels) >= 2: + return f"{clean_heading}包括:{'、'.join(item_labels[:6])}。" + if item_labels: + return f"{item_labels[0]}:{clean_lines[0].split(':', 1)[-1].strip()}" + return clean_lines[0] + + + @staticmethod + def _knowledge_lines_have_multiple_labeled_items(lines: list[str]) -> bool: + labeled_count = 0 + for line in lines: + normalized = str(line or "").strip() + if ":" not in normalized and ":" not in normalized: + continue + label = re.split(r"[::]", normalized, maxsplit=1)[0].strip() + if 1 <= len(label) <= 24: + labeled_count += 1 + return labeled_count >= 2 + + def _score_knowledge_evidence_candidate( self, @@ -169,10 +389,14 @@ class UserAgentKnowledgeHelpersMixin: matched_terms = [term for term in query_terms if term in haystack] score = len(matched_terms) * 10 + score += sum(max(0, len(term) - 4) * 8 for term in matched_terms) score += sum(1 for term in matched_terms if term in heading) * 6 + score += sum(max(0, len(term) - 4) * 6 for term in matched_terms if term in heading) if kind == "table": score += 10 + if content.count("\n") < 2: + score -= 24 elif kind in {"kv", "clause", "list"}: score += 8 elif kind == "paragraph": @@ -220,6 +444,30 @@ class UserAgentKnowledgeHelpersMixin: remember(item) for block in re.findall(r"[\u4e00-\u9fff]{2,20}", normalized_question): + remember(block) + if len(terms) >= MAX_KNOWLEDGE_QUERY_TERMS: + return terms + for marker in ("标准", "金额", "限额", "额度"): + marker_index = block.find(marker) + if marker_index <= 0: + continue + subject = block[:marker_index] + for width in (6, 4, 3, 2): + remember(subject[-width:]) + for anchor in UserAgentKnowledgeHelpersMixin.KNOWLEDGE_QUERY_ANCHOR_TERMS: + if anchor in block: + remember(anchor) + tail = block[-14:] + for size in (8, 7, 6, 5, 4): + for start in range(0, len(tail) - size + 1): + piece = tail[start : start + size] + if any( + anchor in piece + for anchor in UserAgentKnowledgeHelpersMixin.KNOWLEDGE_QUERY_ANCHOR_TERMS + ): + remember(piece) + if len(terms) >= MAX_KNOWLEDGE_QUERY_TERMS: + return terms if len(block) <= 4: remember(block) continue @@ -276,7 +524,14 @@ class UserAgentKnowledgeHelpersMixin: @staticmethod - def _extract_relevant_table_preview(content: str, query_terms: list[str]) -> str: + def _extract_relevant_table_preview( + content: str, + query_terms: list[str], + *, + preferred_terms: list[str] | None = None, + max_rows: int = 3, + fallback_rows: int = 2, + ) -> str: lines = [line.strip() for line in str(content or "").splitlines() if line.strip()] if len(lines) <= 3: return "\n".join(lines) @@ -285,12 +540,39 @@ class UserAgentKnowledgeHelpersMixin: divider = lines[1] if len(lines) > 1 else "" body = lines[2:] if divider.count("|") >= 2 else lines[1:] + preferred = [ + str(term or "").strip().lower() + for term in list(preferred_terms or []) + if str(term or "").strip() + ] + base_terms = preferred + [ + str(term or "").strip().lower() + for term in query_terms + if str(term or "").strip().lower() not in preferred + ] + derived_terms: list[str] = [] + for term in base_terms: + for marker in ("标准", "金额", "限额", "额度", "是多少"): + marker_index = term.find(marker) + if marker_index <= 0: + continue + subject = term[:marker_index].strip() + if len(subject) < 2: + continue + for width in (6, 4, 3, 2): + derived_terms.append(subject[-width:]) + + search_terms: list[str] = [] + for term in [*preferred, *derived_terms, *base_terms]: + if term and term not in search_terms: + search_terms.append(term) + matched_rows = [ row for row in body - if any(term in row.lower() for term in query_terms) + if any(term in row.lower() for term in search_terms) ] - selected_rows = matched_rows[:3] or body[:2] + selected_rows = matched_rows[:max_rows] or body[:fallback_rows] preview_lines = [header] if divider: preview_lines.append(divider) @@ -298,6 +580,18 @@ class UserAgentKnowledgeHelpersMixin: return "\n".join(preview_lines).strip() + @staticmethod + def _question_requests_broad_knowledge_table(question: str) -> bool: + normalized = str(question or "").strip() + if not normalized: + return False + broad_hints = ("有哪些", "是什么", "介绍", "说明", "列表", "清单", "全部", "完整") + table_subject_hints = ("科目", "目录", "清单", "列表", "表", "明细") + return any(hint in normalized for hint in broad_hints) and any( + hint in normalized for hint in table_subject_hints + ) + + @staticmethod def _question_requires_explicit_condition(question: str) -> bool: diff --git a/server/src/app/services/user_agent_response.py b/server/src/app/services/user_agent_response.py index ff9a0b6..d25dd66 100644 --- a/server/src/app/services/user_agent_response.py +++ b/server/src/app/services/user_agent_response.py @@ -261,7 +261,6 @@ class UserAgentResponseMixin: "draft_payload": draft_payload.model_dump(mode="json") if draft_payload is not None else None, "selected_capability_codes": payload.selected_capability_codes, "requires_confirmation": payload.requires_confirmation, - "fallback_answer": fallback_answer, } if payload.ontology.scenario == "knowledge": facts["knowledge_evidence_blocks"] = self._build_knowledge_evidence_blocks( diff --git a/server/storage/knowledge/.index.json b/server/storage/knowledge/.index.json index 74e46a6..a17b24e 100644 --- a/server/storage/knowledge/.index.json +++ b/server/storage/knowledge/.index.json @@ -57,8 +57,8 @@ "uploaded_by": "系统导入", "version_number": 1, "ingest_status": 3, - "ingest_status_updated_at": "2026-05-22T09:22:52.110824+00:00", - "ingest_completed_at": "2026-05-22T09:22:52.110824+00:00", + "ingest_status_updated_at": "2026-05-23T14:30:33.605531+00:00", + "ingest_completed_at": "2026-05-23T14:30:33.605531+00:00", "ingest_document_name": "远光软件财务基础知识手册.docx", "ingest_document_updated_at": "2026-05-22T07:00:22.011016+00:00", "ingest_document_sha256": "", diff --git a/server/storage/knowledge/.lightrag/x_financial_knowledge/graph_chunk_entity_relation.graphml b/server/storage/knowledge/.lightrag/x_financial_knowledge/graph_chunk_entity_relation.graphml index a470a9d..3939722 100644 --- a/server/storage/knowledge/.lightrag/x_financial_knowledge/graph_chunk_entity_relation.graphml +++ b/server/storage/knowledge/.lightrag/x_financial_knowledge/graph_chunk_entity_relation.graphml @@ -1,12 +1,13 @@ - - - - - - - + + + + + + + + @@ -23,6 +24,7 @@ /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf<SEP>/app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx<SEP>/app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx<SEP>/app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx<SEP>/app/server/storage/knowledge/财务知识库/远光软件高新技术企业税收优惠政策汇总.pdf<SEP>/app/server/storage/knowledge/制度政策/远光软件公司内部控制基本规范.pdf<SEP>/app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx<SEP>/app/server/storage/knowledge/制度政策/远光软件公司财务管理制度总则.docx<SEP>/app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf<SEP>/app/server/storage/knowledge/制度政策/远光软件公司采购管理办法.xlsx<SEP>/app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx<SEP>/app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf<SEP>/app/server/storage/knowledge/差旅规范/远光软件国际出差管理规定.docx<SEP>/app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx<SEP>/app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx<SEP>/app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx<SEP>/app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf<SEP>/app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx<SEP>/app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf<SEP>/app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx<SEP>/app/server/storage/knowledge/税务合规/远光软件研发费用加计扣除管理办法.xlsx<SEP>/app/server/storage/knowledge/税务合规/远光软件软件产品增值税即征即退操作指南.pdf<SEP>/app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf<SEP>/app/server/storage/knowledge/预算管理/远光软件预算执行分析报告模板.docx<SEP>/app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx<SEP>/app/server/storage/knowledge/财务共享/远光软件财务共享服务操作手册.pdf<SEP>/app/server/storage/knowledge/培训资料/远光软件报销流程培训手册.pdf<SEP>/app/server/storage/knowledge/培训资料/远光软件新员工财务培训课件.pdf<SEP>/app/server/storage/knowledge/培训资料/远光软件财务制度培训手册.docx<SEP>/app/server/storage/knowledge/培训资料/远光软件财务培训课程安排.xlsx<SEP>/app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf<SEP>/app/server/storage/knowledge/常见问答/远光软件财务报销常见问题解答.docx 1779467739 + 远光软件股份有限公司 第一章总则 @@ -3406,6 +3408,7 @@ The department head also serves as the primary approver for travel‑related act /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx<SEP>/app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx 1779441756 + 库存现金 银行存款 @@ -3415,15 +3418,17 @@ The department head also serves as the primary approver for travel‑related act /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx<SEP>/app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx 1779441756 + 银行存款 应收账款 - concept - 应收账款(code 1122) is an asset-type accounting subject used for recording receivables from sales of goods and provision of services, requiring customer-level details.<SEP>应收账款represents amounts receivable from customers for selling goods or providing services.<SEP>Accounts Receivable is a service item involving payment confirmation and write-off, with a standard turnaround of 1 business day, same-day urgent turnaround, and 99% availability requirement.<SEP>应收账款is a service item involving payment confirmation and write-off, with a standard response time of 1 business day and urgent response time of same day, requiring 99% availability. - chunk-31ff57cf79d009c378478f065eda9d4d<SEP>chunk-78edb0c8ccc8238159196ecaeeb08d43<SEP>chunk-6f1d6991d45799bc8ff24afaed39244d<SEP>chunk-af56151a803634f02e294f2d692fc1f0 + content + 应收账款(code 1122) is an asset-type accounting subject used for recording receivables from sales of goods and provision of services, requiring customer-level details.<SEP>应收账款represents amounts receivable from customers for selling goods or providing services.<SEP>Accounts Receivable is a service item involving payment confirmation and write-off, with a standard turnaround of 1 business day, same-day urgent turnaround, and 99% availability requirement.<SEP>应收账款is a service item involving payment confirmation and write-off, with a standard response time of 1 business day and urgent response time of same day, requiring 99% availability.<SEP>应收账款is a specific accounting item classified under assets, representing accounts receivable. + chunk-31ff57cf79d009c378478f065eda9d4d<SEP>chunk-6f1d6991d45799bc8ff24afaed39244d<SEP>chunk-af56151a803634f02e294f2d692fc1f0<SEP>chunk-f894acfbb6c681d00f75cf9c486d491b /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx<SEP>/app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx<SEP>/app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx - 1779467128 + 1779546632 + 应收账款 其他应收款 @@ -3451,6 +3456,7 @@ The department head also serves as the primary approver for travel‑related act /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx<SEP>/app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx<SEP>/app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf 1779465910 + 固定资产 累计折旧 @@ -3469,6 +3475,7 @@ The department head also serves as the primary approver for travel‑related act /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx<SEP>/app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx<SEP>/app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx 1779467128 + 应付账款 应交税费 @@ -3478,6 +3485,7 @@ The department head also serves as the primary approver for travel‑related act /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx<SEP>/app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx 1779441756 + 应交税费 应付职工薪酬 @@ -3487,6 +3495,7 @@ The department head also serves as the primary approver for travel‑related act /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx<SEP>/app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx 1779441756 + 应付职工薪酬 主营业务收入 @@ -3496,6 +3505,7 @@ The department head also serves as the primary approver for travel‑related act /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx<SEP>/app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx 1779441756 + 主营业务收入 主营业务成本 @@ -3514,6 +3524,7 @@ The department head also serves as the primary approver for travel‑related act /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx<SEP>/app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx 1779441756 + 管理费用 销售费用 @@ -3523,6 +3534,7 @@ The department head also serves as the primary approver for travel‑related act /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx<SEP>/app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx 1779441756 + 销售费用 财务费用 @@ -3554,10 +3566,10 @@ The department head also serves as the primary approver for travel‑related act 资产类 concept - 资产类is the asset category for accounting subjects, used for recording resources and properties owned by the company.<SEP>资产类is a category classification for accounting subjects representing assets, including cash, receivables, inventory, and fixed assets. - chunk-31ff57cf79d009c378478f065eda9d4d<SEP>chunk-e726f44fb0287c5192cf61b350f18abb - /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx - 1779441742 + 资产类is the asset category for accounting subjects, used for recording resources and properties owned by the company.<SEP>资产类is a category classification for accounting subjects representing assets, including cash, receivables, inventory, and fixed assets.<SEP>资产类is an accounting classification category representing asset types in the accounting system. + chunk-31ff57cf79d009c378478f065eda9d4d<SEP>chunk-e726f44fb0287c5192cf61b350f18abb<SEP>chunk-f894acfbb6c681d00f75cf9c486d491b + /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx<SEP>/app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546632 @@ -3695,87 +3707,6 @@ The department head also serves as the primary approver for travel‑related act 1779441742 - - 财务基础知识手册 - content - 财务基础知识手册is a handbook covering foundational accounting and tax knowledge for the organization. - chunk-78edb0c8ccc8238159196ecaeeb08d43 - /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx - 1779441755 - - - - 会计要素 - concept - 会计要素consists of six fundamental elements: assets, liabilities, owner's equity, revenue, expenses, and profit. - chunk-78edb0c8ccc8238159196ecaeeb08d43 - /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx - 1779441755 - - - - 资产 - concept - 资产represents the resources owned by a company that have economic value and are expected to benefit future operations. - chunk-78edb0c8ccc8238159196ecaeeb08d43 - /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx - 1779441755 - - - - 负债 - concept - 负债represents the obligations or debts that a company owes to external parties. - chunk-78edb0c8ccc8238159196ecaeeb08d43 - /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx - 1779441755 - - - - 所有者权益 - concept - 所有者权益represents the residual interest in the assets of a company after deducting liabilities. - chunk-78edb0c8ccc8238159196ecaeeb08d43 - /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx - 1779441755 - - - - 收入 - concept - 收入represents the inflow of economic benefits arising from the main business activities. - chunk-78edb0c8ccc8238159196ecaeeb08d43 - /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx - 1779441755 - - - - 费用 - concept - 费用represents the outflow of economic benefits incurred in the process of generating revenue. - chunk-78edb0c8ccc8238159196ecaeeb08d43 - /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx - 1779441755 - - - - 利润 - concept - 利润represents the positive financial result when revenue exceeds expenses during a specific period. - chunk-78edb0c8ccc8238159196ecaeeb08d43 - /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx - 1779441756 - - - - 会计恒等式 - concept - 会计恒等式is the fundamental accounting equation expressed as assets equal liabilities plus owner's equity. - chunk-78edb0c8ccc8238159196ecaeeb08d43 - /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx - 1779441756 - - 增值税 concept @@ -3784,6 +3715,7 @@ The department head also serves as the primary approver for travel‑related act /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx<SEP>/app/server/storage/knowledge/财务知识库/远光软件高新技术企业税收优惠政策汇总.pdf<SEP>/app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx<SEP>/app/server/storage/knowledge/培训资料/远光软件财务制度培训手册.docx 1779467303 + 增值税 企业所得税 @@ -3793,6 +3725,7 @@ The department head also serves as the primary approver for travel‑related act /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx<SEP>/app/server/storage/knowledge/财务知识库/远光软件高新技术企业税收优惠政策汇总.pdf<SEP>/app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx 1779466482 + 企业所得税 个人所得税 @@ -3802,6 +3735,7 @@ The department head also serves as the primary approver for travel‑related act /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx<SEP>/app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx<SEP>/app/server/storage/knowledge/培训资料/远光软件财务制度培训手册.docx 1779467303 + 个人所得税 印花税 @@ -3811,69 +3745,7 @@ The department head also serves as the primary approver for travel‑related act /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx<SEP>/app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx 1779466482 - - - 三大财务报表 - concept - 三大财务报表consists of three main financial statements: balance sheet, income statement, and cash flow statement. - chunk-78edb0c8ccc8238159196ecaeeb08d43 - /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx - 1779441756 - - - - 资产负债表 - concept - 资产负债表reflects a company's financial position at a specific point in time. - chunk-78edb0c8ccc8238159196ecaeeb08d43 - /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx - 1779441756 - - - - 利润表 - concept - 利润表reflects a company's operating results over a defined period. - chunk-78edb0c8ccc8238159196ecaeeb08d43 - /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx - 1779441756 - - - - 现金流量表 - concept - 现金流量表reflects the inflow and outflow of cash and cash equivalents during a specific period. - chunk-78edb0c8ccc8238159196ecaeeb08d43 - /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx - 1779441756 - - - - 会计基础知识 - concept - 会计基础知识is the first section of the handbook covering fundamental accounting concepts. - chunk-78edb0c8ccc8238159196ecaeeb08d43 - /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx - 1779441756 - - - - 税务基础知识 - concept - 税务基础知识is the second section of the handbook covering major tax types. - chunk-78edb0c8ccc8238159196ecaeeb08d43 - /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx - 1779441757 - - - - 财务报表解读 - concept - 财务报表解读is the third section of the handbook covering interpretation of financial statements. - chunk-78edb0c8ccc8238159196ecaeeb08d43 - /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx - 1779441757 - + 印花税 财务术语解释手册 @@ -4058,10 +3930,10 @@ The department head also serves as the primary approver for travel‑related act Corporate Income Tax concept - Corporate income tax is a tax levied on the profits of enterprises, and certain expenses can be deducted before its calculation.<SEP>Corporate Income Tax is a specific type of tax levied on the profits of corporations, with its own annual return form and filing requirements. - chunk-93d2389cdb74257e90201dccbc3f6539<SEP>chunk-bdfd18ae478b23604f1318623e8e9508 - /app/server/storage/knowledge/财务知识库/远光软件高新技术企业税收优惠政策汇总.pdf<SEP>/app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf - 1779466433 + Corporate income tax is a tax levied on the profits of enterprises, and certain expenses can be deducted before its calculation.<SEP>Corporate Income Tax is a specific type of tax levied on the profits of corporations, with its own annual return form and filing requirements.<SEP>Corporate Income Tax is a tax on corporate profits, with a standard rate of 25% and a preferential rate of 15% for high-tech enterprises. + chunk-93d2389cdb74257e90201dccbc3f6539<SEP>chunk-bdfd18ae478b23604f1318623e8e9508<SEP>chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件高新技术企业税收优惠政策汇总.pdf<SEP>/app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf<SEP>/app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546632 @@ -5705,10 +5577,10 @@ The department head also serves as the primary approver for travel‑related act Yuan Guang Software Co., Ltd. organization - Yuan Guang Software Co., Ltd. is the company that created this procurement management document. - chunk-96ab661ad24e0cb4c468128a58a76b6d - /app/server/storage/knowledge/制度政策/远光软件公司采购管理办法.xlsx - 1779465962 + Yuan Guang Software Co., Ltd. is the company that created this procurement management document.<SEP>Yuan Guang Software Co., Ltd. is the company that created the Financial Basics Manual. + chunk-96ab661ad24e0cb4c468128a58a76b6d<SEP>chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/制度政策/远光软件公司采购管理办法.xlsx<SEP>/app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546631 @@ -12076,4226 +11948,4496 @@ From a compliance standpoint, the invoice is the preferred type that companies s 1779467740 + + Accounting Elements + concept + Accounting Elements include assets, liabilities, owner's equity, revenue, expenses, and profit, which form the fundamental components of accounting. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546631 + + + + Assets + concept + Assets represent resources owned by the company with economic value. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546631 + + + + Liabilities + concept + Liabilities represent obligations or debts owed to others. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546631 + + + + Owner's Equity + concept + Owner's Equity represents the residual interest in the assets after deducting liabilities. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546631 + + + + Revenue + concept + Revenue represents income generated from business activities. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546631 + + + + Expenses + concept + Expenses represent costs incurred in the process of generating revenue. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546631 + + + + Profit + concept + Profit represents the financial gain from business operations. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546631 + + + + Accounting Equation + concept + The Accounting Equation states that Assets equals Liabilities plus Owner's Equity. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546631 + + + + Common Accounting Items + concept + Common Accounting Items refer to standardized categories used to record financial transactions. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546631 + + + + Assets Category + concept + Assets Category is a classification of accounting items representing resources owned by the company. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546631 + + + + Liabilities Category + concept + Liabilities Category is a classification of accounting items representing obligations owed by the company. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546631 + + + + Income And Expense Category + concept + Income and Expense Category is a classification for items related to profitability and operational costs. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546631 + + + + Cash + concept + Cash refers to money held by the company in physical form. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546631 + + + + Bank Deposits + concept + Bank Deposits refer to funds held in bank accounts. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546631 + + + + Accounts Receivable + concept + Accounts Receivable represents amounts owed to the company for sales of goods or services. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546631 + + + + Fixed Assets + concept + Fixed Assets are tangible assets with a useful life exceeding one year. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546631 + + + + Accounts Payable + concept + Accounts Payable represents amounts owed by the company for purchases of goods or services. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546631 + + + + Taxes Payable + concept + Taxes Payable represents various tax obligations owed by the company. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546631 + + + + Employee Compensation Payable + concept + Employee Compensation Payable represents wages and benefits owed to employees. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546631 + + + + Main Business Revenue + concept + Main Business Revenue represents income from primary business operations. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546631 + + + + Management Expenses + concept + Management Expenses represent costs incurred for managing business operations. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546631 + + + + Sales Expenses + concept + Sales Expenses represent costs incurred for selling products. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546631 + + + + Tax Fundamentals + concept + Tax Fundamentals cover the basic knowledge of taxation systems and requirements. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546631 + + + + Major Tax Types + concept + Major Tax Types refer to the main categories of taxes applicable to businesses. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546632 + + + + Value Added Tax + concept + Value Added Tax is a consumption tax imposed on the value added in each stage of production or distribution, with software services taxed at 6% and software product sales at 13%. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546632 + + + + Individual Income Tax + concept + Individual Income Tax is a progressive tax ranging from 3% to 45%, withheld and remitted by the company. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546632 + + + + Stamp Duty + concept + Stamp Duty is a tax levied on taxable documents related to economic activities. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546632 + + + + Software Services Tax Rate 6% + data + Software services are subject to a 6% value added tax rate for general taxpayer companies. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546632 + + + + Software Product Sales Tax Rate 13% + data + Software product sales are subject to a 13% value added tax rate for general taxpayer companies. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546632 + + + + Corporate Income Tax Rate 25% + data + The standard corporate income tax rate is 25% for enterprises. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546632 + + + + High-Tech Enterprise Preferential Tax Rate 15% + data + High-tech enterprises enjoy a preferential corporate income tax rate of 15%. + chunk-6fdc554482754c7c662adc7804d3cf0b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546632 + + + + 所有者权益 + concept + 所有者权益represents owner's equity in accounting, indicating the residual interest in assets after deducting liabilities. + chunk-f894acfbb6c681d00f75cf9c486d491b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546632 + + + + 常用会计科目 + concept + 常用会计科目refers to common accounting items, which are standardized categories used in financial accounting. + chunk-f894acfbb6c681d00f75cf9c486d491b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546632 + + - 1.0 - 远光软件股份有限公司is the issuer of the expense reimbursement regulations, with Chapter 1 General Provisions establishing the foundational framework. - organizational hierarchy,regulation issuer - chunk-aa5435156b829944c173fa1d2d7a93d4 - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012088 - + 1.0 + 远光软件股份有限公司is the issuer of the expense reimbursement regulations, with Chapter 1 General Provisions establishing the foundational framework. + organizational hierarchy,regulation issuer + chunk-aa5435156b829944c173fa1d2d7a93d4 + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012088 + - 1.0 - 远光软件股份有限公司established the Planning and Finance Department to handle financial management and expense-related responsibilities. - financial authority,organizational structure - chunk-aa5435156b829944c173fa1d2d7a93d4 - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012076 - + 1.0 + 远光软件股份有限公司established the Planning and Finance Department to handle financial management and expense-related responsibilities. + financial authority,organizational structure + chunk-aa5435156b829944c173fa1d2d7a93d4 + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012076 + - 1.0 - Yuan Guang Software Co., Ltd. has implemented changes in reimbursement standards as part of its internal policy adjustments. - company governance,policy adjustment - chunk-18d968b78afe916b419c1b5973421ebe - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012084 - + 1.0 + Yuan Guang Software Co., Ltd. has implemented changes in reimbursement standards as part of its internal policy adjustments. + company governance,policy adjustment + chunk-18d968b78afe916b419c1b5973421ebe + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012084 + - 1.0 - 远光软件股份有限公司issued the Company Expenditure Management Measures (2024) to regulate company expenditures. - document issuance,policy implementation - chunk-dd87aa5bc62cc9587ecb4c26d35a5263 - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012085 - + 1.0 + 远光软件股份有限公司issued the Company Expenditure Management Measures (2024) to regulate company expenditures. + document issuance,policy implementation + chunk-dd87aa5bc62cc9587ecb4c26d35a5263 + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012085 + - 1.0 - 远光软件股份有限公司assigned document number远光制度〔2024〕14号to the expenditure management measures. - document numbering,regulatory framework - chunk-dd87aa5bc62cc9587ecb4c26d35a5263 - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012086 - + 1.0 + 远光软件股份有限公司assigned document number远光制度〔2024〕14号to the expenditure management measures. + document numbering,regulatory framework + chunk-dd87aa5bc62cc9587ecb4c26d35a5263 + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012086 + - 1.0 - 远光软件股份有限公司owns and publishes the Excel workbook containing accounting subject guidelines. - corporate publication,document ownership - chunk-31ff57cf79d009c378478f065eda9d4d - /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx - 1779441742 - + 1.0 + 远光软件股份有限公司owns and publishes the Excel workbook containing accounting subject guidelines. + corporate publication,document ownership + chunk-31ff57cf79d009c378478f065eda9d4d + /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx + 1779441742 + - 1.0 - 远光软件股份有限公司owns and uses the Excel workbook远光软件会计科目使用说明.xlsx for accounting subject management. - company resource,document ownership - chunk-e726f44fb0287c5192cf61b350f18abb - /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx - 1779441742 - + 1.0 + 远光软件股份有限公司owns and uses the Excel workbook远光软件会计科目使用说明.xlsx for accounting subject management. + company resource,document ownership + chunk-e726f44fb0287c5192cf61b350f18abb + /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx + 1779441742 + - 1.0 - 2221应交税费is used by远光软件股份有限公司to record tax liabilities. - liability recording,subject usage - chunk-e726f44fb0287c5192cf61b350f18abb - /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx - 1779441743 - + 1.0 + 2221应交税费is used by远光软件股份有限公司to record tax liabilities. + liability recording,subject usage + chunk-e726f44fb0287c5192cf61b350f18abb + /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx + 1779441743 + - 1.0 - 2211应付职工薪酬is used by远光软件股份有限公司to record employee compensation liabilities. - liability recording,subject usage - chunk-e726f44fb0287c5192cf61b350f18abb - /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx - 1779441743 - + 1.0 + 2211应付职工薪酬is used by远光软件股份有限公司to record employee compensation liabilities. + liability recording,subject usage + chunk-e726f44fb0287c5192cf61b350f18abb + /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx + 1779441743 + - 1.0 - 6001主营业务收入is used by远光软件股份有限公司to record main business revenue. - income recording,subject usage - chunk-e726f44fb0287c5192cf61b350f18abb - /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx - 1779441743 - + 1.0 + 6001主营业务收入is used by远光软件股份有限公司to record main business revenue. + income recording,subject usage + chunk-e726f44fb0287c5192cf61b350f18abb + /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx + 1779441743 + - 1.0 - 6401主营业务成本is used by远光软件股份有限公司to record main business costs. - expense recording,subject usage - chunk-e726f44fb0287c5192cf61b350f18abb - /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx - 1779441744 - + 1.0 + 6401主营业务成本is used by远光软件股份有限公司to record main business costs. + expense recording,subject usage + chunk-e726f44fb0287c5192cf61b350f18abb + /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx + 1779441744 + - 1.0 - 1001库存现金is used by远光软件股份有限公司to record cash on hand. - asset recording,subject usage - chunk-e726f44fb0287c5192cf61b350f18abb - /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx - 1779441744 - + 1.0 + 1001库存现金is used by远光软件股份有限公司to record cash on hand. + asset recording,subject usage + chunk-e726f44fb0287c5192cf61b350f18abb + /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx + 1779441744 + - 1.0 - 1002银行存款is used by远光软件股份有限公司to record bank deposits. - asset recording,subject usage - chunk-e726f44fb0287c5192cf61b350f18abb - /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx - 1779441744 - + 1.0 + 1002银行存款is used by远光软件股份有限公司to record bank deposits. + asset recording,subject usage + chunk-e726f44fb0287c5192cf61b350f18abb + /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx + 1779441744 + - 1.0 - 1122应收账款is used by远光软件股份有限公司to record accounts receivable. - asset recording,subject usage - chunk-e726f44fb0287c5192cf61b350f18abb - /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx - 1779441745 - + 1.0 + 1122应收账款is used by远光软件股份有限公司to record accounts receivable. + asset recording,subject usage + chunk-e726f44fb0287c5192cf61b350f18abb + /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx + 1779441745 + - 1.0 - 1221其他应收款is used by远光软件股份有限公司to record other receivables. - asset recording,subject usage - chunk-e726f44fb0287c5192cf61b350f18abb - /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx - 1779441745 - - - - 1.0 - 远光软件股份有限公司authored the财务基础知识手册as an internal training document. - authorship,corporate documentation - chunk-78edb0c8ccc8238159196ecaeeb08d43 - /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx - 1779441770 - + 1.0 + 1221其他应收款is used by远光软件股份有限公司to record other receivables. + asset recording,subject usage + chunk-e726f44fb0287c5192cf61b350f18abb + /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx + 1779441745 + - 1.0 - 远光软件股份有限公司published the Financial Term Explanation Manual as an official company document. - corporate authorship,publication - chunk-2ee7e2a66cb544bdfe1b09e133863ad1 - /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx - 1779441775 - + 1.0 + 远光软件股份有限公司published the Financial Term Explanation Manual as an official company document. + corporate authorship,publication + chunk-2ee7e2a66cb544bdfe1b09e133863ad1 + /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx + 1779441775 + - 1.0 - 远光软件股份有限公司adopts the straight-line method for calculating fixed asset depreciation. - accounting method,depreciation calculation - chunk-2ee7e2a66cb544bdfe1b09e133863ad1 - /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx - 1779441776 - + 1.0 + 远光软件股份有限公司adopts the straight-line method for calculating fixed asset depreciation. + accounting method,depreciation calculation + chunk-2ee7e2a66cb544bdfe1b09e133863ad1 + /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx + 1779441776 + - 1.0 - 第二条establishes that the specifications apply to远光软件股份有限公司and all its subsidiaries - organizational application,regulatory scope - chunk-6c549250b13b7728acb37eb6082bc178 - /app/server/storage/knowledge/制度政策/远光软件公司内部控制基本规范.pdf - 1779465701 - + 1.0 + 第二条establishes that the specifications apply to远光软件股份有限公司and all its subsidiaries + organizational application,regulatory scope + chunk-6c549250b13b7728acb37eb6082bc178 + /app/server/storage/knowledge/制度政策/远光软件公司内部控制基本规范.pdf + 1779465701 + - 1.0 - 远光软件股份有限公司implements internal control as a governance framework for its operations. - operational framework,organizational governance - chunk-6c549250b13b7728acb37eb6082bc178 - /app/server/storage/knowledge/制度政策/远光软件公司内部控制基本规范.pdf - 1779465701 - + 1.0 + 远光软件股份有限公司implements internal control as a governance framework for its operations. + operational framework,organizational governance + chunk-6c549250b13b7728acb37eb6082bc178 + /app/server/storage/knowledge/制度政策/远光软件公司内部控制基本规范.pdf + 1779465701 + - 1.0 - 远光软件股份有限公司developed these internal control standards based on中华人民共和国公司法. - legal compliance,regulatory foundation - chunk-d1529b915580d4271d51c1cc6781f3b4 - /app/server/storage/knowledge/制度政策/远光软件公司内部控制基本规范.pdf - 1779465702 - + 1.0 + 远光软件股份有限公司developed these internal control standards based on中华人民共和国公司法. + legal compliance,regulatory foundation + chunk-d1529b915580d4271d51c1cc6781f3b4 + /app/server/storage/knowledge/制度政策/远光软件公司内部控制基本规范.pdf + 1779465702 + - 1.0 - 远光软件股份有限公司developed these internal control standards in compliance with企业内部控制基本规范. - regulatory compliance,standard foundation - chunk-d1529b915580d4271d51c1cc6781f3b4 - /app/server/storage/knowledge/制度政策/远光软件公司内部控制基本规范.pdf - 1779465702 - + 1.0 + 远光软件股份有限公司developed these internal control standards in compliance with企业内部控制基本规范. + regulatory compliance,standard foundation + chunk-d1529b915580d4271d51c1cc6781f3b4 + /app/server/storage/knowledge/制度政策/远光软件公司内部控制基本规范.pdf + 1779465702 + - 1.0 - 远光软件股份有限公司authored and established the内部控制基本规范for internal control implementation. - document creation,standards establishment - chunk-d1529b915580d4271d51c1cc6781f3b4 - /app/server/storage/knowledge/制度政策/远光软件公司内部控制基本规范.pdf - 1779465702 - + 1.0 + 远光软件股份有限公司authored and established the内部控制基本规范for internal control implementation. + document creation,standards establishment + chunk-d1529b915580d4271d51c1cc6781f3b4 + /app/server/storage/knowledge/制度政策/远光软件公司内部控制基本规范.pdf + 1779465702 + - 2.0 - 远光软件股份有限公司applies these internal control standards to its headquarters and all subsidiaries.<SEP>远光软件股份有限公司has branches and subsidiaries (分、子公司) to which the invoice management standards apply. - corporate governance,organizational scope,subsidiary governance - chunk-d1529b915580d4271d51c1cc6781f3b4<SEP>chunk-65235351abce326b8aca831b128a96c6 - /app/server/storage/knowledge/制度政策/远光软件公司内部控制基本规范.pdf<SEP>/app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466312 - + 2.0 + 远光软件股份有限公司applies these internal control standards to its headquarters and all subsidiaries.<SEP>远光软件股份有限公司has branches and subsidiaries (分、子公司) to which the invoice management standards apply. + corporate governance,organizational scope,subsidiary governance + chunk-d1529b915580d4271d51c1cc6781f3b4<SEP>chunk-65235351abce326b8aca831b128a96c6 + /app/server/storage/knowledge/制度政策/远光软件公司内部控制基本规范.pdf<SEP>/app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466312 + - 1.0 - 远光软件股份有限公司established the contract management system to regulate contract operations. - corporate governance,system establishment - chunk-1f813062c109d781d9d684a4d23bfe1e - /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx - 1779465763 - + 1.0 + 远光软件股份有限公司established the contract management system to regulate contract operations. + corporate governance,system establishment + chunk-1f813062c109d781d9d684a4d23bfe1e + /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx + 1779465763 + - 6.0 - 远光软件股份有限公司established财务部as its functional department for financial management under the leadership of财务总监.<SEP>远光软件股份有限公司establishes and oversees the Finance Department for all financial management operations.<SEP>远光软件股份有限公司has a财务部responsible for handling invoice certification and tax-related matters.<SEP>远光软件股份有限公司prepares the budget execution analysis report through the财务部department.<SEP>远光软件股份有限公司has a dedicated财务部that manages all company financial functions.<SEP>远光软件股份有限公司has a财务部that handles accounting, contract review for payment terms, and payroll tax deductions. - administrative oversight,financial management,financial oversight,internal process,leadership,organizational structure,report preparation - chunk-bb483fb199b8a72b369d87b3fa319ac3<SEP>chunk-9734bc0dd5225675ba6907f874a807ce<SEP>chunk-af51160a1e2350e227249d2eaff8df40<SEP>chunk-b844601174a058e8fbad0ea235898bd4<SEP>chunk-f0242dd79cc2c64d1e111d0380acfa6c<SEP>chunk-6175768b05adf2e7229c16f13ee7cffd - /app/server/storage/knowledge/制度政策/远光软件公司财务管理制度总则.docx<SEP>/app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf<SEP>/app/server/storage/knowledge/预算管理/远光软件预算执行分析报告模板.docx<SEP>/app/server/storage/knowledge/培训资料/远光软件新员工财务培训课件.pdf<SEP>/app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf - 1779467702 - + 6.0 + 远光软件股份有限公司established财务部as its functional department for financial management under the leadership of财务总监.<SEP>远光软件股份有限公司establishes and oversees the Finance Department for all financial management operations.<SEP>远光软件股份有限公司has a财务部responsible for handling invoice certification and tax-related matters.<SEP>远光软件股份有限公司prepares the budget execution analysis report through the财务部department.<SEP>远光软件股份有限公司has a dedicated财务部that manages all company financial functions.<SEP>远光软件股份有限公司has a财务部that handles accounting, contract review for payment terms, and payroll tax deductions. + administrative oversight,financial management,financial oversight,internal process,leadership,organizational structure,report preparation + chunk-bb483fb199b8a72b369d87b3fa319ac3<SEP>chunk-9734bc0dd5225675ba6907f874a807ce<SEP>chunk-af51160a1e2350e227249d2eaff8df40<SEP>chunk-b844601174a058e8fbad0ea235898bd4<SEP>chunk-f0242dd79cc2c64d1e111d0380acfa6c<SEP>chunk-6175768b05adf2e7229c16f13ee7cffd + /app/server/storage/knowledge/制度政策/远光软件公司财务管理制度总则.docx<SEP>/app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf<SEP>/app/server/storage/knowledge/预算管理/远光软件预算执行分析报告模板.docx<SEP>/app/server/storage/knowledge/培训资料/远光软件新员工财务培训课件.pdf<SEP>/app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf + 1779467702 + - 1.0 - 远光软件股份有限公司formulated财务管理制度总则to regulate financial management work and establish internal controls. - institutional establishment,regulatory framework - chunk-bb483fb199b8a72b369d87b3fa319ac3 - /app/server/storage/knowledge/制度政策/远光软件公司财务管理制度总则.docx - 1779465826 - + 1.0 + 远光软件股份有限公司formulated财务管理制度总则to regulate financial management work and establish internal controls. + institutional establishment,regulatory framework + chunk-bb483fb199b8a72b369d87b3fa319ac3 + /app/server/storage/knowledge/制度政策/远光软件公司财务管理制度总则.docx + 1779465826 + - 1.0 - 远光软件股份有限公司established the asset management system to regulate asset management practices. - corporate governance,policy establishment - chunk-4e95fc3e38b2bf65fcb3f6f0664fd9df - /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf - 1779465896 - + 1.0 + 远光软件股份有限公司established the asset management system to regulate asset management practices. + corporate governance,policy establishment + chunk-4e95fc3e38b2bf65fcb3f6f0664fd9df + /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf + 1779465896 + - 1.0 - 远光软件股份有限公司manages无形资产including patent rights, trademark rights, copyright, land use rights, and software usage rights. - asset management,organizational governance - chunk-4e95fc3e38b2bf65fcb3f6f0664fd9df - /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf - 1779465897 - + 1.0 + 远光软件股份有限公司manages无形资产including patent rights, trademark rights, copyright, land use rights, and software usage rights. + asset management,organizational governance + chunk-4e95fc3e38b2bf65fcb3f6f0664fd9df + /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf + 1779465897 + - 1.0 - 远光软件股份有限公司establishes the审批流程that governs how travel reimbursement requests are processed through multiple approval stages. - company policy,procedural framework - chunk-85ebe3a7090c0f5408b34e92c2384b1a - /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf - 1779466042 - + 1.0 + 远光软件股份有限公司establishes the审批流程that governs how travel reimbursement requests are processed through multiple approval stages. + company policy,procedural framework + chunk-85ebe3a7090c0f5408b34e92c2384b1a + /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf + 1779466042 + - 1.0 - 远光软件股份有限公司established the差旅费标准速查表to regulate employee travel expenses. - company document,policy establishment - chunk-f9e0518ef691fb9defdc3af6e1585a0e - /app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx - 1779466161 - + 1.0 + 远光软件股份有限公司established the差旅费标准速查表to regulate employee travel expenses. + company document,policy establishment + chunk-f9e0518ef691fb9defdc3af6e1585a0e + /app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx + 1779466161 + - 2.0 - 远光软件股份有限公司established and uses the invoice auditing standards document for verifying compliance.<SEP>远光软件股份有限公司establishes and enforces the invoice review standards for all company transactions. - company standards,compliance requirement,invoice management - chunk-f7ca8767b8a4ddde879a599a598c044f<SEP>chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 - /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx - 1779466261 - + 2.0 + 远光软件股份有限公司established and uses the invoice auditing standards document for verifying compliance.<SEP>远光软件股份有限公司establishes and enforces the invoice review standards for all company transactions. + company standards,compliance requirement,invoice management + chunk-f7ca8767b8a4ddde879a599a598c044f<SEP>chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 + /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx + 1779466261 + - 1.0 - 远光软件股份有限公司established the invoice management standards to regulate the company's invoice management practices. - governance,policy establishment - chunk-65235351abce326b8aca831b128a96c6 - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466311 - + 1.0 + 远光软件股份有限公司established the invoice management standards to regulate the company's invoice management practices. + governance,policy establishment + chunk-65235351abce326b8aca831b128a96c6 + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466311 + - 1.0 - 公司财务部, as a department of远光软件股份有限公司, is uniformly responsible for the company's invoice management. - management authority,organizational responsibility - chunk-65235351abce326b8aca831b128a96c6 - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466311 - + 1.0 + 公司财务部, as a department of远光软件股份有限公司, is uniformly responsible for the company's invoice management. + management authority,organizational responsibility + chunk-65235351abce326b8aca831b128a96c6 + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466311 + - 1.0 - 公司员工, as employees of远光软件股份有限公司, must obtain compliant invoices for business expenses. - employee obligation,expense management - chunk-65235351abce326b8aca831b128a96c6 - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466311 - + 1.0 + 公司员工, as employees of远光软件股份有限公司, must obtain compliant invoices for business expenses. + employee obligation,expense management + chunk-65235351abce326b8aca831b128a96c6 + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466311 + - 1.0 - The invoice management specification applies to the company and its branches and subsidiaries. - management applicability,organizational scope - chunk-8c48a48e8ce0bfd52d732de60fec82ce - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466312 - + 1.0 + The invoice management specification applies to the company and its branches and subsidiaries. + management applicability,organizational scope + chunk-8c48a48e8ce0bfd52d732de60fec82ce + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466312 + - 1.0 - 远光软件股份有限公司created the invoice management specification based on national regulations. - document creation,organizational governance - chunk-8c48a48e8ce0bfd52d732de60fec82ce - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466312 - + 1.0 + 远光软件股份有限公司created the invoice management specification based on national regulations. + document creation,organizational governance + chunk-8c48a48e8ce0bfd52d732de60fec82ce + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466312 + - 2.0 - 远光软件股份有限公司uses and requires special VAT invoices for business expenses when the other party is a general taxpayer.<SEP>远光软件股份有限公司是增值税专用发票上注明的购买方名称。 - invoice type,tax deduction,发票信息,购买方 - chunk-12b08b984a30d7e156cf75ac4c79ed0a<SEP>chunk-af51160a1e2350e227249d2eaff8df40 - /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf - 1779466341 - + 2.0 + 远光软件股份有限公司uses and requires special VAT invoices for business expenses when the other party is a general taxpayer.<SEP>远光软件股份有限公司是增值税专用发票上注明的购买方名称。 + invoice type,tax deduction,发票信息,购买方 + chunk-12b08b984a30d7e156cf75ac4c79ed0a<SEP>chunk-af51160a1e2350e227249d2eaff8df40 + /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf + 1779466341 + - 1.0 - 远光软件股份有限公司submits red invoice applications to税务机关for review and approval. - red invoice processing,regulatory compliance - chunk-af51160a1e2350e227249d2eaff8df40 - /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf - 1779466342 - + 1.0 + 远光软件股份有限公司submits red invoice applications to税务机关for review and approval. + red invoice processing,regulatory compliance + chunk-af51160a1e2350e227249d2eaff8df40 + /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf + 1779466342 + - 1.0 - 远光软件股份有限公司requires the completion of开具红字增值税发票信息表when issuing red letter invoices for returns or discounts. - form requirement,red invoice procedure - chunk-af51160a1e2350e227249d2eaff8df40 - /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf - 1779466342 - + 1.0 + 远光软件股份有限公司requires the completion of开具红字增值税发票信息表when issuing red letter invoices for returns or discounts. + form requirement,red invoice procedure + chunk-af51160a1e2350e227249d2eaff8df40 + /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf + 1779466342 + - 1.0 - 远光软件股份有限公司uses发票管理台账for regular inspection to ensure standardized invoice usage. - compliance monitoring,invoice management - chunk-af51160a1e2350e227249d2eaff8df40 - /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf - 1779466342 - + 1.0 + 远光软件股份有限公司uses发票管理台账for regular inspection to ensure standardized invoice usage. + compliance monitoring,invoice management + chunk-af51160a1e2350e227249d2eaff8df40 + /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf + 1779466342 + - 1.0 - 远光软件股份有限公司is registered with the tax identification number 91440400192544XXXX. - legal identification,tax registration - chunk-af51160a1e2350e227249d2eaff8df40 - /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf - 1779466342 - + 1.0 + 远光软件股份有限公司is registered with the tax identification number 91440400192544XXXX. + legal identification,tax registration + chunk-af51160a1e2350e227249d2eaff8df40 + /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf + 1779466342 + - 1.0 - 远光软件股份有限公司formulated the电子发票管理办法to regulate the management and use of electronic invoices. - company governance,policy formulation - chunk-4f26391db1f914c1dbf43241f51b8d4e - /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466407 - + 1.0 + 远光软件股份有限公司formulated the电子发票管理办法to regulate the management and use of electronic invoices. + company governance,policy formulation + chunk-4f26391db1f914c1dbf43241f51b8d4e + /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466407 + - 1.0 - 远光软件股份有限公司bases its electronic invoice management on regulations from国家税务总局. - national standards,regulatory compliance - chunk-4f26391db1f914c1dbf43241f51b8d4e - /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466407 - + 1.0 + 远光软件股份有限公司bases its electronic invoice management on regulations from国家税务总局. + national standards,regulatory compliance + chunk-4f26391db1f914c1dbf43241f51b8d4e + /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466407 + - 1.0 - 远光软件股份有限公司established the Tax Management System to regulate its tax-related activities. - establishment,governance - chunk-f61c91e28e8d0f773f83e3daf161ab1c - /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx - 1779466504 - + 1.0 + 远光软件股份有限公司established the Tax Management System to regulate its tax-related activities. + establishment,governance + chunk-f61c91e28e8d0f773f83e3daf161ab1c + /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx + 1779466504 + - 1.0 - 公司serves as the shortened formal reference to远光软件股份有限公司throughout the document. - naming convention,organizational reference - chunk-f61c91e28e8d0f773f83e3daf161ab1c - /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx - 1779466505 - + 1.0 + 公司serves as the shortened formal reference to远光软件股份有限公司throughout the document. + naming convention,organizational reference + chunk-f61c91e28e8d0f773f83e3daf161ab1c + /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx + 1779466505 + - 1.0 - 远光软件股份有限公司created and owns the Excel workbook containing the R&D expense additional deduction management method. - corporate governance,document ownership - chunk-24de3b6d9d2fc0445c2c31da82a60be1 - /app/server/storage/knowledge/税务合规/远光软件研发费用加计扣除管理办法.xlsx - 1779466538 - + 1.0 + 远光软件股份有限公司created and owns the Excel workbook containing the R&D expense additional deduction management method. + corporate governance,document ownership + chunk-24de3b6d9d2fc0445c2c31da82a60be1 + /app/server/storage/knowledge/税务合规/远光软件研发费用加计扣除管理办法.xlsx + 1779466538 + - 1.0 - 远光软件股份有限公司制定了研发费用加计扣除管理办法,用于规范公司的研发费用管理。 - 制定,管理 - chunk-e650a577ed84565fd87ee6422b4b82a2 - /app/server/storage/knowledge/税务合规/远光软件研发费用加计扣除管理办法.xlsx - 1779466539 - + 1.0 + 远光软件股份有限公司制定了研发费用加计扣除管理办法,用于规范公司的研发费用管理。 + 制定,管理 + chunk-e650a577ed84565fd87ee6422b4b82a2 + /app/server/storage/knowledge/税务合规/远光软件研发费用加计扣除管理办法.xlsx + 1779466539 + - 1.0 - 远光软件股份有限公司tracks营业收入as a key performance metric against budget targets. - budget tracking,financial performance - chunk-b844601174a058e8fbad0ea235898bd4 - /app/server/storage/knowledge/预算管理/远光软件预算执行分析报告模板.docx - 1779467060 - + 1.0 + 远光软件股份有限公司tracks营业收入as a key performance metric against budget targets. + budget tracking,financial performance + chunk-b844601174a058e8fbad0ea235898bd4 + /app/server/storage/knowledge/预算管理/远光软件预算执行分析报告模板.docx + 1779467060 + - 1.0 - 远光软件股份有限公司tracks费用支出as an expense metric against budget allocations. - expense control,financial performance - chunk-b844601174a058e8fbad0ea235898bd4 - /app/server/storage/knowledge/预算管理/远光软件预算执行分析报告模板.docx - 1779467060 - + 1.0 + 远光软件股份有限公司tracks费用支出as an expense metric against budget allocations. + expense control,financial performance + chunk-b844601174a058e8fbad0ea235898bd4 + /app/server/storage/knowledge/预算管理/远光软件预算执行分析报告模板.docx + 1779467060 + - 1.0 - 远光软件股份有限公司monitors资本支出against budgeted capital expenditure. - budget compliance,investment tracking - chunk-b844601174a058e8fbad0ea235898bd4 - /app/server/storage/knowledge/预算管理/远光软件预算执行分析报告模板.docx - 1779467077 - + 1.0 + 远光软件股份有限公司monitors资本支出against budgeted capital expenditure. + budget compliance,investment tracking + chunk-b844601174a058e8fbad0ea235898bd4 + /app/server/storage/knowledge/预算管理/远光软件预算执行分析报告模板.docx + 1779467077 + - 1.0 - 远光软件股份有限公司establishes the financial shared service center to promote financial management transformation. - company establishment,organizational structure - chunk-3b77f7e8beca3e7d537d0623f97473ee - /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx - 1779467178 - + 1.0 + 远光软件股份有限公司establishes the financial shared service center to promote financial management transformation. + company establishment,organizational structure + chunk-3b77f7e8beca3e7d537d0623f97473ee + /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx + 1779467178 + - 1.0 - 远光软件股份有限公司establishes and implements the financial shared service center operational management measures. - company policy,organizational governance - chunk-3b77f7e8beca3e7d537d0623f97473ee - /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx - 1779467178 - + 1.0 + 远光软件股份有限公司establishes and implements the financial shared service center operational management measures. + company policy,organizational governance + chunk-3b77f7e8beca3e7d537d0623f97473ee + /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx + 1779467178 + - 1.0 - 远光软件股份有限公司operates and provides the Financial Shared Services Platform for internal financial operations. - company operation,platform provision - chunk-e9620692094a0b2c6a4059a9d54b156a - /app/server/storage/knowledge/财务共享/远光软件财务共享服务操作手册.pdf - 1779467212 - + 1.0 + 远光软件股份有限公司operates and provides the Financial Shared Services Platform for internal financial operations. + company operation,platform provision + chunk-e9620692094a0b2c6a4059a9d54b156a + /app/server/storage/knowledge/财务共享/远光软件财务共享服务操作手册.pdf + 1779467212 + - 1.0 - 远光软件股份有限公司has established the reimbursement process as a company policy for employees to follow. - company policy,operational framework - chunk-962e1165f2750bf5d5d1e2cfd62dc1d8 - /app/server/storage/knowledge/培训资料/远光软件报销流程培训手册.pdf - 1779467250 - + 1.0 + 远光软件股份有限公司has established the reimbursement process as a company policy for employees to follow. + company policy,operational framework + chunk-962e1165f2750bf5d5d1e2cfd62dc1d8 + /app/server/storage/knowledge/培训资料/远光软件报销流程培训手册.pdf + 1779467250 + - 1.0 - 远光软件股份有限公司created the培训大纲for new employee financial training. - organizational knowledge,training provision - chunk-f0242dd79cc2c64d1e111d0380acfa6c - /app/server/storage/knowledge/培训资料/远光软件新员工财务培训课件.pdf - 1779467263 - + 1.0 + 远光软件股份有限公司created the培训大纲for new employee financial training. + organizational knowledge,training provision + chunk-f0242dd79cc2c64d1e111d0380acfa6c + /app/server/storage/knowledge/培训资料/远光软件新员工财务培训课件.pdf + 1779467263 + - 1.0 - 远光软件股份有限公司conducts annual financial training for the year 2024. - annual training,temporal context - chunk-f0242dd79cc2c64d1e111d0380acfa6c - /app/server/storage/knowledge/培训资料/远光软件新员工财务培训课件.pdf - 1779467263 - + 1.0 + 远光软件股份有限公司conducts annual financial training for the year 2024. + annual training,temporal context + chunk-f0242dd79cc2c64d1e111d0380acfa6c + /app/server/storage/knowledge/培训资料/远光软件新员工财务培训课件.pdf + 1779467263 + - 1.0 - 远光软件股份有限公司organizes the财务制度总则培训as a mandatory onboarding course for new employees. - employee development,organizational training - chunk-6df7635e39ab9c079752505fca7213be - /app/server/storage/knowledge/培训资料/远光软件财务培训课程安排.xlsx - 1779467342 - + 1.0 + 远光软件股份有限公司organizes the财务制度总则培训as a mandatory onboarding course for new employees. + employee development,organizational training + chunk-6df7635e39ab9c079752505fca7213be + /app/server/storage/knowledge/培训资料/远光软件财务培训课程安排.xlsx + 1779467342 + - 1.0 - 远光软件股份有限公司organizes the费用报销实操培训to train department reimbursement officers on expense procedures. - organizational training,procedural guidance - chunk-6df7635e39ab9c079752505fca7213be - /app/server/storage/knowledge/培训资料/远光软件财务培训课程安排.xlsx - 1779467342 - + 1.0 + 远光软件股份有限公司organizes the费用报销实操培训to train department reimbursement officers on expense procedures. + organizational training,procedural guidance + chunk-6df7635e39ab9c079752505fca7213be + /app/server/storage/knowledge/培训资料/远光软件财务培训课程安排.xlsx + 1779467342 + - 1.0 - 远光软件股份有限公司has an资产管理部门responsible for asset retirement approval and inter-departmental transfers. - asset oversight,organizational structure - chunk-6175768b05adf2e7229c16f13ee7cffd - /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf - 1779467718 - + 1.0 + 远光软件股份有限公司has an资产管理部门responsible for asset retirement approval and inter-departmental transfers. + asset oversight,organizational structure + chunk-6175768b05adf2e7229c16f13ee7cffd + /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf + 1779467718 + - 1.0 - 远光软件股份有限公司publishes the financial reimbursement FAQ document for internal use. - corporate documentation,policy publication - chunk-cfac1ddf5942f8fe2d5a296380818faf - /app/server/storage/knowledge/常见问答/远光软件财务报销常见问题解答.docx - 1779467725 - + 1.0 + 远光软件股份有限公司publishes the financial reimbursement FAQ document for internal use. + corporate documentation,policy publication + chunk-cfac1ddf5942f8fe2d5a296380818faf + /app/server/storage/knowledge/常见问答/远光软件财务报销常见问题解答.docx + 1779467725 + - 1.0 - 远光软件股份有限公司operates the OA system for processing electronic invoices. - automated workflow,corporate system - chunk-cfac1ddf5942f8fe2d5a296380818faf - /app/server/storage/knowledge/常见问答/远光软件财务报销常见问题解答.docx - 1779467726 - + 1.0 + 远光软件股份有限公司operates the OA system for processing electronic invoices. + automated workflow,corporate system + chunk-cfac1ddf5942f8fe2d5a296380818faf + /app/server/storage/knowledge/常见问答/远光软件财务报销常见问题解答.docx + 1779467726 + - 1.0 - Article 3 Management Principles provides the foundational principles for the entire expense reimbursement system. - chapter article relationship,regulatory foundation - chunk-aa5435156b829944c173fa1d2d7a93d4 - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012076 - + 1.0 + Article 3 Management Principles provides the foundational principles for the entire expense reimbursement system. + chapter article relationship,regulatory foundation + chunk-aa5435156b829944c173fa1d2d7a93d4 + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012076 + - 1.0 - 第一章总则establishes the purpose and definition of electronic invoices. - concept establishment,definition scope - chunk-4f26391db1f914c1dbf43241f51b8d4e - /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466394 - + 1.0 + 第一章总则establishes the purpose and definition of electronic invoices. + concept establishment,definition scope + chunk-4f26391db1f914c1dbf43241f51b8d4e + /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466394 + - 1.0 - The designated management department determines expenditure scope, standards, methods, and management processes in accordance with company financial, procurement, and human resources policies. - department responsibility,regulatory compliance - chunk-aa5435156b829944c173fa1d2d7a93d4 - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012079 - + 1.0 + The designated management department determines expenditure scope, standards, methods, and management processes in accordance with company financial, procurement, and human resources policies. + department responsibility,regulatory compliance + chunk-aa5435156b829944c173fa1d2d7a93d4 + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012079 + - 1.0 - 控股子公司must report expenditure management measures to计划财务部for filing after approval. - compliance,reporting relationship - chunk-dd87aa5bc62cc9587ecb4c26d35a5263 - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012099 - + 1.0 + 控股子公司must report expenditure management measures to计划财务部for filing after approval. + compliance,reporting relationship + chunk-dd87aa5bc62cc9587ecb4c26d35a5263 + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012099 + - 1.0 - Article 11 Petty Cash Loans is one of the key expense management regulations under Chapter - chapter article relationship,specific regulation - chunk-aa5435156b829944c173fa1d2d7a93d4 - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012088 - + 1.0 + Article 11 Petty Cash Loans is one of the key expense management regulations under Chapter + chapter article relationship,specific regulation + chunk-aa5435156b829944c173fa1d2d7a93d4 + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012088 + - 1.0 - 办公室(党委办公室)manages party building and official vehicle expenses according to the company expense management policy. - expense management,policy execution - chunk-afc57a0e9548d1f484da6df6c182676b - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012088 - + 1.0 + 办公室(党委办公室)manages party building and official vehicle expenses according to the company expense management policy. + expense management,policy execution + chunk-afc57a0e9548d1f484da6df6c182676b + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012088 + - 1.0 - 工会委员会manages trade union expenses according to the company expense management policy. - expense management,policy execution - chunk-afc57a0e9548d1f484da6df6c182676b - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012079 - + 1.0 + 工会委员会manages trade union expenses according to the company expense management policy. + expense management,policy execution + chunk-afc57a0e9548d1f484da6df6c182676b + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012079 + - 1.0 - 营销中心manages bidding - expense management,policy execution - chunk-afc57a0e9548d1f484da6df6c182676b - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012079 - + 1.0 + 营销中心manages bidding + expense management,policy execution + chunk-afc57a0e9548d1f484da6df6c182676b + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012079 + - 1.0 - 组织人事部负责确定调动工作人员的报销标准,对异地挂职锻炼等人员的费用报销进行规范管理。 - 标准制定、人事管理 - chunk-d26b288ed4001dc5c504dce0eb841362 - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012090 - + 1.0 + 组织人事部负责确定调动工作人员的报销标准,对异地挂职锻炼等人员的费用报销进行规范管理。 + 标准制定、人事管理 + chunk-d26b288ed4001dc5c504dce0eb841362 + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012090 + - 1.0 - 远光软件报销问题处理指引categorizes expense standard issues as报销标准problem type. - categorization,contains - chunk-74de48577772db0161356fc844026b4e - /app/server/storage/knowledge/常见问答/远光软件报销问题处理指引.xlsx - 1779467383 - + 1.0 + 远光软件报销问题处理指引categorizes expense standard issues as报销标准problem type. + categorization,contains + chunk-74de48577772db0161356fc844026b4e + /app/server/storage/knowledge/常见问答/远光软件报销问题处理指引.xlsx + 1779467383 + - 1.0 - 住宿费超标准 - instance of,problem type - chunk-74de48577772db0161356fc844026b4e - /app/server/storage/knowledge/常见问答/远光软件报销问题处理指引.xlsx - 1779467383 - + 1.0 + 住宿费超标准 + instance of,problem type + chunk-74de48577772db0161356fc844026b4e + /app/server/storage/knowledge/常见问答/远光软件报销问题处理指引.xlsx + 1779467383 + - 1.0 - 商旅系统是公司差旅费管理的核心平台,用于统一预定和审批差旅相关费用。 - 系统支持、费用管控 - chunk-d26b288ed4001dc5c504dce0eb841362 - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012086 - + 1.0 + 商旅系统是公司差旅费管理的核心平台,用于统一预定和审批差旅相关费用。 + 系统支持、费用管控 + chunk-d26b288ed4001dc5c504dce0eb841362 + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012086 + - 1.0 - 业务招待费是公司费用管理体系的重要组成部分,与差旅费并列作为公司主要费用报销项目。 - 费用类别、公司运营 - chunk-d26b288ed4001dc5c504dce0eb841362 - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012089 - + 1.0 + 业务招待费是公司费用管理体系的重要组成部分,与差旅费并列作为公司主要费用报销项目。 + 费用类别、公司运营 + chunk-d26b288ed4001dc5c504dce0eb841362 + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012089 + - 1.0 - 会议费是公司费用管理体系的重要组成部分,与差旅费并列作为公司主要费用报销项目,需要事前审批并附业务佐证材料。 - 费用类别、公司运营 - chunk-d26b288ed4001dc5c504dce0eb841362 - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012092 - + 1.0 + 会议费是公司费用管理体系的重要组成部分,与差旅费并列作为公司主要费用报销项目,需要事前审批并附业务佐证材料。 + 费用类别、公司运营 + chunk-d26b288ed4001dc5c504dce0eb841362 + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012092 + - 1.0 - 费用预算编制包含差旅费,需要根据出差计划和标准进行编制。 - 标准依据,费用编制 - chunk-06f2e5b7b8d7365196980080ed26b760 - /app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf - 1779467007 - + 1.0 + 费用预算编制包含差旅费,需要根据出差计划和标准进行编制。 + 标准依据,费用编制 + chunk-06f2e5b7b8d7365196980080ed26b760 + /app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf + 1779467007 + - 1.0 - The reimbursement standard changes include the cancellation of official vehicle subsidy reimbursement since it has been incorporated into wages. - expense reduction,policy modification - chunk-18d968b78afe916b419c1b5973421ebe - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012085 - + 1.0 + The reimbursement standard changes include the cancellation of official vehicle subsidy reimbursement since it has been incorporated into wages. + expense reduction,policy modification + chunk-18d968b78afe916b419c1b5973421ebe + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012085 + - 1.0 - Management personnel at all levels exercise approval authority within the company's expenditure authorization approval scope. - hierarchical authority,organizational structure - chunk-74c01decac4a10cd40a491786743b0ee - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012076 - + 1.0 + Management personnel at all levels exercise approval authority within the company's expenditure authorization approval scope. + hierarchical authority,organizational structure + chunk-74c01decac4a10cd40a491786743b0ee + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012076 + - 1.0 - The centralized management department implements expenditure centralized management on behalf of the company. - centralized management,departmental responsibility - chunk-74c01decac4a10cd40a491786743b0ee - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012077 - + 1.0 + The centralized management department implements expenditure centralized management on behalf of the company. + centralized management,departmental responsibility + chunk-74c01decac4a10cd40a491786743b0ee + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012077 + - 1.0 - The Planning and Finance Department assists the centralized management department and is responsible for financial reimbursement auditing and payment settlement. - departmental responsibility,financial oversight - chunk-74c01decac4a10cd40a491786743b0ee - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012077 - + 1.0 + The Planning and Finance Department assists the centralized management department and is responsible for financial reimbursement auditing and payment settlement. + departmental responsibility,financial oversight + chunk-74c01decac4a10cd40a491786743b0ee + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012077 + - 1.0 - The operating department (individual) conducts expenditure business activities within the company's authorization. - business execution,departmental responsibility - chunk-74c01decac4a10cd40a491786743b0ee - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012078 - + 1.0 + The operating department (individual) conducts expenditure business activities within the company's authorization. + business execution,departmental responsibility + chunk-74c01decac4a10cd40a491786743b0ee + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012078 + - 1.0 - Operating departments must strictly follow company bidding, procurement, and material management regulations for procurement of materials and services. - business execution,procurement compliance - chunk-74c01decac4a10cd40a491786743b0ee - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012083 - + 1.0 + Operating departments must strictly follow company bidding, procurement, and material management regulations for procurement of materials and services. + business execution,procurement compliance + chunk-74c01decac4a10cd40a491786743b0ee + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012083 + - 1.0 - The operator submits the expenditure reimbursement application through the financial information system and provides business original documents. - documentation responsibility,workflow initiation - chunk-74c01decac4a10cd40a491786743b0ee - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012079 - + 1.0 + The operator submits the expenditure reimbursement application through the financial information system and provides business original documents. + documentation responsibility,workflow initiation + chunk-74c01decac4a10cd40a491786743b0ee + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012079 + - 1.0 - The operator is responsible for obtaining real - authenticity responsibility,document preparation - chunk-74c01decac4a10cd40a491786743b0ee - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012094 - + 1.0 + The operator is responsible for obtaining real + authenticity responsibility,document preparation + chunk-74c01decac4a10cd40a491786743b0ee + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012094 + - 1.0 - The operator has three working days to supplement incomplete business original documents after financial review. - documentation compliance,workflow timeline - chunk-74c01decac4a10cd40a491786743b0ee - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012083 - + 1.0 + The operator has three working days to supplement incomplete business original documents after financial review. + documentation compliance,workflow timeline + chunk-74c01decac4a10cd40a491786743b0ee + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012083 + - 1.0 - Financial review can reject applications if documents are incomplete, incorrectly filled, or non-compliant. - document verification,rejection handling - chunk-74c01decac4a10cd40a491786743b0ee - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012088 - + 1.0 + Financial review can reject applications if documents are incomplete, incorrectly filled, or non-compliant. + document verification,rejection handling + chunk-74c01decac4a10cd40a491786743b0ee + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012088 + - 1.0 - Aggregated VAT invoices must be accompanied by tax control system detail lists. - documentation requirement,tax compliance - chunk-74c01decac4a10cd40a491786743b0ee - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012079 - + 1.0 + Aggregated VAT invoices must be accompanied by tax control system detail lists. + documentation requirement,tax compliance + chunk-74c01decac4a10cd40a491786743b0ee + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012079 + - 1.0 - Expenditures other than employee remuneration, personal service compensation, travel allowance, special subsidy, and current account payment require tax authority-recognized invoices. - compliance requirement,documentation standard - chunk-74c01decac4a10cd40a491786743b0ee - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012082 - + 1.0 + Expenditures other than employee remuneration, personal service compensation, travel allowance, special subsidy, and current account payment require tax authority-recognized invoices. + compliance requirement,documentation standard + chunk-74c01decac4a10cd40a491786743b0ee + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012082 + - 1.0 - 公司通过第十七条对培训费进行规范管理。 - 合规管理,规章制定 - chunk-e9438f69c9e221d9f0f00a05ad84eac6 - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012084 - + 1.0 + 公司通过第十七条对培训费进行规范管理。 + 合规管理,规章制定 + chunk-e9438f69c9e221d9f0f00a05ad84eac6 + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012084 + - 1.0 - 公司通过第十八条对通信费进行规范管理。 - 合规管理,规章制定 - chunk-e9438f69c9e221d9f0f00a05ad84eac6 - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012084 - + 1.0 + 公司通过第十八条对通信费进行规范管理。 + 合规管理,规章制定 + chunk-e9438f69c9e221d9f0f00a05ad84eac6 + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012084 + - 1.0 - 公司通过第十九条对邮递费进行规范管理。 - 合规管理,规章制定 - chunk-e9438f69c9e221d9f0f00a05ad84eac6 - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012084 - + 1.0 + 公司通过第十九条对邮递费进行规范管理。 + 合规管理,规章制定 + chunk-e9438f69c9e221d9f0f00a05ad84eac6 + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012084 + - 1.0 - 公司通过第二十条对薪酬福利支出进行规范管理。 - 薪酬管理,规章制定 - chunk-e9438f69c9e221d9f0f00a05ad84eac6 - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012086 - + 1.0 + 公司通过第二十条对薪酬福利支出进行规范管理。 + 薪酬管理,规章制定 + chunk-e9438f69c9e221d9f0f00a05ad84eac6 + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012086 + - 1.0 - 公司通过第二十一条对对外捐赠支出进行规范管理。 - 捐赠管理,规章制定 - chunk-e9438f69c9e221d9f0f00a05ad84eac6 - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012089 - + 1.0 + 公司通过第二十一条对对外捐赠支出进行规范管理。 + 捐赠管理,规章制定 + chunk-e9438f69c9e221d9f0f00a05ad84eac6 + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012089 + - 1.0 - Departments and units must implement the night high-speed rail provision allowing employees to choose sleeper seats when high-speed train travel exceeds 6 hours at night. - policy implementation,travel standards - chunk-613d6dfd4c5e9c807229a3147f96b584 - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012084 - + 1.0 + Departments and units must implement the night high-speed rail provision allowing employees to choose sleeper seats when high-speed train travel exceeds 6 hours at night. + policy implementation,travel standards + chunk-613d6dfd4c5e9c807229a3147f96b584 + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012084 + - 1.0 - Departments and units are responsible for strictly managing taxi usage, limiting reimbursements to emergency situations, client接送, late night work, and other special circumstances. - cost control,policy enforcement - chunk-613d6dfd4c5e9c807229a3147f96b584 - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012099 - + 1.0 + Departments and units are responsible for strictly managing taxi usage, limiting reimbursements to emergency situations, client接送, late night work, and other special circumstances. + cost control,policy enforcement + chunk-613d6dfd4c5e9c807229a3147f96b584 + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012099 + - 1.0 - Senior Management P8 and Above represents a subset of Company Leadership at the highest organizational levels. - management level,organizational hierarchy - chunk-2eea91fe956cae84935e609164d08d55 - /app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx - 1779466161 - + 1.0 + Senior Management P8 and Above represents a subset of Company Leadership at the highest organizational levels. + management level,organizational hierarchy + chunk-2eea91fe956cae84935e609164d08d55 + /app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx + 1779466161 + - 1.0 - 第十四条专门定义了业务招待费的概念和报销要求,明确了接待客户和相关单位的餐饮等合理支出范围。 - 条款规定、费用管理 - chunk-d26b288ed4001dc5c504dce0eb841362 - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012092 - + 1.0 + 第十四条专门定义了业务招待费的概念和报销要求,明确了接待客户和相关单位的餐饮等合理支出范围。 + 条款规定、费用管理 + chunk-d26b288ed4001dc5c504dce0eb841362 + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012092 + - 1.0 - 费用预算编制包含业务招待费,需要严格控制并参考上年度标准。 - 控制标准,费用编制 - chunk-06f2e5b7b8d7365196980080ed26b760 - /app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf - 1779467008 - + 1.0 + 费用预算编制包含业务招待费,需要严格控制并参考上年度标准。 + 控制标准,费用编制 + chunk-06f2e5b7b8d7365196980080ed26b760 + /app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf + 1779467008 + - 1.0 - 第十五条专门规定了会议费的报销范围和报销要求,包括公司主办或承办会议以及参加外部会议的报销标准。 - 条款规定、费用管理 - chunk-d26b288ed4001dc5c504dce0eb841362 - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012092 - + 1.0 + 第十五条专门规定了会议费的报销范围和报销要求,包括公司主办或承办会议以及参加外部会议的报销标准。 + 条款规定、费用管理 + chunk-d26b288ed4001dc5c504dce0eb841362 + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012092 + - 1.0 - 公司总裁对经费预算30000元及以上的内部会议具有审批权限,体现了公司对大额会议支出的管控。 - 审批权限、预算管理 - chunk-d26b288ed4001dc5c504dce0eb841362 - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012093 - + 1.0 + 公司总裁对经费预算30000元及以上的内部会议具有审批权限,体现了公司对大额会议支出的管控。 + 审批权限、预算管理 + chunk-d26b288ed4001dc5c504dce0eb841362 + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012093 + - 1.0 - 第十六条专门规定了广告宣传费的定义和管理要求,包括广告费和业务宣传费两类。 - 条款规定、费用管理 - chunk-d26b288ed4001dc5c504dce0eb841362 - /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf - 1779012092 - + 1.0 + 第十六条专门规定了广告宣传费的定义和管理要求,包括广告费和业务宣传费两类。 + 条款规定、费用管理 + chunk-d26b288ed4001dc5c504dce0eb841362 + /app/server/storage/knowledge/报销制度/2c1cb358f08d44ceb0e4d287133206ec__远光《公司支出管理办法(2024)》.pdf + 1779012092 + - 1.0 - 经办人initiates the approval process as the first step for all contract approvals. - approval initiation,process start - chunk-1f813062c109d781d9d684a4d23bfe1e - /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx - 1779465763 - + 1.0 + 经办人initiates the approval process as the first step for all contract approvals. + approval initiation,process start + chunk-1f813062c109d781d9d684a4d23bfe1e + /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx + 1779465763 + - 1.0 - 经办人initiates the travel reimbursement process by submitting required documents including the差旅费报销单. - document submission,reimbursement initiation - chunk-85ebe3a7090c0f5408b34e92c2384b1a - /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf - 1779466042 - + 1.0 + 经办人initiates the travel reimbursement process by submitting required documents including the差旅费报销单. + document submission,reimbursement initiation + chunk-85ebe3a7090c0f5408b34e92c2384b1a + /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf + 1779466042 + - 1.0 - The company implements a hierarchical approval system for fund payments to ensure proper authorization and financial oversight. - authorization framework,financial control - chunk-9734bc0dd5225675ba6907f874a807ce - /app/server/storage/knowledge/制度政策/远光软件公司财务管理制度总则.docx - 1779465826 - + 1.0 + The company implements a hierarchical approval system for fund payments to ensure proper authorization and financial oversight. + authorization framework,financial control + chunk-9734bc0dd5225675ba6907f874a807ce + /app/server/storage/knowledge/制度政策/远光软件公司财务管理制度总则.docx + 1779465826 + - 1.0 - 员工uses the OA系统to submit travel applications before departure, following company procedures. - process initiation,system usage - chunk-85ebe3a7090c0f5408b34e92c2384b1a - /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf - 1779466041 - + 1.0 + 员工uses the OA系统to submit travel applications before departure, following company procedures. + process initiation,system usage + chunk-85ebe3a7090c0f5408b34e92c2384b1a + /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf + 1779466041 + - 1.0 - 员工initiates a出差申请through the OA系统before traveling on company business. - business travel,procedural compliance - chunk-85ebe3a7090c0f5408b34e92c2384b1a - /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf - 1779466041 - + 1.0 + 员工initiates a出差申请through the OA系统before traveling on company business. + business travel,procedural compliance + chunk-85ebe3a7090c0f5408b34e92c2384b1a + /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf + 1779466041 + - 1.0 - 员工requests approval from上级领导when changes to travel plans are needed or for emergency travel situations. - approval request,hierarchy - chunk-85ebe3a7090c0f5408b34e92c2384b1a - /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf - 1779466042 - + 1.0 + 员工requests approval from上级领导when changes to travel plans are needed or for emergency travel situations. + approval request,hierarchy + chunk-85ebe3a7090c0f5408b34e92c2384b1a + /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf + 1779466042 + - 1.0 - 员工follows特殊情况处理guidelines when facing emergency travel, client entertainment, or unexpected expenses during business trips. - emergency procedures,policy compliance - chunk-85ebe3a7090c0f5408b34e92c2384b1a - /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf - 1779466042 - + 1.0 + 员工follows特殊情况处理guidelines when facing emergency travel, client entertainment, or unexpected expenses during business trips. + emergency procedures,policy compliance + chunk-85ebe3a7090c0f5408b34e92c2384b1a + /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf + 1779466042 + - 1.0 - 员工may招待客户during travel if prior approval from a superior is obtained, as specified in special case handling procedures. - business entertainment,prior approval - chunk-85ebe3a7090c0f5408b34e92c2384b1a - /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf - 1779466042 - + 1.0 + 员工may招待客户during travel if prior approval from a superior is obtained, as specified in special case handling procedures. + business entertainment,prior approval + chunk-85ebe3a7090c0f5408b34e92c2384b1a + /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf + 1779466042 + - 1.0 - 部门负责人has approval authority for contracts below 100,000 yuan. - approval authority,contract approval - chunk-1f813062c109d781d9d684a4d23bfe1e - /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx - 1779465763 - + 1.0 + 部门负责人has approval authority for contracts below 100,000 yuan. + approval authority,contract approval + chunk-1f813062c109d781d9d684a4d23bfe1e + /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx + 1779465763 + - 1.0 - 部门负责人对出差申请具有审批权限。 - 审批权限,层级管理 - chunk-589aae03864f03017b4a61f95c13b5e1 - /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx - 1779466006 - + 1.0 + 部门负责人对出差申请具有审批权限。 + 审批权限,层级管理 + chunk-589aae03864f03017b4a61f95c13b5e1 + /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx + 1779466006 + - 1.0 - 部门负责人reviews and approves travel reimbursement submissions as part of the approval workflow. - department management,review and approval - chunk-85ebe3a7090c0f5408b34e92c2384b1a - /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf - 1779466041 - + 1.0 + 部门负责人reviews and approves travel reimbursement submissions as part of the approval workflow. + department management,review and approval + chunk-85ebe3a7090c0f5408b34e92c2384b1a + /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf + 1779466041 + - 1.0 - 部门负责人must approve the固定资产报废申请表along with the asset management department. - approval authority,departmental responsibility - chunk-6175768b05adf2e7229c16f13ee7cffd - /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf - 1779467718 - + 1.0 + 部门负责人must approve the固定资产报废申请表along with the asset management department. + approval authority,departmental responsibility + chunk-6175768b05adf2e7229c16f13ee7cffd + /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf + 1779467718 + - 1.0 - 部门负责人from both departments must sign the资产调拨单for asset transfers. - inter-departmental coordination,signature requirement - chunk-6175768b05adf2e7229c16f13ee7cffd - /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf - 1779467718 - + 1.0 + 部门负责人from both departments must sign the资产调拨单for asset transfers. + inter-departmental coordination,signature requirement + chunk-6175768b05adf2e7229c16f13ee7cffd + /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf + 1779467718 + - 1.0 - 无单报销is officially named总裁办, serving as the primary product designation. - product naming,system identity - chunk-07de6ea74f60535b689f977295770273 - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379014 - + 1.0 + 无单报销is officially named总裁办, serving as the primary product designation. + product naming,system identity + chunk-07de6ea74f60535b689f977295770273 + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379014 + - 1.0 - The status bar is referenced in the document structure alongside the color scheme section. - document structure,hierarchy - chunk-2224d777c0b72d0b2dab622c79096c2c - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379015 - + 1.0 + The status bar is referenced in the document structure alongside the color scheme section. + document structure,hierarchy + chunk-2224d777c0b72d0b2dab622c79096c2c + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379015 + - 1.0 - 准备阶段is the first step in the overall reimbursement process workflow. - process step,workflow sequence - chunk-962e1165f2750bf5d5d1e2cfd62dc1d8 - /app/server/storage/knowledge/培训资料/远光软件报销流程培训手册.pdf - 1779467250 - + 1.0 + 准备阶段is the first step in the overall reimbursement process workflow. + process step,workflow sequence + chunk-962e1165f2750bf5d5d1e2cfd62dc1d8 + /app/server/storage/knowledge/培训资料/远光软件报销流程培训手册.pdf + 1779467250 + - 1.0 - 填报阶段is the second step in the overall reimbursement process workflow. - process step,workflow sequence - chunk-962e1165f2750bf5d5d1e2cfd62dc1d8 - /app/server/storage/knowledge/培训资料/远光软件报销流程培训手册.pdf - 1779467251 - + 1.0 + 填报阶段is the second step in the overall reimbursement process workflow. + process step,workflow sequence + chunk-962e1165f2750bf5d5d1e2cfd62dc1d8 + /app/server/storage/knowledge/培训资料/远光软件报销流程培训手册.pdf + 1779467251 + - 1.0 - 审批阶段is the third step in the overall reimbursement process workflow, involving department head approval, finance department compliance review, and level-by-level approval according to approval authority. - process step,workflow sequence - chunk-962e1165f2750bf5d5d1e2cfd62dc1d8 - /app/server/storage/knowledge/培训资料/远光软件报销流程培训手册.pdf - 1779467251 - + 1.0 + 审批阶段is the third step in the overall reimbursement process workflow, involving department head approval, finance department compliance review, and level-by-level approval according to approval authority. + process step,workflow sequence + chunk-962e1165f2750bf5d5d1e2cfd62dc1d8 + /app/server/storage/knowledge/培训资料/远光软件报销流程培训手册.pdf + 1779467251 + - 1.0 - 无单报销is a web-based tool for expense reimbursement. - platform,product type - chunk-07de6ea74f60535b689f977295770273 - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379015 - + 1.0 + 无单报销is a web-based tool for expense reimbursement. + platform,product type + chunk-07de6ea74f60535b689f977295770273 + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379015 + - 1.0 - 无单报销targets large enterprises to solve existing ERP user experience problems. - customer segment,target market - chunk-07de6ea74f60535b689f977295770273 - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379015 - + 1.0 + 无单报销targets large enterprises to solve existing ERP user experience problems. + customer segment,target market + chunk-07de6ea74f60535b689f977295770273 + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379015 + - 1.0 - 无单报销is designed for business personnel (non-finance professionals) as the primary users. - intended audience,target users - chunk-07de6ea74f60535b689f977295770273 - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379015 - + 1.0 + 无单报销is designed for business personnel (non-finance professionals) as the primary users. + intended audience,target users + chunk-07de6ea74f60535b689f977295770273 + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379015 + - 1.0 - 无单报销operates in front of the ERP system, using ERP as its backend database and archiving system. - backend support,system integration - chunk-07de6ea74f60535b689f977295770273 - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379016 - + 1.0 + 无单报销operates in front of the ERP system, using ERP as its backend database and archiving system. + backend support,system integration + chunk-07de6ea74f60535b689f977295770273 + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379016 + - 1.0 - AI预审performs completeness checks to verify all required vouchers and attachments are present. - automated verification,document completeness - chunk-1746bd83138e85e66a78e0cb9ad79272 - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379014 - + 1.0 + AI预审performs completeness checks to verify all required vouchers and attachments are present. + automated verification,document completeness + chunk-1746bd83138e85e66a78e0cb9ad79272 + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379014 + - 1.0 - AI预审performs compliance checks to verify expenses meet regulatory standards. - automated verification,policy compliance - chunk-1746bd83138e85e66a78e0cb9ad79272 - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379015 - + 1.0 + AI预审performs compliance checks to verify expenses meet regulatory standards. + automated verification,policy compliance + chunk-1746bd83138e85e66a78e0cb9ad79272 + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379015 + - 1.0 - AI预审automatically marks identified issues in the audit process. - automated identification,issue marking - chunk-1746bd83138e85e66a78e0cb9ad79272 - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379015 - + 1.0 + AI预审automatically marks identified issues in the audit process. + automated identification,issue marking + chunk-1746bd83138e85e66a78e0cb9ad79272 + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379015 + - 1.0 - Clicking the pre-audit button initiates the AI预审automated verification process. - audit trigger,user interaction - chunk-1746bd83138e85e66a78e0cb9ad79272 - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379015 - + 1.0 + Clicking the pre-audit button initiates the AI预审automated verification process. + audit trigger,user interaction + chunk-1746bd83138e85e66a78e0cb9ad79272 + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379015 + - 1.0 - 审核点includes check items categorized under the completeness verification type. - audit structure,verification type - chunk-1746bd83138e85e66a78e0cb9ad79272 - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379015 - + 1.0 + 审核点includes check items categorized under the completeness verification type. + audit structure,verification type + chunk-1746bd83138e85e66a78e0cb9ad79272 + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379015 + - 1.0 - 审核点includes check items categorized under the compliance verification type. - audit structure,verification type - chunk-1746bd83138e85e66a78e0cb9ad79272 - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379015 - + 1.0 + 审核点includes check items categorized under the compliance verification type. + audit structure,verification type + chunk-1746bd83138e85e66a78e0cb9ad79272 + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379015 + - 3.0 - 上级领导参与出差返回后审批手续的补办流程。<SEP>出差前需电话请示上级领导,获得批准后方可执行。<SEP>出差期间招待客户需事先征得上级领导同意。 - 事前同意,事后备案,审批,批准,补办流程,请示 - chunk-a645037600147280d64fd17543098f51 - /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf - 1779466041 - + 3.0 + 上级领导参与出差返回后审批手续的补办流程。<SEP>出差前需电话请示上级领导,获得批准后方可执行。<SEP>出差期间招待客户需事先征得上级领导同意。 + 事前同意,事后备案,审批,批准,补办流程,请示 + chunk-a645037600147280d64fd17543098f51 + /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf + 1779466041 + - 1.0 - 出差返回后需补办审批手续以完成正规程序。 - 补办流程 - chunk-a645037600147280d64fd17543098f51 - /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf - 1779466041 - + 1.0 + 出差返回后需补办审批手续以完成正规程序。 + 补办流程 + chunk-a645037600147280d64fd17543098f51 + /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf + 1779466041 + - 1.0 - 出差期间可能因工作需要招待客户。 - 业务往来,招待 - chunk-a645037600147280d64fd17543098f51 - /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf - 1779466042 - + 1.0 + 出差期间可能因工作需要招待客户。 + 业务往来,招待 + chunk-a645037600147280d64fd17543098f51 + /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf + 1779466042 + - 1.0 - 意外费用发生在出差期间,报销时需说明情况。 - 报销说明,费用产生 - chunk-a645037600147280d64fd17543098f51 - /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf - 1779466042 - + 1.0 + 意外费用发生在出差期间,报销时需说明情况。 + 报销说明,费用产生 + chunk-a645037600147280d64fd17543098f51 + /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf + 1779466042 + - 1.0 - 出差期间发生意外费用需保留相关证明材料用于报销说明。 - 情况说明,报销凭证 - chunk-a645037600147280d64fd17543098f51 - /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf - 1779466042 - + 1.0 + 出差期间发生意外费用需保留相关证明材料用于报销说明。 + 情况说明,报销凭证 + chunk-a645037600147280d64fd17543098f51 + /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf + 1779466042 + - 1.0 - Train Ticket Compliance Check is one of the pre-review items that determines whether expense items pass verification and are displayed in the pre-review result. - compliance verification,system workflow - chunk-ce44e4483e4119265b43eacb72e0326a - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379015 - + 1.0 + Train Ticket Compliance Check is one of the pre-review items that determines whether expense items pass verification and are displayed in the pre-review result. + compliance verification,system workflow + chunk-ce44e4483e4119265b43eacb72e0326a + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379015 + - 1.0 - Flight Ticket Compliance Check is one of the - compliance verification,system workflow - chunk-ce44e4483e4119265b43eacb72e0326a - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379015 - + 1.0 + Flight Ticket Compliance Check is one of the + compliance verification,system workflow + chunk-ce44e4483e4119265b43eacb72e0326a + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379015 + - 1.0 - The color scheme section (3.2) precedes the functional requirements section (4) in the document. - document structure,sequential - chunk-2224d777c0b72d0b2dab622c79096c2c - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379016 - + 1.0 + The color scheme section (3.2) precedes the functional requirements section (4) in the document. + document structure,sequential + chunk-2224d777c0b72d0b2dab622c79096c2c + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379016 + - 1.0 - Menu 2 contains the Matter List feature for viewing pending and processed matters. - feature containment,menu structure - chunk-99c6f377dff2b9a37a7214b7b05ea9a8 - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379015 - + 1.0 + Menu 2 contains the Matter List feature for viewing pending and processed matters. + feature containment,menu structure + chunk-99c6f377dff2b9a37a7214b7b05ea9a8 + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379015 + - 1.0 - Menu 2 contains the Receipt-Free Reimbursement module for submitting expenses without traditional receipts. - feature containment,menu structure - chunk-99c6f377dff2b9a37a7214b7b05ea9a8 - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379016 - + 1.0 + Menu 2 contains the Receipt-Free Reimbursement module for submitting expenses without traditional receipts. + feature containment,menu structure + chunk-99c6f377dff2b9a37a7214b7b05ea9a8 + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379016 + - 1.0 - Menu 2 contains the AI Assistant feature providing global chat functionality. - feature containment,menu structure - chunk-99c6f377dff2b9a37a7214b7b05ea9a8 - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379016 - + 1.0 + Menu 2 contains the AI Assistant feature providing global chat functionality. + feature containment,menu structure + chunk-99c6f377dff2b9a37a7214b7b05ea9a8 + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379016 + - 1.0 - Menu 2 contains the User Center feature with personal center and logout options. - feature containment,menu structure - chunk-99c6f377dff2b9a37a7214b7b05ea9a8 - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379016 - + 1.0 + Menu 2 contains the User Center feature with personal center and logout options. + feature containment,menu structure + chunk-99c6f377dff2b9a37a7214b7b05ea9a8 + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379016 + - 1.0 - Matter List displays a business travel matter titled Q1 Quarterly Business Progress Report with amount 1678.20 and status Not Submitted. - business record,item display - chunk-99c6f377dff2b9a37a7214b7b05ea9a8 - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379016 - + 1.0 + Matter List displays a business travel matter titled Q1 Quarterly Business Progress Report with amount 1678.20 and status Not Submitted. + business record,item display + chunk-99c6f377dff2b9a37a7214b7b05ea9a8 + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379016 + - 1.0 - Matter List displays a business travel matter for the 2026 National AI Technology Summit in Hefei with amount 3498.39 and status Not Submitted. - business record,item display - chunk-99c6f377dff2b9a37a7214b7b05ea9a8 - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379016 - + 1.0 + Matter List displays a business travel matter for the 2026 National AI Technology Summit in Hefei with amount 3498.39 and status Not Submitted. + business record,item display + chunk-99c6f377dff2b9a37a7214b7b05ea9a8 + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379016 + - 1.0 - Matter List displays a business travel matter for Smart Platform Jiangsu Province Company Operations Support with amount 1345.87 and status Submitted. - business record,item display - chunk-99c6f377dff2b9a37a7214b7b05ea9a8 - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379017 - + 1.0 + Matter List displays a business travel matter for Smart Platform Jiangsu Province Company Operations Support with amount 1345.87 and status Submitted. + business record,item display + chunk-99c6f377dff2b9a37a7214b7b05ea9a8 + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379017 + - 1.0 - Receipt-Free Reimbursement module includes the Initiate Matter function for starting reimbursement processes. - module function,workflow step - chunk-99c6f377dff2b9a37a7214b7b05ea9a8 - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379016 - + 1.0 + Receipt-Free Reimbursement module includes the Initiate Matter function for starting reimbursement processes. + module function,workflow step + chunk-99c6f377dff2b9a37a7214b7b05ea9a8 + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379016 + - 1.0 - Receipt-Free Reimbursement module includes the Document Upload function supporting drag-and-drop and click upload. - module function,workflow step - chunk-99c6f377dff2b9a37a7214b7b05ea9a8 - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379017 - + 1.0 + Receipt-Free Reimbursement module includes the Document Upload function supporting drag-and-drop and click upload. + module function,workflow step + chunk-99c6f377dff2b9a37a7214b7b05ea9a8 + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379017 + - 1.0 - Receipt-Free Reimbursement module includes the Time Track function that generates visual timelines after document upload. - module function,workflow step - chunk-99c6f377dff2b9a37a7214b7b05ea9a8 - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379017 - + 1.0 + Receipt-Free Reimbursement module includes the Time Track function that generates visual timelines after document upload. + module function,workflow step + chunk-99c6f377dff2b9a37a7214b7b05ea9a8 + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379017 + - 1.0 - Receipt-Free Reimbursement module includes the Submit Reimbursement function accessible after AI pre-review. - module function,workflow completion - chunk-99c6f377dff2b9a37a7214b7b05ea9a8 - /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx - 1779379017 - + 1.0 + Receipt-Free Reimbursement module includes the Submit Reimbursement function accessible after AI pre-review. + module function,workflow completion + chunk-99c6f377dff2b9a37a7214b7b05ea9a8 + /app/server/storage/knowledge/报销制度/a8f8465df08e455ebe133351721d49f8__无单需求文档0506.docx + 1779379017 + - 1.0 - The Excel workbook contains the worksheet "会计科目说明" as its first sheet. - workbook structure,worksheet inclusion - chunk-31ff57cf79d009c378478f065eda9d4d - /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx - 1779441744 - + 1.0 + The Excel workbook contains the worksheet "会计科目说明" as its first sheet. + workbook structure,worksheet inclusion + chunk-31ff57cf79d009c378478f065eda9d4d + /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx + 1779441744 + - 1.0 - The worksheet includes "科目编码" as a column header for organizing accounting subject codes. - data classification,worksheet column - chunk-31ff57cf79d009c378478f065eda9d4d - /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx - 1779441742 - + 1.0 + The worksheet includes "科目编码" as a column header for organizing accounting subject codes. + data classification,worksheet column + chunk-31ff57cf79d009c378478f065eda9d4d + /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx + 1779441742 + - 1.0 - The worksheet includes "科目名称" as a column header for naming accounting subjects. - data classification,worksheet column - chunk-31ff57cf79d009c378478f065eda9d4d - /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx - 1779441742 - + 1.0 + The worksheet includes "科目名称" as a column header for naming accounting subjects. + data classification,worksheet column + chunk-31ff57cf79d009c378478f065eda9d4d + /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx + 1779441742 + - 1.0 - The worksheet includes "科目类别" as a column header for categorizing accounting subjects. - data classification,worksheet column - chunk-31ff57cf79d009c378478f065eda9d4d - /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx - 1779441743 - + 1.0 + The worksheet includes "科目类别" as a column header for categorizing accounting subjects. + data classification,worksheet column + chunk-31ff57cf79d009c378478f065eda9d4d + /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx + 1779441743 + - 1.0 - The worksheet includes "使用说明" as a column header for describing accounting subject usage. - data classification,worksheet column - chunk-31ff57cf79d009c378478f065eda9d4d - /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx - 1779441743 - + 1.0 + The worksheet includes "使用说明" as a column header for describing accounting subject usage. + data classification,worksheet column + chunk-31ff57cf79d009c378478f065eda9d4d + /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx + 1779441743 + - 1.0 - The worksheet includes "备注" as a column header for additional notes on accounting subjects. - data classification,worksheet column - chunk-31ff57cf79d009c378478f065eda9d4d - /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx - 1779441743 - + 1.0 + The worksheet includes "备注" as a column header for additional notes on accounting subjects. + data classification,worksheet column + chunk-31ff57cf79d009c378478f065eda9d4d + /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx + 1779441743 + - 1.0 - 库存现金is classified under the asset category (资产类) in the accounting system. - account category classification,asset type - chunk-31ff57cf79d009c378478f065eda9d4d - /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx - 1779441742 - + 1.0 + 库存现金is classified under the asset category (资产类) in the accounting system. + account category classification,asset type + chunk-31ff57cf79d009c378478f065eda9d4d + /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx + 1779441742 + - 1.0 - 银行存款is classified under the asset category (资产类 - account category classification,asset type - chunk-31ff57cf79d009c378478f065eda9d4d - /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx - 1779441742 - + 1.0 + 银行存款is classified under the asset category (资产类 + account category classification,asset type + chunk-31ff57cf79d009c378478f065eda9d4d + /app/server/storage/knowledge/财务知识库/远光软件会计科目使用说明.xlsx + 1779441742 + - 1.0 - The SLA service standard defines the service content, response times, and availability requirements for accounts receivable processing. - service definition,service scope - chunk-af56151a803634f02e294f2d692fc1f0 - /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx - 1779467116 - + 1.0 + The SLA service standard defines the service content, response times, and availability requirements for accounts receivable processing. + service definition,service scope + chunk-af56151a803634f02e294f2d692fc1f0 + /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx + 1779467116 + + + + 1.0 + 应收账款is classified under the资产类category as an asset item. + accounting type,category classification + chunk-f894acfbb6c681d00f75cf9c486d491b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546633 + - 1.0 - Accounts Payable is one of the service items provided by Yuan Guang Software Financial Shared Service Center, involving supplier payment processing with a standard turnaround of 1 business day, same-day urgent turnaround, and 99% availability requirement. - financial process,service provision - chunk-6f1d6991d45799bc8ff24afaed39244d - /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx - 1779467115 - + 1.0 + Accounts Payable is one of the service items provided by Yuan Guang Software Financial Shared Service Center, involving supplier payment processing with a standard turnaround of 1 business day, same-day urgent turnaround, and 99% availability requirement. + financial process,service provision + chunk-6f1d6991d45799bc8ff24afaed39244d + /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx + 1779467115 + - 1.0 - The SLA service standard defines the service content, response times, and availability requirements for accounts payable processing. - service definition,service scope - chunk-af56151a803634f02e294f2d692fc1f0 - /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx - 1779467116 - + 1.0 + The SLA service standard defines the service content, response times, and availability requirements for accounts payable processing. + service definition,service scope + chunk-af56151a803634f02e294f2d692fc1f0 + /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx + 1779467116 + - - 1.0 - 会计基础知识is the first section of财务基础知识手册. - content organization,document structure - chunk-78edb0c8ccc8238159196ecaeeb08d43 - /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx - 1779441771 - - - - 1.0 - 税务基础知识is the second section of财务基础知识手册. - content organization,document structure - chunk-78edb0c8ccc8238159196ecaeeb08d43 - /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx - 1779441771 - - - - 1.0 - 财务报表解读is the third section of财务基础知识手册. - content organization,document structure - chunk-78edb0c8ccc8238159196ecaeeb08d43 - /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx - 1779441771 - - - - 1.0 - 资产is one of the six accounting elements representing economic resources owned by the company. - accounting framework,conceptual component - chunk-78edb0c8ccc8238159196ecaeeb08d43 - /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx - 1779441770 - + + 1.0 + 常用会计科目includes资产类as one of its classification categories. + accounting classification,category membership + chunk-f894acfbb6c681d00f75cf9c486d491b + /app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx + 1779546632 + - 1.0 - 案例一通过张三的差旅费报销案例说明了增值税专用发票的取得和进项税额抵扣。 - 案例说明,税务示例 - chunk-89afdbbf904b60cf6494cba2638e08a8 - /app/server/storage/knowledge/培训资料/远光软件财务制度培训手册.docx - 1779467318 - + 1.0 + 案例一通过张三的差旅费报销案例说明了增值税专用发票的取得和进项税额抵扣。 + 案例说明,税务示例 + chunk-89afdbbf904b60cf6494cba2638e08a8 + /app/server/storage/knowledge/培训资料/远光软件财务制度培训手册.docx + 1779467318 + - 1.0 - The manual explains权责发生制as the accrual basis of accounting principle. - content explanation,terminology definition - chunk-2ee7e2a66cb544bdfe1b09e133863ad1 - /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx - 1779441776 - + 1.0 + The manual explains权责发生制as the accrual basis of accounting principle. + content explanation,terminology definition + chunk-2ee7e2a66cb544bdfe1b09e133863ad1 + /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx + 1779441776 + - 1.0 - The manual explains收付实现制as the cash basis of accounting principle. - content explanation,terminology definition - chunk-2ee7e2a66cb544bdfe1b09e133863ad1 - /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx - 1779441776 - + 1.0 + The manual explains收付实现制as the cash basis of accounting principle. + content explanation,terminology definition + chunk-2ee7e2a66cb544bdfe1b09e133863ad1 + /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx + 1779441776 + - 1.0 - The manual explains固定资产折旧as fixed asset depreciation using straight-line method. - content explanation,terminology definition - chunk-2ee7e2a66cb544bdfe1b09e133863ad1 - /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx - 1779441776 - + 1.0 + The manual explains固定资产折旧as fixed asset depreciation using straight-line method. + content explanation,terminology definition + chunk-2ee7e2a66cb544bdfe1b09e133863ad1 + /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx + 1779441776 + - 1.0 - The manual explains摊销as the process of amortizing intangible assets over time. - content explanation,terminology definition - chunk-2ee7e2a66cb544bdfe1b09e133863ad1 - /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx - 1779441790 - + 1.0 + The manual explains摊销as the process of amortizing intangible assets over time. + content explanation,terminology definition + chunk-2ee7e2a66cb544bdfe1b09e133863ad1 + /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx + 1779441790 + - 1.0 - The manual explains增值税进项税额as VAT input tax deductible from - content explanation,terminology definition - chunk-2ee7e2a66cb544bdfe1b09e133863ad1 - /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx - 1779441791 - + 1.0 + The manual explains增值税进项税额as VAT input tax deductible from + content explanation,terminology definition + chunk-2ee7e2a66cb544bdfe1b09e133863ad1 + /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx + 1779441791 + - 1.0 - Fixed asset depreciation is calculated using the straight-line method as specified by the company. - accounting standard,depreciation method - chunk-2ee7e2a66cb544bdfe1b09e133863ad1 - /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx - 1779441790 - + 1.0 + Fixed asset depreciation is calculated using the straight-line method as specified by the company. + accounting standard,depreciation method + chunk-2ee7e2a66cb544bdfe1b09e133863ad1 + /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx + 1779441790 + - 1.0 - Gross profit margin is calculated by dividing gross profit by operating revenue. - profitability measure,ratio component - chunk-2ee7e2a66cb544bdfe1b09e133863ad1 - /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx - 1779441776 - + 1.0 + Gross profit margin is calculated by dividing gross profit by operating revenue. + profitability measure,ratio component + chunk-2ee7e2a66cb544bdfe1b09e133863ad1 + /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx + 1779441776 + - 1.0 - Gross margin calculation uses operating revenue as the denominator. - ratio component,revenue basis - chunk-2ee7e2a66cb544bdfe1b09e133863ad1 - /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx - 1779441776 - + 1.0 + Gross margin calculation uses operating revenue as the denominator. + ratio component,revenue basis + chunk-2ee7e2a66cb544bdfe1b09e133863ad1 + /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx + 1779441776 + - 1.0 - Gross margin calculation subtracts operating cost from operating revenue in the numerator. - cost deduction,ratio component - chunk-2ee7e2a66cb544bdfe1b09e133863ad1 - /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx - 1779441776 - + 1.0 + Gross margin calculation subtracts operating cost from operating revenue in the numerator. + cost deduction,ratio component + chunk-2ee7e2a66cb544bdfe1b09e133863ad1 + /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx + 1779441776 + - 1.0 - ROE is calculated by dividing net income by shareholders' equity. - profitability measure,ratio component - chunk-2ee7e2a66cb544bdfe1b09e133863ad1 - /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx - 1779441776 - + 1.0 + ROE is calculated by dividing net income by shareholders' equity. + profitability measure,ratio component + chunk-2ee7e2a66cb544bdfe1b09e133863ad1 + /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx + 1779441776 + - 1.0 - ROE calculation uses shareholders' equity as the denominator. - equity basis,ratio component - chunk-2ee7e2a66cb544bdfe1b09e133863ad1 - /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx - 1779441776 - + 1.0 + ROE calculation uses shareholders' equity as the denominator. + equity basis,ratio component + chunk-2ee7e2a66cb544bdfe1b09e133863ad1 + /app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx + 1779441776 + - 1.0 - 第六条规定固定资产折旧采用年限平均法,按照使用寿命平均分摊成本。 - 成本分摊,折旧方法 - chunk-4287121b009a169fe4155526bfe413ea - /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf - 1779465897 - + 1.0 + 第六条规定固定资产折旧采用年限平均法,按照使用寿命平均分摊成本。 + 成本分摊,折旧方法 + chunk-4287121b009a169fe4155526bfe413ea + /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf + 1779465897 + - 1.0 - Training expenses can be fully deducted before calculating corporate income tax liability. - deductible expense,tax deduction - chunk-93d2389cdb74257e90201dccbc3f6539 - /app/server/storage/knowledge/财务知识库/远光软件高新技术企业税收优惠政策汇总.pdf - 1779441857 - + 1.0 + Training expenses can be fully deducted before calculating corporate income tax liability. + deductible expense,tax deduction + chunk-93d2389cdb74257e90201dccbc3f6539 + /app/server/storage/knowledge/财务知识库/远光软件高新技术企业税收优惠政策汇总.pdf + 1779441857 + - 1.0 - Venture capital deduction allows a percentage of the investment to be deducted from taxable income. - deductible amount,tax reduction - chunk-93d2389cdb74257e90201dccbc3f6539 - /app/server/storage/knowledge/财务知识库/远光软件高新技术企业税收优惠政策汇总.pdf - 1779441857 - + 1.0 + Venture capital deduction allows a percentage of the investment to be deducted from taxable income. + deductible amount,tax reduction + chunk-93d2389cdb74257e90201dccbc3f6539 + /app/server/storage/knowledge/财务知识库/远光软件高新技术企业税收优惠政策汇总.pdf + 1779441857 + - 1.0 - Venture capital deduction applies specifically to investments made in unlisted small and medium high-tech enterprises. - investment target,qualifying entity - chunk-93d2389cdb74257e90201dccbc3f6539 - /app/server/storage/knowledge/财务知识库/远光软件高新技术企业税收优惠政策汇总.pdf - 1779441858 - + 1.0 + Venture capital deduction applies specifically to investments made in unlisted small and medium high-tech enterprises. + investment target,qualifying entity + chunk-93d2389cdb74257e90201dccbc3f6539 + /app/server/storage/knowledge/财务知识库/远光软件高新技术企业税收优惠政策汇总.pdf + 1779441858 + - 1.0 - Venture capital deduction is part of the broader preferential tax policies offered by the government. - policy category,tax incentive - chunk-93d2389cdb74257e90201dccbc3f6539 - /app/server/storage/knowledge/财务知识库/远光软件高新技术企业税收优惠政策汇总.pdf - 1779441858 - + 1.0 + Venture capital deduction is part of the broader preferential tax policies offered by the government. + policy category,tax incentive + chunk-93d2389cdb74257e90201dccbc3f6539 + /app/server/storage/knowledge/财务知识库/远光软件高新技术企业税收优惠政策汇总.pdf + 1779441858 + - 1.0 - The venture capital deduction allows 70% of the investment amount to be deducted from taxable income. - deduction ratio,tax calculation basis - chunk-93d2389cdb74257e90201dccbc3f6539 - /app/server/storage/knowledge/财务知识库/远光软件高新技术企业税收优惠政策汇总.pdf - 1779441858 - + 1.0 + The venture capital deduction allows 70% of the investment amount to be deducted from taxable income. + deduction ratio,tax calculation basis + chunk-93d2389cdb74257e90201dccbc3f6539 + /app/server/storage/knowledge/财务知识库/远光软件高新技术企业税收优惠政策汇总.pdf + 1779441858 + - 1.0 - Taxable Income is calculated by performing tax adjustments according to the provisions of Tax Law. - calculation basis,legal compliance - chunk-bdfd18ae478b23604f1318623e8e9508 - /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf - 1779466422 - + 1.0 + Taxable Income is calculated by performing tax adjustments according to the provisions of Tax Law. + calculation basis,legal compliance + chunk-bdfd18ae478b23604f1318623e8e9508 + /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf + 1779466422 + - 1.0 - Annual Tax Return Form is used to report and calculate the taxable income after adjustments. - reporting,tax calculation - chunk-bdfd18ae478b23604f1318623e8e9508 - /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf - 1779466422 - + 1.0 + Annual Tax Return Form is used to report and calculate the taxable income after adjustments. + reporting,tax calculation + chunk-bdfd18ae478b23604f1318623e8e9508 + /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf + 1779466422 + - 1.0 - 税务专员applies to主管税务机关to procure invoices on behalf of the company. - procurement application,regulatory interaction - chunk-65235351abce326b8aca831b128a96c6 - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466311 - + 1.0 + 税务专员applies to主管税务机关to procure invoices on behalf of the company. + procurement application,regulatory interaction + chunk-65235351abce326b8aca831b128a96c6 + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466311 + - 1.0 - 税务专员from the finance department applies to the competent tax authority to purchase invoices. - administrative process,invoice procurement - chunk-8c48a48e8ce0bfd52d732de60fec82ce - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466312 - + 1.0 + 税务专员from the finance department applies to the competent tax authority to purchase invoices. + administrative process,invoice procurement + chunk-8c48a48e8ce0bfd52d732de60fec82ce + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466312 + - 1.0 - The software product VAT immediate collection and refund policy uses 3% actual tax burden as the threshold - amounts exceeding 3% are refunded to enterprises. - VAT refund calculation,policy threshold - chunk-2c8384b328272063de4dac306a52d21e - /app/server/storage/knowledge/财务知识库/远光软件高新技术企业税收优惠政策汇总.pdf - 1779441857 - + 1.0 + The software product VAT immediate collection and refund policy uses 3% actual tax burden as the threshold - amounts exceeding 3% are refunded to enterprises. + VAT refund calculation,policy threshold + chunk-2c8384b328272063de4dac306a52d21e + /app/server/storage/knowledge/财务知识库/远光软件高新技术企业税收优惠政策汇总.pdf + 1779441857 + - 1.0 - 第五条establishes internal audit and internal control evaluation as a company function. - audit function,control evaluation - chunk-6c549250b13b7728acb37eb6082bc178 - /app/server/storage/knowledge/制度政策/远光软件公司内部控制基本规范.pdf - 1779465701 - + 1.0 + 第五条establishes internal audit and internal control evaluation as a company function. + audit function,control evaluation + chunk-6c549250b13b7728acb37eb6082bc178 + /app/server/storage/knowledge/制度政策/远光软件公司内部控制基本规范.pdf + 1779465701 + - 1.0 - 第六条将房屋及建筑物列为固定资产一类,折旧年限为20年。 - 折旧年限,资产分类 - chunk-4287121b009a169fe4155526bfe413ea - /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf - 1779465897 - + 1.0 + 第六条将房屋及建筑物列为固定资产一类,折旧年限为20年。 + 折旧年限,资产分类 + chunk-4287121b009a169fe4155526bfe413ea + /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf + 1779465897 + - 1.0 - 第六条将机器设备列为固定资产一类,折旧年限为10年。 - 折旧年限,资产分类 - chunk-4287121b009a169fe4155526bfe413ea - /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf - 1779465897 - + 1.0 + 第六条将机器设备列为固定资产一类,折旧年限为10年。 + 折旧年限,资产分类 + chunk-4287121b009a169fe4155526bfe413ea + /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf + 1779465897 + - 1.0 - 第六条将电子设备列为固定资产一类,折旧年限为3年。 - 折旧年限,资产分类 - chunk-4287121b009a169fe4155526bfe413ea - /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf - 1779465898 - + 1.0 + 第六条将电子设备列为固定资产一类,折旧年限为3年。 + 折旧年限,资产分类 + chunk-4287121b009a169fe4155526bfe413ea + /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf + 1779465898 + - 1.0 - 第七条mandates establishing a risk assessment mechanism for identifying and analyzing risks. - risk identification,risk management mechanism - chunk-6c549250b13b7728acb37eb6082bc178 - /app/server/storage/knowledge/制度政策/远光软件公司内部控制基本规范.pdf - 1779465701 - + 1.0 + 第七条mandates establishing a risk assessment mechanism for identifying and analyzing risks. + risk identification,risk management mechanism + chunk-6c549250b13b7728acb37eb6082bc178 + /app/server/storage/knowledge/制度政策/远光软件公司内部控制基本规范.pdf + 1779465701 + - 1.0 - 第七条requires the company to identify and analyze risks in business activities. - risk analysis,risk management - chunk-6c549250b13b7728acb37eb6082bc178 - /app/server/storage/knowledge/制度政策/远光软件公司内部控制基本规范.pdf - 1779465701 - + 1.0 + 第七条requires the company to identify and analyze risks in business activities. + risk analysis,risk management + chunk-6c549250b13b7728acb37eb6082bc178 + /app/server/storage/knowledge/制度政策/远光软件公司内部控制基本规范.pdf + 1779465701 + - 1.0 - Tax risk management is covered under Chapter 4, with Article 7 specifically addressing tax dispute procedures. - chapter-article relationship,policy structure - chunk-7dbbc500ab3d85025ed0a40708c3585f - /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx - 1779466505 - + 1.0 + Tax risk management is covered under Chapter 4, with Article 7 specifically addressing tax dispute procedures. + chapter-article relationship,policy structure + chunk-7dbbc500ab3d85025ed0a40708c3585f + /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx + 1779466505 + - 1.0 - Article 7 is a specific provision within the overall tax management policy document. - policy authority,procedural rule - chunk-7dbbc500ab3d85025ed0a40708c3585f - /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx - 1779466505 - + 1.0 + Article 7 is a specific provision within the overall tax management policy document. + policy authority,procedural rule + chunk-7dbbc500ab3d85025ed0a40708c3585f + /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx + 1779466505 + - 1.0 - 第九条requires the company to establish and improve various internal control systems. - control framework,system establishment - chunk-6c549250b13b7728acb37eb6082bc178 - /app/server/storage/knowledge/制度政策/远光软件公司内部控制基本规范.pdf - 1779465701 - + 1.0 + 第九条requires the company to establish and improve various internal control systems. + control framework,system establishment + chunk-6c549250b13b7728acb37eb6082bc178 + /app/server/storage/knowledge/制度政策/远光软件公司内部控制基本规范.pdf + 1779465701 + - 1.0 - 董事会provides the final approval for the budget during the budget preparation schedule. - approval,final authorization - chunk-6493ba2ae9f87d70ec970b53687e2557 - /app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf - 1779467008 - + 1.0 + 董事会provides the final approval for the budget during the budget preparation schedule. + approval,final authorization + chunk-6493ba2ae9f87d70ec970b53687e2557 + /app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf + 1779467008 + - 2.0 - 财务部exercises unified management over all units' financial personnel through unified management, assignment, or registration.<SEP>财务部exercises unified management over all units including headquarters, branches, and subsidiaries through centralized approval and personnel administration. - administrative management,governance,management authority,unified oversight - chunk-bb483fb199b8a72b369d87b3fa319ac3<SEP>chunk-9734bc0dd5225675ba6907f874a807ce - /app/server/storage/knowledge/制度政策/远光软件公司财务管理制度总则.docx - 1779465826 - + 2.0 + 财务部exercises unified management over all units' financial personnel through unified management, assignment, or registration.<SEP>财务部exercises unified management over all units including headquarters, branches, and subsidiaries through centralized approval and personnel administration. + administrative management,governance,management authority,unified oversight + chunk-bb483fb199b8a72b369d87b3fa319ac3<SEP>chunk-9734bc0dd5225675ba6907f874a807ce + /app/server/storage/knowledge/制度政策/远光软件公司财务管理制度总则.docx + 1779465826 + - 1.0 - 财务部holds the authority and responsibility to approve and manage bank accounts for all units. - centralized control,financial management - chunk-9734bc0dd5225675ba6907f874a807ce - /app/server/storage/knowledge/制度政策/远光软件公司财务管理制度总则.docx - 1779465826 - + 1.0 + 财务部holds the authority and responsibility to approve and manage bank accounts for all units. + centralized control,financial management + chunk-9734bc0dd5225675ba6907f874a807ce + /app/server/storage/knowledge/制度政策/远光软件公司财务管理制度总则.docx + 1779465826 + - 1.0 - 财务部audits travel reimbursement requests to ensure proper documentation and compliance with company policies. - compliance review,financial audit - chunk-85ebe3a7090c0f5408b34e92c2384b1a - /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf - 1779466042 - + 1.0 + 财务部audits travel reimbursement requests to ensure proper documentation and compliance with company policies. + compliance review,financial audit + chunk-85ebe3a7090c0f5408b34e92c2384b1a + /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf + 1779466042 + - 1.0 - 财务部and国际业务部jointly interpret this regulation. - departmental collaboration,joint interpretation - chunk-70109ec1883be48ac9fecfe9cb6c7a3e - /app/server/storage/knowledge/差旅规范/远光软件国际出差管理规定.docx - 1779466081 - + 1.0 + 财务部and国际业务部jointly interpret this regulation. + departmental collaboration,joint interpretation + chunk-70109ec1883be48ac9fecfe9cb6c7a3e + /app/server/storage/knowledge/差旅规范/远光软件国际出差管理规定.docx + 1779466081 + - 2.0 - 财务部is responsible for establishing duplicate invoice checking mechanisms for electronic invoices.<SEP>财务部is responsible for managing the receipt, duplicate checking, and archiving of electronic invoices. - archival responsibility,compliance oversight,management oversight,management responsibility - chunk-8c48a48e8ce0bfd52d732de60fec82ce<SEP>chunk-4f26391db1f914c1dbf43241f51b8d4e - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx<SEP>/app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466408 - + 2.0 + 财务部is responsible for establishing duplicate invoice checking mechanisms for electronic invoices.<SEP>财务部is responsible for managing the receipt, duplicate checking, and archiving of electronic invoices. + archival responsibility,compliance oversight,management oversight,management responsibility + chunk-8c48a48e8ce0bfd52d732de60fec82ce<SEP>chunk-4f26391db1f914c1dbf43241f51b8d4e + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx<SEP>/app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466408 + - 1.0 - 财务部oversees the proper use of the invoice special seal during invoice issuance. - issuance oversight,management responsibility - chunk-8c48a48e8ce0bfd52d732de60fec82ce - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466312 - + 1.0 + 财务部oversees the proper use of the invoice special seal during invoice issuance. + issuance oversight,management responsibility + chunk-8c48a48e8ce0bfd52d732de60fec82ce + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466312 + - 1.0 - 财务部verifies deduction linkage information for VAT special invoices during acquisition. - regulatory compliance,verification responsibility - chunk-8c48a48e8ce0bfd52d732de60fec82ce - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466313 - + 1.0 + 财务部verifies deduction linkage information for VAT special invoices during acquisition. + regulatory compliance,verification responsibility + chunk-8c48a48e8ce0bfd52d732de60fec82ce + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466313 + - 1.0 - The finance department verifies that company employees properly acquire invoices for official business expenses. - compliance oversight,expense verification - chunk-8c48a48e8ce0bfd52d732de60fec82ce - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466313 - + 1.0 + The finance department verifies that company employees properly acquire invoices for official business expenses. + compliance oversight,expense verification + chunk-8c48a48e8ce0bfd52d732de60fec82ce + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466313 + - 2.0 - 财务部uses the增值税发票综合服务平台to perform invoice selection and confirmation procedures for certification.<SEP>财务部在增值税发票综合服务平台进行发票勾选确认操作。 - invoice processing,tax compliance,发票认证,部门操作 - chunk-12b08b984a30d7e156cf75ac4c79ed0a<SEP>chunk-af51160a1e2350e227249d2eaff8df40 - /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf - 1779466357 - + 2.0 + 财务部uses the增值税发票综合服务平台to perform invoice selection and confirmation procedures for certification.<SEP>财务部在增值税发票综合服务平台进行发票勾选确认操作。 + invoice processing,tax compliance,发票认证,部门操作 + chunk-12b08b984a30d7e156cf75ac4c79ed0a<SEP>chunk-af51160a1e2350e227249d2eaff8df40 + /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf + 1779466357 + - 1.0 - 财务部在发票认证通过后在当月增值税申报中进行抵扣操作。 - 发票认证,税务处理 - chunk-12b08b984a30d7e156cf75ac4c79ed0a - /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf - 1779466342 - + 1.0 + 财务部在发票认证通过后在当月增值税申报中进行抵扣操作。 + 发票认证,税务处理 + chunk-12b08b984a30d7e156cf75ac4c79ed0a + /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf + 1779466342 + - 2.0 - 财务部在增值税发票综合服务平台进行勾选确认,按流程完成发票认证。<SEP>财务部负责执行发票认证流程中的勾选确认、抵扣及发票处理工作。 - 流程执行,部门操作,部门职责 - chunk-12b08b984a30d7e156cf75ac4c79ed0a - /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf - 1779466342 - + 2.0 + 财务部在增值税发票综合服务平台进行勾选确认,按流程完成发票认证。<SEP>财务部负责执行发票认证流程中的勾选确认、抵扣及发票处理工作。 + 流程执行,部门操作,部门职责 + chunk-12b08b984a30d7e156cf75ac4c79ed0a + /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf + 1779466342 + - 1.0 - Special invoices must be submitted to财务部within 5 working days of receipt. - deadline requirement,internal process - chunk-af51160a1e2350e227249d2eaff8df40 - /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf - 1779466343 - + 1.0 + Special invoices must be submitted to财务部within 5 working days of receipt. + deadline requirement,internal process + chunk-af51160a1e2350e227249d2eaff8df40 + /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf + 1779466343 + - 1.0 - 财务部establishes the electronic invoice duplicate checking mechanism and enforces compliance with reimbursement regulations. - compliance enforcement,mechanism establishment - chunk-4f26391db1f914c1dbf43241f51b8d4e - /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466407 - + 1.0 + 财务部establishes the electronic invoice duplicate checking mechanism and enforces compliance with reimbursement regulations. + compliance enforcement,mechanism establishment + chunk-4f26391db1f914c1dbf43241f51b8d4e + /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466407 + - 1.0 - 财务部is responsible for interpreting and overseeing the implementation of the电子发票管理办法. - interpretation authority,policy responsibility - chunk-4f26391db1f914c1dbf43241f51b8d4e - /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466393 - + 1.0 + 财务部is responsible for interpreting and overseeing the implementation of the电子发票管理办法. + interpretation authority,policy responsibility + chunk-4f26391db1f914c1dbf43241f51b8d4e + /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466393 + - 1.0 - 第三章电子发票的查重assigns the finance department to establish duplicate checking mechanisms. - duplicate checking,mechanism responsibility - chunk-4f26391db1f914c1dbf43241f51b8d4e - /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466393 - + 1.0 + 第三章电子发票的查重assigns the finance department to establish duplicate checking mechanisms. + duplicate checking,mechanism responsibility + chunk-4f26391db1f914c1dbf43241f51b8d4e + /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466393 + - 1.0 - 财务部is the department responsible for executing tax management responsibilities. - duty execution,organizational responsibility - chunk-f61c91e28e8d0f773f83e3daf161ab1c - /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx - 1779466505 - + 1.0 + 财务部is the department responsible for executing tax management responsibilities. + duty execution,organizational responsibility + chunk-f61c91e28e8d0f773f83e3daf161ab1c + /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx + 1779466505 + - 1.0 - The Tax Management System assigns implementation responsibility to the Finance Department for interpretation and revision. - implementation responsibility,organizational assignment - chunk-f61c91e28e8d0f773f83e3daf161ab1c - /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx - 1779466505 - + 1.0 + The Tax Management System assigns implementation responsibility to the Finance Department for interpretation and revision. + implementation responsibility,organizational assignment + chunk-f61c91e28e8d0f773f83e3daf161ab1c + /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx + 1779466505 + - 1.0 - 财务部organizes budget training, distributes templates, consolidates and reviews budget drafts, and coordinates with departments during the budget preparation schedule. - coordination,organizing - chunk-6493ba2ae9f87d70ec970b53687e2557 - /app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf - 1779467008 - + 1.0 + 财务部organizes budget training, distributes templates, consolidates and reviews budget drafts, and coordinates with departments during the budget preparation schedule. + coordination,organizing + chunk-6493ba2ae9f87d70ec970b53687e2557 + /app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf + 1779467008 + - 1.0 - 财务部organizes the budget preparation training session for staff. - organizing,training - chunk-6493ba2ae9f87d70ec970b53687e2557 - /app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf - 1779467008 - + 1.0 + 财务部organizes the budget preparation training session for staff. + organizing,training + chunk-6493ba2ae9f87d70ec970b53687e2557 + /app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf + 1779467008 + - 1.0 - 财务部distributes the budget preparation templates to departments. - distribution,preparation support - chunk-6493ba2ae9f87d70ec970b53687e2557 - /app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf - 1779467008 - + 1.0 + 财务部distributes the budget preparation templates to departments. + distribution,preparation support + chunk-6493ba2ae9f87d70ec970b53687e2557 + /app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf + 1779467008 + - 1.0 - 财务部is responsible for preparing documents using the预算执行分析报告模板. - department responsibility,document preparation - chunk-b844601174a058e8fbad0ea235898bd4 - /app/server/storage/knowledge/预算管理/远光软件预算执行分析报告模板.docx - 1779467060 - + 1.0 + 财务部is responsible for preparing documents using the预算执行分析报告模板. + department responsibility,document preparation + chunk-b844601174a058e8fbad0ea235898bd4 + /app/server/storage/knowledge/预算管理/远光软件预算执行分析报告模板.docx + 1779467060 + - 1.0 - Contracts exceeding 500,000 yuan (重大合同) must be cosigned by财务部. - approval requirement,financial oversight - chunk-6175768b05adf2e7229c16f13ee7cffd - /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf - 1779467718 - + 1.0 + Contracts exceeding 500,000 yuan (重大合同) must be cosigned by财务部. + approval requirement,financial oversight + chunk-6175768b05adf2e7229c16f13ee7cffd + /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf + 1779467718 + - 1.0 - After risk assessment, the company determines response strategies to address identified risks. - risk management,strategic response - chunk-6c549250b13b7728acb37eb6082bc178 - /app/server/storage/knowledge/制度政策/远光软件公司内部控制基本规范.pdf - 1779465701 - + 1.0 + After risk assessment, the company determines response strategies to address identified risks. + risk management,strategic response + chunk-6c549250b13b7728acb37eb6082bc178 + /app/server/storage/knowledge/制度政策/远光软件公司内部控制基本规范.pdf + 1779465701 + - 1.0 - The contract management system applies to远光软件股份有限公司and all its branches and subsidiaries. - organizational coverage,scope of application - chunk-1f813062c109d781d9d684a4d23bfe1e - /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx - 1779465763 - + 1.0 + The contract management system applies to远光软件股份有限公司and all its branches and subsidiaries. + organizational coverage,scope of application + chunk-1f813062c109d781d9d684a4d23bfe1e + /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx + 1779465763 + - 1.0 - The invoice management standards apply to远光软件股份有限公司and its分、子公司. - policy application,regulatory scope - chunk-65235351abce326b8aca831b128a96c6 - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466312 - + 1.0 + The invoice management standards apply to远光软件股份有限公司and its分、子公司. + policy application,regulatory scope + chunk-65235351abce326b8aca831b128a96c6 + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466312 + - 1.0 - The contract management system is formulated according to 《中华人民共和国民法典》 and related laws and regulations. - legal basis,regulatory framework - chunk-1f813062c109d781d9d684a4d23bfe1e - /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx - 1779465763 - + 1.0 + The contract management system is formulated according to 《中华人民共和国民法典》 and related laws and regulations. + legal basis,regulatory framework + chunk-1f813062c109d781d9d684a4d23bfe1e + /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx + 1779465763 + - 1.0 - The contract management system applies to various contracts signed between the company and external parties. - contractual relationship,scope of application - chunk-1f813062c109d781d9d684a4d23bfe1e - /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx - 1779465764 - + 1.0 + The contract management system applies to various contracts signed between the company and external parties. + contractual relationship,scope of application + chunk-1f813062c109d781d9d684a4d23bfe1e + /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx + 1779465764 + - 1.0 - 公司法务部reviews all contracts before they - compliance approval,legal review - chunk-1f813062c109d781d9d684a4d23bfe1e - /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx - 1779465763 - + 1.0 + 公司法务部reviews all contracts before they + compliance approval,legal review + chunk-1f813062c109d781d9d684a4d23bfe1e + /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx + 1779465763 + - 1.0 - 业务部门conducts credit investigations to understand counterparty qualifications before signing contracts. - due diligence,risk prevention - chunk-1f813062c109d781d9d684a4d23bfe1e - /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx - 1779465763 - + 1.0 + 业务部门conducts credit investigations to understand counterparty qualifications before signing contracts. + due diligence,risk prevention + chunk-1f813062c109d781d9d684a4d23bfe1e + /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx + 1779465763 + - 1.0 - 董事长has approval authority for contracts of 2,000,000 yuan or above. - approval authority,contract approval - chunk-1f813062c109d781d9d684a4d23bfe1e - /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx - 1779465763 - + 1.0 + 董事长has approval authority for contracts of 2,000,000 yuan or above. + approval authority,contract approval + chunk-1f813062c109d781d9d684a4d23bfe1e + /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx + 1779465763 + - 1.0 - 总经理has approval authority for contracts between 500,000 and 2,000,000 yuan. - approval authority,contract approval - chunk-1f813062c109d781d9d684a4d23bfe1e - /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx - 1779465763 - + 1.0 + 总经理has approval authority for contracts between 500,000 and 2,000,000 yuan. + approval authority,contract approval + chunk-1f813062c109d781d9d684a4d23bfe1e + /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx + 1779465763 + - 1.0 - 出国(境)出差申请must be approved by总经理. - approval authority,organizational hierarchy - chunk-70109ec1883be48ac9fecfe9cb6c7a3e - /app/server/storage/knowledge/差旅规范/远光软件国际出差管理规定.docx - 1779466081 - + 1.0 + 出国(境)出差申请must be approved by总经理. + approval authority,organizational hierarchy + chunk-70109ec1883be48ac9fecfe9cb6c7a3e + /app/server/storage/knowledge/差旅规范/远光软件国际出差管理规定.docx + 1779466081 + - 1.0 - 分管副总has approval authority for contracts between 100,000 and 500,000 yuan. - approval authority,contract approval - chunk-1f813062c109d781d9d684a4d23bfe1e - /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx - 1779465763 - + 1.0 + 分管副总has approval authority for contracts between 100,000 and 500,000 yuan. + approval authority,contract approval + chunk-1f813062c109d781d9d684a4d23bfe1e + /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx + 1779465763 + - 1.0 - 分管副总对出差申请具有审批权限。 - 审批权限,层级管理 - chunk-589aae03864f03017b4a61f95c13b5e1 - /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx - 1779466007 - + 1.0 + 分管副总对出差申请具有审批权限。 + 审批权限,层级管理 + chunk-589aae03864f03017b4a61f95c13b5e1 + /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx + 1779466007 + - 1.0 - Contracts are managed through hierarchical approval based on contract amount thresholds. - approval hierarchy,contract金额分级 - chunk-1f813062c109d781d9d684a4d23bfe1e - /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx - 1779465763 - + 1.0 + Contracts are managed through hierarchical approval based on contract amount thresholds. + approval hierarchy,contract金额分级 + chunk-1f813062c109d781d9d684a4d23bfe1e + /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx + 1779465763 + - 1.0 - Fund payments must be processed according to established approval procedures and workflows. - operational procedure,process compliance - chunk-9734bc0dd5225675ba6907f874a807ce - /app/server/storage/knowledge/制度政策/远光软件公司财务管理制度总则.docx - 1779465826 - + 1.0 + Fund payments must be processed according to established approval procedures and workflows. + operational procedure,process compliance + chunk-9734bc0dd5225675ba6907f874a807ce + /app/server/storage/knowledge/制度政策/远光软件公司财务管理制度总则.docx + 1779465826 + - 1.0 - 出纳processes the final payment as the last step in the审批流程after all approvals are completed. - final step,payment processing - chunk-85ebe3a7090c0f5408b34e92c2384b1a - /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf - 1779466042 - + 1.0 + 出纳processes the final payment as the last step in the审批流程after all approvals are completed. + final step,payment processing + chunk-85ebe3a7090c0f5408b34e92c2384b1a + /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf + 1779466042 + - 1.0 - Contract Approval Authority is a key section within Contract Management Principles establishing the approval authority framework. - hierarchy,policy framework - chunk-f7fd90e245185f1d10c4d35de739bb44 - /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx - 1779465763 - + 1.0 + Contract Approval Authority is a key section within Contract Management Principles establishing the approval authority framework. + hierarchy,policy framework + chunk-f7fd90e245185f1d10c4d35de739bb44 + /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx + 1779465763 + - 1.0 - Credit Investigation is mandated by Article 6 as part of Contract Management Principles before contract signing. - due diligence,procedural requirement - chunk-f7fd90e245185f1d10c4d35de739bb44 - /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx - 1779465764 - + 1.0 + Credit Investigation is mandated by Article 6 as part of Contract Management Principles before contract signing. + due diligence,procedural requirement + chunk-f7fd90e245185f1d10c4d35de739bb44 + /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx + 1779465764 + - 1.0 - Legal Department Review is a core policy requirement specified in Contract Management Principles for all contracts. - governance policy,quality control - chunk-f7fd90e245185f1d10c4d35de739bb44 - /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx - 1779465764 - + 1.0 + Legal Department Review is a core policy requirement specified in Contract Management Principles for all contracts. + governance policy,quality control + chunk-f7fd90e245185f1d10c4d35de739bb44 + /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx + 1779465764 + - 1.0 - Contract Tracking is established as a policy requirement in Contract Management Principles after contract signing. - operational policy,performance monitoring - chunk-f7fd90e245185f1d10c4d35de739bb44 - /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx - 1779465780 - + 1.0 + Contract Tracking is established as a policy requirement in Contract Management Principles after contract signing. + operational policy,performance monitoring + chunk-f7fd90e245185f1d10c4d35de739bb44 + /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx + 1779465780 + - 1.0 - Contracts Below 100,000 Yuan fall under the approval authority established by Article 4. - approval threshold,hierarchical management - chunk-f7fd90e245185f1d10c4d35de739bb44 - /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx - 1779465764 - + 1.0 + Contracts Below 100,000 Yuan fall under the approval authority established by Article 4. + approval threshold,hierarchical management + chunk-f7fd90e245185f1d10c4d35de739bb44 + /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx + 1779465764 + - 1.0 - Contracts Between 100,000-500,000 Yuan fall under the approval authority established by Article 4. - approval threshold,hierarchical management - chunk-f7fd90e245185f1d10c4d35de739bb44 - /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx - 1779465764 - + 1.0 + Contracts Between 100,000-500,000 Yuan fall under the approval authority established by Article 4. + approval threshold,hierarchical management + chunk-f7fd90e245185f1d10c4d35de739bb44 + /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx + 1779465764 + - 1.0 - Contracts Between 500,000-2,000,000 Yuan fall under the approval authority established by Article - approval threshold,hierarchical management - chunk-f7fd90e245185f1d10c4d35de739bb44 - /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx - 1779465780 - + 1.0 + Contracts Between 500,000-2,000,000 Yuan fall under the approval authority established by Article + approval threshold,hierarchical management + chunk-f7fd90e245185f1d10c4d35de739bb44 + /app/server/storage/knowledge/制度政策/远光软件公司合同管理制度.docx + 1779465780 + - 1.0 - Article 7 establishes compliance requirements for electronic invoice archiving in relation to national standards and the archive system. - archival standards,compliance requirements - chunk-34116b8b9f61b21eaacb3b4c95f20122 - /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466393 - + 1.0 + Article 7 establishes compliance requirements for electronic invoice archiving in relation to national standards and the archive system. + archival standards,compliance requirements + chunk-34116b8b9f61b21eaacb3b4c95f20122 + /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466393 + - 1.0 - Article 7 and Article 8 together establish the framework for electronic invoice archiving, with Article 7 setting requirements and Article 8 detailing storage procedures. - archival framework,procedural sequence - chunk-34116b8b9f61b21eaacb3b4c95f20122 - /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466394 - + 1.0 + Article 7 and Article 8 together establish the framework for electronic invoice archiving, with Article 7 setting requirements and Article 8 detailing storage procedures. + archival framework,procedural sequence + chunk-34116b8b9f61b21eaacb3b4c95f20122 + /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466394 + - 1.0 - Article 7 mandates that electronic invoice archiving must comply with National Archive Management Regulations. - legal framework,regulatory compliance - chunk-34116b8b9f61b21eaacb3b4c95f20122 - /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466395 - + 1.0 + Article 7 mandates that electronic invoice archiving must comply with National Archive Management Regulations. + legal framework,regulatory compliance + chunk-34116b8b9f61b21eaacb3b4c95f20122 + /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466395 + - 1.0 - Article 8 specifies the storage of electronic invoices within the Electronic Archive System. - archiving procedures,data storage - chunk-34116b8b9f61b21eaacb3b4c95f20122 - /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466394 - + 1.0 + Article 8 specifies the storage of electronic invoices within the Electronic Archive System. + archiving procedures,data storage + chunk-34116b8b9f61b21eaacb3b4c95f20122 + /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466394 + - 1.0 - Article 8 falls under Chapter 4 Electronic Invoice Archiving, establishing storage procedures for electronic invoices. - chapter authority,document structure - chunk-34116b8b9f61b21eaacb3b4c95f20122 - /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466395 - + 1.0 + Article 8 falls under Chapter 4 Electronic Invoice Archiving, establishing storage procedures for electronic invoices. + chapter authority,document structure + chunk-34116b8b9f61b21eaacb3b4c95f20122 + /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466395 + - 1.0 - Article 9 designates the Company Finance Department as responsible for interpreting the management method. - interpretive authority,organizational responsibility - chunk-34116b8b9f61b21eaacb3b4c95f20122 - /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466394 - + 1.0 + Article 9 designates the Company Finance Department as responsible for interpreting the management method. + interpretive authority,organizational responsibility + chunk-34116b8b9f61b21eaacb3b4c95f20122 + /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466394 + - 1.0 - Article 9 is part of Chapter 5 Supplementary Provisions, defining the finance department's interpretive role. - document structure,interpretive authority - chunk-34116b8b9f61b21eaacb3b4c95f20122 - /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466394 - + 1.0 + Article 9 is part of Chapter 5 Supplementary Provisions, defining the finance department's interpretive role. + document structure,interpretive authority + chunk-34116b8b9f61b21eaacb3b4c95f20122 + /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466394 + - 1.0 - The financial management system is formulated based on中华人民共和国会计法as its legal foundation - legal basis,regulatory compliance - chunk-bb483fb199b8a72b369d87b3fa319ac3 - /app/server/storage/knowledge/制度政策/远光软件公司财务管理制度总则.docx - 1779465826 - + 1.0 + The financial management system is formulated based on中华人民共和国会计法as its legal foundation + legal basis,regulatory compliance + chunk-bb483fb199b8a72b369d87b3fa319ac3 + /app/server/storage/knowledge/制度政策/远光软件公司财务管理制度总则.docx + 1779465826 + - 1.0 - Fund payments must follow the hierarchical approval system to ensure proper authorization at each level. - financial authorization,procedural requirement - chunk-9734bc0dd5225675ba6907f874a807ce - /app/server/storage/knowledge/制度政策/远光软件公司财务管理制度总则.docx - 1779465826 - + 1.0 + Fund payments must follow the hierarchical approval system to ensure proper authorization at each level. + financial authorization,procedural requirement + chunk-9734bc0dd5225675ba6907f874a807ce + /app/server/storage/knowledge/制度政策/远光软件公司财务管理制度总则.docx + 1779465826 + - 1.0 - 财务共享服务中心provides standardized financial services to the company headquarters. - financial support,service provision - chunk-3b77f7e8beca3e7d537d0623f97473ee - /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx - 1779467178 - + 1.0 + 财务共享服务中心provides standardized financial services to the company headquarters. + financial support,service provision + chunk-3b77f7e8beca3e7d537d0623f97473ee + /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx + 1779467178 + - 1.0 - 专利权is a component of无形资产as defined in the asset management system. - intangible asset composition,intellectual property - chunk-4e95fc3e38b2bf65fcb3f6f0664fd9df - /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf - 1779465896 - + 1.0 + 专利权is a component of无形资产as defined in the asset management system. + intangible asset composition,intellectual property + chunk-4e95fc3e38b2bf65fcb3f6f0664fd9df + /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf + 1779465896 + - 1.0 - 商标权is a component of无形资产as defined in the asset management system. - intangible asset composition,intellectual property - chunk-4e95fc3e38b2bf65fcb3f6f0664fd9df - /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf - 1779465897 - + 1.0 + 商标权is a component of无形资产as defined in the asset management system. + intangible asset composition,intellectual property + chunk-4e95fc3e38b2bf65fcb3f6f0664fd9df + /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf + 1779465897 + - 1.0 - 著作权is a component of无形资产as defined in the asset management system. - intangible asset composition,intellectual property - chunk-4e95fc3e38b2bf65fcb3f6f0664fd9df - /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf - 1779465897 - + 1.0 + 著作权is a component of无形资产as defined in the asset management system. + intangible asset composition,intellectual property + chunk-4e95fc3e38b2bf65fcb3f6f0664fd9df + /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf + 1779465897 + - 1.0 - 土地使用权is a component of无形资产as defined in the asset management system. - intangible asset composition,property rights - chunk-4e95fc3e38b2bf65fcb3f6f0664fd9df - /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf - 1779465898 - + 1.0 + 土地使用权is a component of无形资产as defined in the asset management system. + intangible asset composition,property rights + chunk-4e95fc3e38b2bf65fcb3f6f0664fd9df + /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf + 1779465898 + - 1.0 - 软件使用权is a component of无形资产as defined in the asset management system. - intangible asset composition,software rights - chunk-4e95fc3e38b2bf65fcb3f6f0664fd9df - /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf - 1779465898 - + 1.0 + 软件使用权is a component of无形资产as defined in the asset management system. + intangible asset composition,software rights + chunk-4e95fc3e38b2bf65fcb3f6f0664fd9df + /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf + 1779465898 + - 1.0 - 资产盘盈requires investigation and accounting treatment following approval procedures. - accounting procedure,inventory adjustment - chunk-4e95fc3e38b2bf65fcb3f6f0664fd9df - /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf - 1779465896 - + 1.0 + 资产盘盈requires investigation and accounting treatment following approval procedures. + accounting procedure,inventory adjustment + chunk-4e95fc3e38b2bf65fcb3f6f0664fd9df + /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf + 1779465896 + - 1.0 - 资产盘亏requires investigation and accounting treatment following approval procedures. - accounting procedure,inventory adjustment - chunk-4e95fc3e38b2bf65fcb3f6f0664fd9df - /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf - 1779465897 - + 1.0 + 资产盘亏requires investigation and accounting treatment following approval procedures. + accounting procedure,inventory adjustment + chunk-4e95fc3e38b2bf65fcb3f6f0664fd9df + /app/server/storage/knowledge/制度政策/远光软件公司资产管理制度.pdf + 1779465897 + - 1.0 - 公司财务部负责解释本办法,具有最终解释权。 - 制度解释,管理职责 - chunk-589aae03864f03017b4a61f95c13b5e1 - /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx - 1779466006 - + 1.0 + 公司财务部负责解释本办法,具有最终解释权。 + 制度解释,管理职责 + chunk-589aae03864f03017b4a61f95c13b5e1 + /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx + 1779466006 + - 1.0 - 公司财务部负责按国家外汇管理规定统一办理购汇手续。 - 外汇管理,财务职责 - chunk-9914d9020029547d965dbc105f824b74 - /app/server/storage/knowledge/差旅规范/远光软件国际出差管理规定.docx - 1779466081 - + 1.0 + 公司财务部负责按国家外汇管理规定统一办理购汇手续。 + 外汇管理,财务职责 + chunk-9914d9020029547d965dbc105f824b74 + /app/server/storage/knowledge/差旅规范/远光软件国际出差管理规定.docx + 1779466081 + - 1.0 - 公司财务部负责办理外汇核销手续,出差人员需在返回后10个工作日内完成。 - 外汇管理,财务职责 - chunk-9914d9020029547d965dbc105f824b74 - /app/server/storage/knowledge/差旅规范/远光软件国际出差管理规定.docx - 1779466081 - + 1.0 + 公司财务部负责办理外汇核销手续,出差人员需在返回后10个工作日内完成。 + 外汇管理,财务职责 + chunk-9914d9020029547d965dbc105f824b74 + /app/server/storage/knowledge/差旅规范/远光软件国际出差管理规定.docx + 1779466081 + - 1.0 - 本规定由公司财务部和国际业务部共同解释。 - 规定解释,部门合作 - chunk-9914d9020029547d965dbc105f824b74 - /app/server/storage/knowledge/差旅规范/远光软件国际出差管理规定.docx - 1779466081 - + 1.0 + 本规定由公司财务部和国际业务部共同解释。 + 规定解释,部门合作 + chunk-9914d9020029547d965dbc105f824b74 + /app/server/storage/knowledge/差旅规范/远光软件国际出差管理规定.docx + 1779466081 + - 1.0 - 公司财务部is responsible for interpreting and revising the invoice management standards. - administrative implementation,policy enforcement - chunk-65235351abce326b8aca831b128a96c6 - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466311 - + 1.0 + 公司财务部is responsible for interpreting and revising the invoice management standards. + administrative implementation,policy enforcement + chunk-65235351abce326b8aca831b128a96c6 + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466311 + - 1.0 - 税务专员is designated by公司财务部to handle invoice procurement with the tax authority. - role assignment,tax operations - chunk-65235351abce326b8aca831b128a96c6 - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466312 - + 1.0 + 税务专员is designated by公司财务部to handle invoice procurement with the tax authority. + role assignment,tax operations + chunk-65235351abce326b8aca831b128a96c6 + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466312 + - 1.0 - 发票管理人员are assigned by公司财务部to manage and preserve invoices. - custodial role,personnel management - chunk-65235351abce326b8aca831b128a96c6 - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466312 - + 1.0 + 发票管理人员are assigned by公司财务部to manage and preserve invoices. + custodial role,personnel management + chunk-65235351abce326b8aca831b128a96c6 + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466312 + - 1.0 - 财务部门is part of or functions under公司财务部, handling reimbursement reviews and invoice verification. - operational function,organizational unit - chunk-65235351abce326b8aca831b128a96c6 - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466312 - + 1.0 + 财务部门is part of or functions under公司财务部, handling reimbursement reviews and invoice verification. + operational function,organizational unit + chunk-65235351abce326b8aca831b128a96c6 + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466312 + - 1.0 - The Finance Department oversees the tax risk management chapter and is responsible for interpreting the policy. - document interpretation,policy governance - chunk-7dbbc500ab3d85025ed0a40708c3585f - /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx - 1779466504 - + 1.0 + The Finance Department oversees the tax risk management chapter and is responsible for interpreting the policy. + document interpretation,policy governance + chunk-7dbbc500ab3d85025ed0a40708c3585f + /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx + 1779466504 + - 1.0 - The Finance Department is responsible for interpreting and revising the supplementary provisions. - policy interpretation,responsibility - chunk-7dbbc500ab3d85025ed0a40708c3585f - /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx - 1779466505 - + 1.0 + The Finance Department is responsible for interpreting and revising the supplementary provisions. + policy interpretation,responsibility + chunk-7dbbc500ab3d85025ed0a40708c3585f + /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx + 1779466505 + - 1.0 - 公司财务部is responsible for interpreting and overseeing the management measures for the shared service center. - management oversight,policy interpretation - chunk-3b77f7e8beca3e7d537d0623f97473ee - /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx - 1779467163 - + 1.0 + 公司财务部is responsible for interpreting and overseeing the management measures for the shared service center. + management oversight,policy interpretation + chunk-3b77f7e8beca3e7d537d0623f97473ee + /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx + 1779467163 + - 1.0 - The procurement approval process applies to procurement amounts between 10,000 and 50,000 yuan. - approval hierarchy,procurement threshold - chunk-0f617968c59d049fd95d0d6325bc5c6c - /app/server/storage/knowledge/制度政策/远光软件公司采购管理办法.xlsx - 1779465966 - + 1.0 + The procurement approval process applies to procurement amounts between 10,000 and 50,000 yuan. + approval hierarchy,procurement threshold + chunk-0f617968c59d049fd95d0d6325bc5c6c + /app/server/storage/knowledge/制度政策/远光软件公司采购管理办法.xlsx + 1779465966 + - 1.0 - The procurement approval process applies to procurement amounts between 50,000 and 200,000 yuan. - approval hierarchy,procurement threshold - chunk-0f617968c59d049fd95d0d6325bc5c6c - /app/server/storage/knowledge/制度政策/远光软件公司采购管理办法.xlsx - 1779465967 - + 1.0 + The procurement approval process applies to procurement amounts between 50,000 and 200,000 yuan. + approval hierarchy,procurement threshold + chunk-0f617968c59d049fd95d0d6325bc5c6c + /app/server/storage/knowledge/制度政策/远光软件公司采购管理办法.xlsx + 1779465967 + - 1.0 - The procurement approval process applies to procurement amounts between 200,000 and 1,000,000 yuan. - approval hierarchy,procurement threshold - chunk-0f617968c59d049fd95d0d6325bc5c6c - /app/server/storage/knowledge/制度政策/远光软件公司采购管理办法.xlsx - 1779465967 - + 1.0 + The procurement approval process applies to procurement amounts between 200,000 and 1,000,000 yuan. + approval hierarchy,procurement threshold + chunk-0f617968c59d049fd95d0d6325bc5c6c + /app/server/storage/knowledge/制度政策/远光软件公司采购管理办法.xlsx + 1779465967 + - 1.0 - The procurement approval process applies to procurement amounts exceeding 1,000,000 yuan. - approval hierarchy,procurement threshold - chunk-0f617968c59d049fd95d0d6325bc5c6c - /app/server/storage/knowledge/制度政策/远光软件公司采购管理办法.xlsx - 1779465967 - + 1.0 + The procurement approval process applies to procurement amounts exceeding 1,000,000 yuan. + approval hierarchy,procurement threshold + chunk-0f617968c59d049fd95d0d6325bc5c6c + /app/server/storage/knowledge/制度政策/远光软件公司采购管理办法.xlsx + 1779465967 + - 1.0 - Yuan Guang Software Co., Ltd. created the Excel Workbook containing procurement management policies. - company document,procurement policy - chunk-96ab661ad24e0cb4c468128a58a76b6d - /app/server/storage/knowledge/制度政策/远光软件公司采购管理办法.xlsx - 1779465966 - + 1.0 + Yuan Guang Software Co., Ltd. created the Excel Workbook containing procurement management policies. + company document,procurement policy + chunk-96ab661ad24e0cb4c468128a58a76b6d + /app/server/storage/knowledge/制度政策/远光软件公司采购管理办法.xlsx + 1779465966 + - 1.0 - The Excel Workbook contains the Procurement Management Methods worksheet with procurement category details. - table structure,worksheet content - chunk-96ab661ad24e0cb4c468128a58a76b6d - /app/server/storage/knowledge/制度政策/远光软件公司采购管理办法.xlsx - 1779465967 - + 1.0 + The Excel Workbook contains the Procurement Management Methods worksheet with procurement category details. + table structure,worksheet content + chunk-96ab661ad24e0cb4c468128a58a76b6d + /app/server/storage/knowledge/制度政策/远光软件公司采购管理办法.xlsx + 1779465967 + - 1.0 - The Excel Workbook contains the Approval Process worksheet with approval procedures. - table structure,worksheet content - chunk-96ab661ad24e0cb4c468128a58a76b6d - /app/server/storage/knowledge/制度政策/远光软件公司采购管理办法.xlsx - 1779465967 - + 1.0 + The Excel Workbook contains the Approval Process worksheet with approval procedures. + table structure,worksheet content + chunk-96ab661ad24e0cb4c468128a58a76b6d + /app/server/storage/knowledge/制度政策/远光软件公司采购管理办法.xlsx + 1779465967 + - 1.0 - Office supplies procurement is a category defined in the Procurement Management Methods. - policy definition,procurement category - chunk-96ab661ad24e0cb4c468128a58a76b6d - /app/server/storage/knowledge/制度政策/远光软件公司采购管理办法.xlsx - 1779465966 - + 1.0 + Office supplies procurement is a category defined in the Procurement Management Methods. + policy definition,procurement category + chunk-96ab661ad24e0cb4c468128a58a76b6d + /app/server/storage/knowledge/制度政策/远光软件公司采购管理办法.xlsx + 1779465966 + - 1.0 - IT equipment and software procurement is a category defined in the Procurement Management Methods. - policy definition,procurement category - chunk-96ab661ad24e0cb4c468128a58a76b6d - /app/server/storage/knowledge/制度政策/远光软件公司采购管理办法.xlsx - 1779465967 - + 1.0 + IT equipment and software procurement is a category defined in the Procurement Management Methods. + policy definition,procurement category + chunk-96ab661ad24e0cb4c468128a58a76b6d + /app/server/storage/knowledge/制度政策/远光软件公司采购管理办法.xlsx + 1779465967 + - 1.0 - 员工因公出差须通过OA系统提交出差申请。 - 流程操作,系统使用 - chunk-589aae03864f03017b4a61f95c13b5e1 - /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx - 1779466008 - + 1.0 + 员工因公出差须通过OA系统提交出差申请。 + 流程操作,系统使用 + chunk-589aae03864f03017b4a61f95c13b5e1 + /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx + 1779466008 + - 1.0 - 本办法依据国家相关规定制定,确保差旅费用管理的合法性。 - 制度依据,合规管理 - chunk-589aae03864f03017b4a61f95c13b5e1 - /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx - 1779466007 - + 1.0 + 本办法依据国家相关规定制定,确保差旅费用管理的合法性。 + 制度依据,合规管理 + chunk-589aae03864f03017b4a61f95c13b5e1 + /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx + 1779466007 + - 1.0 - 本办法依据公司财务管理制度制定,与公司财务管理体系保持一致。 - 制度依据,财务管理 - chunk-589aae03864f03017b4a61f95c13b5e1 - /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx - 1779466007 - + 1.0 + 本办法依据公司财务管理制度制定,与公司财务管理体系保持一致。 + 制度依据,财务管理 + chunk-589aae03864f03017b4a61f95c13b5e1 + /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx + 1779466007 + - 1.0 - 本办法适用于公司全体员工的因公出差费用管理。 - 制度约束,适用范围 - chunk-589aae03864f03017b4a61f95c13b5e1 - /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx - 1779466007 - + 1.0 + 本办法适用于公司全体员工的因公出差费用管理。 + 制度约束,适用范围 + chunk-589aae03864f03017b4a61f95c13b5e1 + /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx + 1779466007 + - 1.0 - 高层管理人员(P8及以上)适用特定的交通费标准。 - 人员分类,标准执行 - chunk-589aae03864f03017b4a61f95c13b5e1 - /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx - 1779466006 - + 1.0 + 高层管理人员(P8及以上)适用特定的交通费标准。 + 人员分类,标准执行 + chunk-589aae03864f03017b4a61f95c13b5e1 + /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx + 1779466006 + - 1.0 - 高层管理人员是指P8及以上级别的管理人员。 - 人员定义,职级划分 - chunk-589aae03864f03017b4a61f95c13b5e1 - /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx - 1779466007 - + 1.0 + 高层管理人员是指P8及以上级别的管理人员。 + 人员定义,职级划分 + chunk-589aae03864f03017b4a61f95c13b5e1 + /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx + 1779466007 + - 1.0 - 中层管理人员适用特定的交通费标准。 - 人员分类,标准执行 - chunk-589aae03864f03017b4a61f95c13b5e1 - /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx - 1779466007 - + 1.0 + 中层管理人员适用特定的交通费标准。 + 人员分类,标准执行 + chunk-589aae03864f03017b4a61f95c13b5e1 + /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx + 1779466007 + - 1.0 - 住宿费标准中的一类城市执行800元/晚的标准。 - 城市分类,费用等级 - chunk-589aae03864f03017b4a61f95c13b5e1 - /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx - 1779466007 - + 1.0 + 住宿费标准中的一类城市执行800元/晚的标准。 + 城市分类,费用等级 + chunk-589aae03864f03017b4a61f95c13b5e1 + /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx + 1779466007 + - 1.0 - 住宿费标准中的二类城市执行700元/晚的标准。 - 城市分类,费用等级 - chunk-589aae03864f03017b4a61f95c13b5e1 - /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx - 1779466007 - + 1.0 + 住宿费标准中的二类城市执行700元/晚的标准。 + 城市分类,费用等级 + chunk-589aae03864f03017b4a61f95c13b5e1 + /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx + 1779466007 + - 1.0 - 住宿费标准中的三类城市执行600元/晚的标准。 - 城市分类,费用等级 - chunk-589aae03864f03017b4a61f95c13b5e1 - /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx - 1779466007 - + 1.0 + 住宿费标准中的三类城市执行600元/晚的标准。 + 城市分类,费用等级 + chunk-589aae03864f03017b4a61f95c13b5e1 + /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx + 1779466007 + - 1.0 - 差旅费标准速查表contains the住宿费标准section specifying accommodation fee limits by city category. - document structure,section inclusion - chunk-f9e0518ef691fb9defdc3af6e1585a0e - /app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx - 1779466162 - + 1.0 + 差旅费标准速查表contains the住宿费标准section specifying accommodation fee limits by city category. + document structure,section inclusion + chunk-f9e0518ef691fb9defdc3af6e1585a0e + /app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx + 1779466162 + - 1.0 - 港澳地区的伙食补贴按伙食补贴标准执行,为200元/天。 - 地区分类,补贴标准 - chunk-589aae03864f03017b4a61f95c13b5e1 - /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx - 1779466007 - + 1.0 + 港澳地区的伙食补贴按伙食补贴标准执行,为200元/天。 + 地区分类,补贴标准 + chunk-589aae03864f03017b4a61f95c13b5e1 + /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx + 1779466007 + - 1.0 - 欧美地区的伙食补贴按伙食补贴标准执行,为400元/天。 - 地区分类,补贴标准 - chunk-589aae03864f03017b4a61f95c13b5e1 - /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx - 1779466007 - + 1.0 + 欧美地区的伙食补贴按伙食补贴标准执行,为400元/天。 + 地区分类,补贴标准 + chunk-589aae03864f03017b4a61f95c13b5e1 + /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx + 1779466007 + - 1.0 - 差旅费标准速查表contains the伙食补贴标准section specifying daily meal allowances. - document structure,section inclusion - chunk-f9e0518ef691fb9defdc3af6e1585a0e - /app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx - 1779466162 - + 1.0 + 差旅费标准速查表contains the伙食补贴标准section specifying daily meal allowances. + document structure,section inclusion + chunk-f9e0518ef691fb9defdc3af6e1585a0e + /app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx + 1779466162 + - 1.0 - 报销手续须在出差返回后5个工作日内完成。 - 时限要求,流程管理 - chunk-589aae03864f03017b4a61f95c13b5e1 - /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx - 1779466007 - + 1.0 + 报销手续须在出差返回后5个工作日内完成。 + 时限要求,流程管理 + chunk-589aae03864f03017b4a61f95c13b5e1 + /app/server/storage/knowledge/差旅规范/远光软件公司差旅费管理办法.docx + 1779466007 + - 1.0 - 上级领导审核出差期间产生的意外费用及相关证明材料 - 审核,费用审批 - chunk-a645037600147280d64fd17543098f51 - /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf - 1779466041 - + 1.0 + 上级领导审核出差期间产生的意外费用及相关证明材料 + 审核,费用审批 + chunk-a645037600147280d64fd17543098f51 + /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf + 1779466041 + - 1.0 - Emergency procurement allows immediate purchase followed by completing procedures within 3 working days. - compliance requirement,procedural exception - chunk-6175768b05adf2e7229c16f13ee7cffd - /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf - 1779467718 - + 1.0 + Emergency procurement allows immediate purchase followed by completing procedures within 3 working days. + compliance requirement,procedural exception + chunk-6175768b05adf2e7229c16f13ee7cffd + /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf + 1779467718 + - 1.0 - 出差期间产生的意外费用需保留相关证明材料以便报销。 - 保留,报销凭证 - chunk-a645037600147280d64fd17543098f51 - /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf - 1779466041 - + 1.0 + 出差期间产生的意外费用需保留相关证明材料以便报销。 + 保留,报销凭证 + chunk-a645037600147280d64fd17543098f51 + /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf + 1779466041 + - 1.0 - 出差报销requires the出差审批单as one of the mandatory supporting documents to complete the reimbursement submission. - document requirement,reimbursement process - chunk-85ebe3a7090c0f5408b34e92c2384b1a - /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf - 1779466042 - + 1.0 + 出差报销requires the出差审批单as one of the mandatory supporting documents to complete the reimbursement submission. + document requirement,reimbursement process + chunk-85ebe3a7090c0f5408b34e92c2384b1a + /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf + 1779466042 + - 1.0 - 出差报销may require其他相关证明材料for verifying unexpected or special expenses incurred during travel. - expense verification,supporting documentation - chunk-85ebe3a7090c0f5408b34e92c2384b1a - /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf - 1779466042 - + 1.0 + 出差报销may require其他相关证明材料for verifying unexpected or special expenses incurred during travel. + expense verification,supporting documentation + chunk-85ebe3a7090c0f5408b34e92c2384b1a + /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf + 1779466042 + - 1.0 - 出纳performs出纳付款as the final step in the reimbursement process after all approvals have been completed. - payment processing,reimbursement completion - chunk-85ebe3a7090c0f5408b34e92c2384b1a - /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf - 1779466042 - + 1.0 + 出纳performs出纳付款as the final step in the reimbursement process after all approvals have been completed. + payment processing,reimbursement completion + chunk-85ebe3a7090c0f5408b34e92c2384b1a + /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf + 1779466042 + - 1.0 - 国内出差has a submission deadline of 3 working days before departure as part of the approval timeline requirements. - application deadline,travel category - chunk-85ebe3a7090c0f5408b34e92c2384b1a - /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf - 1779466042 - + 1.0 + 国内出差has a submission deadline of 3 working days before departure as part of the approval timeline requirements. + application deadline,travel category + chunk-85ebe3a7090c0f5408b34e92c2384b1a + /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf + 1779466042 + - 1.0 - 出国(境)出差has a longer submission deadline of 15 working days before departure to accommodate international travel planning. - application deadline,international travel - chunk-85ebe3a7090c0f5408b34e92c2384b1a - /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf - 1779466042 - + 1.0 + 出国(境)出差has a longer submission deadline of 15 working days before departure to accommodate international travel planning. + application deadline,international travel + chunk-85ebe3a7090c0f5408b34e92c2384b1a + /app/server/storage/knowledge/差旅规范/远光软件出差审批流程说明.pdf + 1779466042 + - 1.0 - 人力资源部uniformly keeps因私护照and港澳通行证for employees. - HR management,document custody - chunk-70109ec1883be48ac9fecfe9cb6c7a3e - /app/server/storage/knowledge/差旅规范/远光软件国际出差管理规定.docx - 1779466081 - + 1.0 + 人力资源部uniformly keeps因私护照and港澳通行证for employees. + HR management,document custody + chunk-70109ec1883be48ac9fecfe9cb6c7a3e + /app/server/storage/knowledge/差旅规范/远光软件国际出差管理规定.docx + 1779466081 + - 1.0 - 人力资源部uniformly keeps因私护照and港澳通行证for employees. - HR management,document custody - chunk-70109ec1883be48ac9fecfe9cb6c7a3e - /app/server/storage/knowledge/差旅规范/远光软件国际出差管理规定.docx - 1779466081 - + 1.0 + 人力资源部uniformly keeps因私护照and港澳通行证for employees. + HR management,document custody + chunk-70109ec1883be48ac9fecfe9cb6c7a3e + /app/server/storage/knowledge/差旅规范/远光软件国际出差管理规定.docx + 1779466081 + - 1.0 - 出国(境)出差申请must be approved by分管副总裁. - approval authority,organizational hierarchy - chunk-70109ec1883be48ac9fecfe9cb6c7a3e - /app/server/storage/knowledge/差旅规范/远光软件国际出差管理规定.docx - 1779466081 - + 1.0 + 出国(境)出差申请must be approved by分管副总裁. + approval authority,organizational hierarchy + chunk-70109ec1883be48ac9fecfe9cb6c7a3e + /app/server/storage/knowledge/差旅规范/远光软件国际出差管理规定.docx + 1779466081 + - 1.0 - 公司领导is entitled to first-class cabin (头等舱) for air travel. - rank privilege,transportation entitlement - chunk-f9e0518ef691fb9defdc3af6e1585a0e - /app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx - 1779466161 - + 1.0 + 公司领导is entitled to first-class cabin (头等舱) for air travel. + rank privilege,transportation entitlement + chunk-f9e0518ef691fb9defdc3af6e1585a0e + /app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx + 1779466161 + - 1.0 - 公司领导is entitled to business-class seats (商务座) for train travel. - rank privilege,transportation entitlement - chunk-f9e0518ef691fb9defdc3af6e1585a0e - /app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx - 1779466161 - + 1.0 + 公司领导is entitled to business-class seats (商务座) for train travel. + rank privilege,transportation entitlement + chunk-f9e0518ef691fb9defdc3af6e1585a0e + /app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx + 1779466161 + - 1.0 - 高层管理人员(P8及以上)is entitled to business - rank privilege,transportation entitlement - chunk-f9e0518ef691fb9defdc3af6e1585a0e - /app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx - 1779466161 - + 1.0 + 高层管理人员(P8及以上)is entitled to business + rank privilege,transportation entitlement + chunk-f9e0518ef691fb9defdc3af6e1585a0e + /app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx + 1779466161 + - 1.0 - 差旅费标准速查表contains the交通工具标准section specifying transportation allowances by personnel category. - document structure,section inclusion - chunk-f9e0518ef691fb9defdc3af6e1585a0e - /app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx - 1779466161 - + 1.0 + 差旅费标准速查表contains the交通工具标准section specifying transportation allowances by personnel category. + document structure,section inclusion + chunk-f9e0518ef691fb9defdc3af6e1585a0e + /app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx + 1779466161 + - 1.0 - 城市分类标准将北京、上海、广州、深圳划分为一类城市,对应最高的差旅费报销标准。 - 地理分布,城市分级 - chunk-5109df8302a1a8dc1d2254955e7e440f - /app/server/storage/knowledge/培训资料/远光软件新员工财务培训课件.pdf - 1779467263 - + 1.0 + 城市分类标准将北京、上海、广州、深圳划分为一类城市,对应最高的差旅费报销标准。 + 地理分布,城市分级 + chunk-5109df8302a1a8dc1d2254955e7e440f + /app/server/storage/knowledge/培训资料/远光软件新员工财务培训课件.pdf + 1779467263 + - 1.0 - 城市分类标准将省会城市及计划单列市划分为二类城市,对应中等差旅费报销标准。 - 地理分布,城市分级 - chunk-5109df8302a1a8dc1d2254955e7e440f - /app/server/storage/knowledge/培训资料/远光软件新员工财务培训课件.pdf - 1779467263 - + 1.0 + 城市分类标准将省会城市及计划单列市划分为二类城市,对应中等差旅费报销标准。 + 地理分布,城市分级 + chunk-5109df8302a1a8dc1d2254955e7e440f + /app/server/storage/knowledge/培训资料/远光软件新员工财务培训课件.pdf + 1779467263 + - 1.0 - 城市分类标准将其他地级市划分为三类城市,对应较低的差旅费报销标准。 - 地理分布,城市分级 - chunk-5109df8302a1a8dc1d2254955e7e440f - /app/server/storage/knowledge/培训资料/远光软件新员工财务培训课件.pdf - 1779467263 - + 1.0 + 城市分类标准将其他地级市划分为三类城市,对应较低的差旅费报销标准。 + 地理分布,城市分级 + chunk-5109df8302a1a8dc1d2254955e7e440f + /app/server/storage/knowledge/培训资料/远光软件新员工财务培训课件.pdf + 1779467263 + - 1.0 - Senior Management P8 and Above are entitled to First Class Cabin travel as part of their executive benefits. - executive privilege,travel allowance - chunk-2eea91fe956cae84935e609164d08d55 - /app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx - 1779466161 - + 1.0 + Senior Management P8 and Above are entitled to First Class Cabin travel as part of their executive benefits. + executive privilege,travel allowance + chunk-2eea91fe956cae84935e609164d08d55 + /app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx + 1779466161 + - 1.0 - Senior Management P8 and Above are entitled to Business Class Seat travel as part of their executive benefits. - executive privilege,travel allowance - chunk-2eea91fe956cae84935e609164d08d55 - /app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx - 1779466162 - + 1.0 + Senior Management P8 and Above are entitled to Business Class Seat travel as part of their executive benefits. + executive privilege,travel allowance + chunk-2eea91fe956cae84935e609164d08d55 + /app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx + 1779466162 + - 1.0 - Senior Management P8 and Above are entitled to First Class Seat travel as part of their executive benefits. - executive privilege,travel allowance - chunk-2eea91fe956cae84935e609164d08d55 - /app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx - 1779466162 - + 1.0 + Senior Management P8 and Above are entitled to First Class Seat travel as part of their executive benefits. + executive privilege,travel allowance + chunk-2eea91fe956cae84935e609164d08d55 + /app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx + 1779466162 + - 1.0 - Senior Management P8 and Above operate under the Reimbursement Of Actual Expenses policy for their travel costs. - expense coverage,financial policy - chunk-2eea91fe956cae84935e609164d08d55 - /app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx - 1779466162 - + 1.0 + Senior Management P8 and Above operate under the Reimbursement Of Actual Expenses policy for their travel costs. + expense coverage,financial policy + chunk-2eea91fe956cae84935e609164d08d55 + /app/server/storage/knowledge/差旅规范/远光软件差旅费标准速查表.xlsx + 1779466162 + - 1.0 - 发票抬头错误is a problem type documented in the common issues handling section. - handling procedure,issue classification - chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 - /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx - 1779466247 - + 1.0 + 发票抬头错误is a problem type documented in the common issues handling section. + handling procedure,issue classification + chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 + /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx + 1779466247 + - 1.0 - 发票金额错误is a problem type documented in the common issues handling section. - handling procedure,issue classification - chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 - /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx - 1779466247 - + 1.0 + 发票金额错误is a problem type documented in the common issues handling section. + handling procedure,issue classification + chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 + /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx + 1779466247 + - 1.0 - 发票内容与业务不符is a problem type documented in the common issues handling section. - handling procedure,issue classification - chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 - /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx - 1779466247 - + 1.0 + 发票内容与业务不符is a problem type documented in the common issues handling section. + handling procedure,issue classification + chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 + /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx + 1779466247 + - 2.0 - 发票真伪is one of the audit items defined in the invoice auditing standards.<SEP>发票真伪is the first verification item in the invoice review standards checking invoice authenticity. - audit criteria,compliance check,document structure,verification item - chunk-f7ca8767b8a4ddde879a599a598c044f<SEP>chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 - /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx - 1779466246 - + 2.0 + 发票真伪is one of the audit items defined in the invoice auditing standards.<SEP>发票真伪is the first verification item in the invoice review standards checking invoice authenticity. + audit criteria,compliance check,document structure,verification item + chunk-f7ca8767b8a4ddde879a599a598c044f<SEP>chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 + /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx + 1779466246 + - 2.0 - 抬头信息is one of the audit items defined in the invoice auditing standards.<SEP>抬头信息is a verification item in the invoice review standards checking buyer name matches company name. - audit criteria,company identification,document structure,verification item - chunk-f7ca8767b8a4ddde879a599a598c044f<SEP>chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 - /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx - 1779466246 - + 2.0 + 抬头信息is one of the audit items defined in the invoice auditing standards.<SEP>抬头信息is a verification item in the invoice review standards checking buyer name matches company name. + audit criteria,company identification,document structure,verification item + chunk-f7ca8767b8a4ddde879a599a598c044f<SEP>chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 + /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx + 1779466246 + - 1.0 - 纳税人识别号is one of the audit items defined in the invoice auditing standards. - audit criteria,document structure - chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 - /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx - 1779466246 - + 1.0 + 纳税人识别号is one of the audit items defined in the invoice auditing standards. + audit criteria,document structure + chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 + /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx + 1779466246 + - 1.0 - 开票日期is one of the audit items defined in the invoice auditing standards. - audit criteria,document structure - chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 - /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx - 1779466247 - + 1.0 + 开票日期is one of the audit items defined in the invoice auditing standards. + audit criteria,document structure + chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 + /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx + 1779466247 + - 1.0 - 发票内容is one of the audit items defined in the invoice auditing standards. - audit criteria,document structure - chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 - /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx - 1779466247 - + 1.0 + 发票内容is one of the audit items defined in the invoice auditing standards. + audit criteria,document structure + chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 + /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx + 1779466247 + - 1.0 - 金额核对is one of the audit items defined in the invoice auditing standards. - audit criteria,document structure - chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 - /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx - 1779466247 - + 1.0 + 金额核对is one of the audit items defined in the invoice auditing standards. + audit criteria,document structure + chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 + /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx + 1779466247 + - 1.0 - 税率检查is one of the audit items defined in the invoice auditing standards. - audit criteria,document structure - chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 - /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx - 1779466247 - + 1.0 + 税率检查is one of the audit items defined in the invoice auditing standards. + audit criteria,document structure + chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 + /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx + 1779466247 + - 1.0 - 印章检查is one of the audit items defined in the invoice auditing standards. - audit criteria,document structure - chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 - /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx - 1779466248 - + 1.0 + 印章检查is one of the audit items defined in the invoice auditing standards. + audit criteria,document structure + chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 + /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx + 1779466248 + - 1.0 - 重复检查is one of the audit items defined in the invoice auditing standards. - audit criteria,document structure - chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 - /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx - 1779466248 - + 1.0 + 重复检查is one of the audit items defined in the invoice auditing standards. + audit criteria,document structure + chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 + /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx + 1779466248 + - 1.0 - 附件完整性is one of the audit items defined in the invoice auditing standards. - audit criteria,document structure - chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 - /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx - 1779466264 - + 1.0 + 附件完整性is one of the audit items defined in the invoice auditing standards. + audit criteria,document structure + chunk-a3d1dc9708ed46c3ab2fdb3399ac8343 + /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx + 1779466264 + - 1.0 - 发票抬头错误is an instance of发票问题problem category. - instance of,problem type - chunk-74de48577772db0161356fc844026b4e - /app/server/storage/knowledge/常见问答/远光软件报销问题处理指引.xlsx - 1779467383 - + 1.0 + 发票抬头错误is an instance of发票问题problem category. + instance of,problem type + chunk-74de48577772db0161356fc844026b4e + /app/server/storage/knowledge/常见问答/远光软件报销问题处理指引.xlsx + 1779467383 + - 1.0 - 发票丢失is an instance of发票问题problem category. - instance of,problem type - chunk-74de48577772db0161356fc844026b4e - /app/server/storage/knowledge/常见问答/远光软件报销问题处理指引.xlsx - 1779467383 - + 1.0 + 发票丢失is an instance of发票问题problem category. + instance of,problem type + chunk-74de48577772db0161356fc844026b4e + /app/server/storage/knowledge/常见问答/远光软件报销问题处理指引.xlsx + 1779467383 + - 1.0 - The invoicing party must issue invoices with the correct header displaying the full company name. - compliance requirement,invoice issuance - chunk-cfac1ddf5942f8fe2d5a296380818faf - /app/server/storage/knowledge/常见问答/远光软件财务报销常见问题解答.docx - 1779467725 - + 1.0 + The invoicing party must issue invoices with the correct header displaying the full company name. + compliance requirement,invoice issuance + chunk-cfac1ddf5942f8fe2d5a296380818faf + /app/server/storage/knowledge/常见问答/远光软件财务报销常见问题解答.docx + 1779467725 + - 1.0 - When an invoice is lost, the invoicing party provides a copy of the bookkeeping form with official seal. - documentation provision,invoice replacement - chunk-cfac1ddf5942f8fe2d5a296380818faf - /app/server/storage/knowledge/常见问答/远光软件财务报销常见问题解答.docx - 1779467725 - + 1.0 + When an invoice is lost, the invoicing party provides a copy of the bookkeeping form with official seal. + documentation provision,invoice replacement + chunk-cfac1ddf5942f8fe2d5a296380818faf + /app/server/storage/knowledge/常见问答/远光软件财务报销常见问题解答.docx + 1779467725 + - 1.0 - Electronic invoices and paper invoices have equal legal effect. - document format,legal equivalence - chunk-8c48a48e8ce0bfd52d732de60fec82ce - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466312 - + 1.0 + Electronic invoices and paper invoices have equal legal effect. + document format,legal equivalence + chunk-8c48a48e8ce0bfd52d732de60fec82ce + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466312 + - 1.0 - 发票号码serves as identification data for verifying the uniqueness of electronic invoices during duplicate checking. - identification,verification data - chunk-4f26391db1f914c1dbf43241f51b8d4e - /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466393 - + 1.0 + 发票号码serves as identification data for verifying the uniqueness of electronic invoices during duplicate checking. + identification,verification data + chunk-4f26391db1f914c1dbf43241f51b8d4e + /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466393 + - 1.0 - 发票代码serves as identification data for verifying the uniqueness of electronic invoices during duplicate checking. - identification,verification data - chunk-4f26391db1f914c1dbf43241f51b8d4e - /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466393 - + 1.0 + 发票代码serves as identification data for verifying the uniqueness of electronic invoices during duplicate checking. + identification,verification data + chunk-4f26391db1f914c1dbf43241f51b8d4e + /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466393 + - 1.0 - 电子发票must be saved in PDF or OFD format as original files upon receipt. - file format,storage requirement - chunk-4f26391db1f914c1dbf43241f51b8d4e - /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466393 - + 1.0 + 电子发票must be saved in PDF or OFD format as original files upon receipt. + file format,storage requirement + chunk-4f26391db1f914c1dbf43241f51b8d4e + /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466393 + - 1.0 - 电子发票is stored in the company's electronic archives system with proper backup procedures. - archival management,storage system - chunk-4f26391db1f914c1dbf43241f51b8d4e - /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466394 - + 1.0 + 电子发票is stored in the company's electronic archives system with proper backup procedures. + archival management,storage system + chunk-4f26391db1f914c1dbf43241f51b8d4e + /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466394 + - 1.0 - 增值税电子普通发票is a type of electronic invoice with equal legal effect to paper invoices. - invoice type,legal equivalence - chunk-4f26391db1f914c1dbf43241f51b8d4e - /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466394 - + 1.0 + 增值税电子普通发票is a type of electronic invoice with equal legal effect to paper invoices. + invoice type,legal equivalence + chunk-4f26391db1f914c1dbf43241f51b8d4e + /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466394 + - 1.0 - 增值税电子专用发票is a type of electronic invoice with equal legal effect to paper invoices. - invoice type,legal equivalence - chunk-4f26391db1f914c1dbf43241f51b8d4e - /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466394 - + 1.0 + 增值税电子专用发票is a type of electronic invoice with equal legal effect to paper invoices. + invoice type,legal equivalence + chunk-4f26391db1f914c1dbf43241f51b8d4e + /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466394 + - 1.0 - 第二章电子发票的接收specifies the regulations for receiving electronic invoices. - operational procedure,receiving regulations - chunk-4f26391db1f914c1dbf43241f51b8d4e - /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466395 - + 1.0 + 第二章电子发票的接收specifies the regulations for receiving electronic invoices. + operational procedure,receiving regulations + chunk-4f26391db1f914c1dbf43241f51b8d4e + /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466395 + - 1.0 - Tax Rate Check involves inspecting applicable tax rates to ensure they are correctly applied. - tax compliance,verification method - chunk-d3a2a23083356bd293563d06dbaa6a0c - /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx - 1779466247 - + 1.0 + Tax Rate Check involves inspecting applicable tax rates to ensure they are correctly applied. + tax compliance,verification method + chunk-d3a2a23083356bd293563d06dbaa6a0c + /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx + 1779466247 + - 1.0 - Tax Rate Check verifies that the tax rate stated on the invoice is accurate and valid. - quality control,regulatory compliance - chunk-d3a2a23083356bd293563d06dbaa6a0c - /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx - 1779466247 - + 1.0 + Tax Rate Check verifies that the tax rate stated on the invoice is accurate and valid. + quality control,regulatory compliance + chunk-d3a2a23083356bd293563d06dbaa6a0c + /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx + 1779466247 + - 1.0 - Tax Rate Check includes attention to applicable tax incentive policies that may affect the rate. - policy awareness,tax savings - chunk-d3a2a23083356bd293563d06dbaa6a0c - /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx - 1779466248 - + 1.0 + Tax Rate Check includes attention to applicable tax incentive policies that may affect the rate. + policy awareness,tax savings + chunk-d3a2a23083356bd293563d06dbaa6a0c + /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx + 1779466248 + - 1.0 - Stamp Inspection verifies the presence and authenticity of the invoice special seal. - invoice validation,seal requirement - chunk-d3a2a23083356bd293563d06dbaa6a0c - /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx - 1779466247 - + 1.0 + Stamp Inspection verifies the presence and authenticity of the invoice special seal. + invoice validation,seal requirement + chunk-d3a2a23083356bd293563d06dbaa6a0c + /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx + 1779466247 + - 1.0 - Stamp Inspection requires that all invoice stamps are clear and clearly identifiable. - document quality,seal legibility - chunk-d3a2a23083356bd293563d06dbaa6a0c - /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx - 1779466248 - + 1.0 + Stamp Inspection requires that all invoice stamps are clear and clearly identifiable. + document quality,seal legibility + chunk-d3a2a23083356bd293563d06dbaa6a0c + /app/server/storage/knowledge/发票管理/远光软件公司发票审核标准.xlsx + 1779466248 + - 2.0 - When invoice management personnel changes occur, the finance department head supervises the handover procedures.<SEP>财务部负责人supervises the handover process when发票管理人员changes. - handover oversight,supervision - chunk-65235351abce326b8aca831b128a96c6<SEP>chunk-8c48a48e8ce0bfd52d732de60fec82ce - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466311 - + 2.0 + When invoice management personnel changes occur, the finance department head supervises the handover procedures.<SEP>财务部负责人supervises the handover process when发票管理人员changes. + handover oversight,supervision + chunk-65235351abce326b8aca831b128a96c6<SEP>chunk-8c48a48e8ce0bfd52d732de60fec82ce + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466311 + - 1.0 - Invoices are stored using specialized insurance cabinets or iron cabinets with fire, theft, moisture, and pest prevention measures. - security measures,storage management - chunk-8c48a48e8ce0bfd52d732de60fec82ce - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466313 - + 1.0 + Invoices are stored using specialized insurance cabinets or iron cabinets with fire, theft, moisture, and pest prevention measures. + security measures,storage management + chunk-8c48a48e8ce0bfd52d732de60fec82ce + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466313 + - 1.0 - 公司员工must verify deduction联information when obtaining增值税专用发票for business expenses. - compliance requirement,invoice acquisition - chunk-65235351abce326b8aca831b128a96c6 - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466312 - + 1.0 + 公司员工must verify deduction联information when obtaining增值税专用发票for business expenses. + compliance requirement,invoice acquisition + chunk-65235351abce326b8aca831b128a96c6 + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466312 + - 1.0 - Company employees acquire invoices when incurring official business expenses for reimbursement purposes. - business expenditure,expense reimbursement - chunk-8c48a48e8ce0bfd52d732de60fec82ce - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466313 - + 1.0 + Company employees acquire invoices when incurring official business expenses for reimbursement purposes. + business expenditure,expense reimbursement + chunk-8c48a48e8ce0bfd52d732de60fec82ce + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466313 + - 1.0 - 财务部门must verify deduction information when reviewing增值税专用发票for reimbursement. - reimbursement review,verification procedure - chunk-65235351abce326b8aca831b128a96c6 - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466312 - + 1.0 + 财务部门must verify deduction information when reviewing增值税专用发票for reimbursement. + reimbursement review,verification procedure + chunk-65235351abce326b8aca831b128a96c6 + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466312 + - 1.0 - The invoice management standards are formulated based on and in compliance with the national invoice management regulations. - compliance reference,legal basis - chunk-65235351abce326b8aca831b128a96c6 - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466311 - + 1.0 + The invoice management standards are formulated based on and in compliance with the national invoice management regulations. + compliance reference,legal basis + chunk-65235351abce326b8aca831b128a96c6 + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466311 + - 1.0 - The specification was developed according to the national Invoice Management Regulations and its implementation rules. - legal basis,regulatory compliance - chunk-8c48a48e8ce0bfd52d732de60fec82ce - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466313 - + 1.0 + The specification was developed according to the national Invoice Management Regulations and its implementation rules. + legal basis,regulatory compliance + chunk-8c48a48e8ce0bfd52d732de60fec82ce + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466313 + - 1.0 - When sales returns or discounts occur with VAT special invoices, red-character invoices must be issued. - invoice adjustment,regulatory requirement - chunk-8c48a48e8ce0bfd52d732de60fec82ce - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466313 - + 1.0 + When sales returns or discounts occur with VAT special invoices, red-character invoices must be issued. + invoice adjustment,regulatory requirement + chunk-8c48a48e8ce0bfd52d732de60fec82ce + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466313 + - 1.0 - 增值税专用发票可用于进项税额抵扣,适用于一般纳税人之间的交易。 - 发票功能,税务抵扣 - chunk-12b08b984a30d7e156cf75ac4c79ed0a - /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf - 1779466357 - + 1.0 + 增值税专用发票可用于进项税额抵扣,适用于一般纳税人之间的交易。 + 发票功能,税务抵扣 + chunk-12b08b984a30d7e156cf75ac4c79ed0a + /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf + 1779466357 + - 1.0 - 通过发票管理台账定期检查发票使用规范情况,确保发票管理合规。 - 台账管理,合规检查 - chunk-12b08b984a30d7e156cf75ac4c79ed0a - /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf - 1779466342 - + 1.0 + 通过发票管理台账定期检查发票使用规范情况,确保发票管理合规。 + 台账管理,合规检查 + chunk-12b08b984a30d7e156cf75ac4c79ed0a + /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf + 1779466342 + - 1.0 - Special VAT invoices must be certified within the 360-day period from the date of issuance. - certification deadline,tax compliance - chunk-af51160a1e2350e227249d2eaff8df40 - /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf - 1779466342 - + 1.0 + Special VAT invoices must be certified within the 360-day period from the date of issuance. + certification deadline,tax compliance + chunk-af51160a1e2350e227249d2eaff8df40 + /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf + 1779466342 + - 1.0 - When sales returns or discounts occur after invoice issuance, 红字发票must be issued to reverse the original invoice. - reversal mechanism,sales adjustment - chunk-65235351abce326b8aca831b128a96c6 - /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx - 1779466313 - + 1.0 + When sales returns or discounts occur after invoice issuance, 红字发票must be issued to reverse the original invoice. + reversal mechanism,sales adjustment + chunk-65235351abce326b8aca831b128a96c6 + /app/server/storage/knowledge/发票管理/远光软件公司发票管理规范.docx + 1779466313 + - 1.0 - 发生退货或折让等情况时需填写《开具红字增值税发票信息表》后开具红字发票。 - 发票申请,表单流程 - chunk-12b08b984a30d7e156cf75ac4c79ed0a - /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf - 1779466357 - + 1.0 + 发生退货或折让等情况时需填写《开具红字增值税发票信息表》后开具红字发票。 + 发票申请,表单流程 + chunk-12b08b984a30d7e156cf75ac4c79ed0a + /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf + 1779466357 + - 1.0 - 红字专票应妥善保管,作为进项税额转出的凭证,涉及购买方信息核对。 - 发票凭证,进项转出 - chunk-12b08b984a30d7e156cf75ac4c79ed0a - /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf - 1779466342 - + 1.0 + 红字专票应妥善保管,作为进项税额转出的凭证,涉及购买方信息核对。 + 发票凭证,进项转出 + chunk-12b08b984a30d7e156cf75ac4c79ed0a + /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf + 1779466342 + - 1.0 - 增值税普通发票不可用于进项税额抵扣,适用于向消费者个人或小规模纳税人的销售。 - 发票功能,税务限制 - chunk-12b08b984a30d7e156cf75ac4c79ed0a - /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf - 1779466341 - + 1.0 + 增值税普通发票不可用于进项税额抵扣,适用于向消费者个人或小规模纳税人的销售。 + 发票功能,税务限制 + chunk-12b08b984a30d7e156cf75ac4c79ed0a + /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf + 1779466341 + - 1.0 - 增值税电子发票与纸质发票具有同等法律效力,作为正式的发票形式存在。 - 发票形式,法律效力 - chunk-12b08b984a30d7e156cf75ac4c79ed0a - /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf - 1779466342 - + 1.0 + 增值税电子发票与纸质发票具有同等法律效力,作为正式的发票形式存在。 + 发票形式,法律效力 + chunk-12b08b984a30d7e156cf75ac4c79ed0a + /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf + 1779466342 + - 1.0 - 专票获取要求规定取得专票时须核对购买方信息,包括名称和纳税人识别号。 - 信息核对,发票获取 - chunk-12b08b984a30d7e156cf75ac4c79ed0a - /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf - 1779466341 - + 1.0 + 专票获取要求规定取得专票时须核对购买方信息,包括名称和纳税人识别号。 + 信息核对,发票获取 + chunk-12b08b984a30d7e156cf75ac4c79ed0a + /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf + 1779466341 + - 1.0 - 注意事项中规定发票开票日起超过360天未认证的不得再进行抵扣。 - 合规管理,期限规定 - chunk-12b08b984a30d7e156cf75ac4c79ed0a - /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf - 1779466341 - + 1.0 + 注意事项中规定发票开票日起超过360天未认证的不得再进行抵扣。 + 合规管理,期限规定 + chunk-12b08b984a30d7e156cf75ac4c79ed0a + /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf + 1779466341 + - 1.0 - 注意事项规定取得的发票信息与实际交易不一致的不得入账,需核对购买方信息。 - 信息一致性,合规检查 - chunk-12b08b984a30d7e156cf75ac4c79ed0a - /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf - 1779466342 - + 1.0 + 注意事项规定取得的发票信息与实际交易不一致的不得入账,需核对购买方信息。 + 信息一致性,合规检查 + chunk-12b08b984a30d7e156cf75ac4c79ed0a + /app/server/storage/knowledge/发票管理/远光软件公司增值税发票操作指南.pdf + 1779466342 + - 1.0 - 电子发票管理办法is formulated according to national tax regulations from国家税务总局. - compliance basis,regulatory framework - chunk-4f26391db1f914c1dbf43241f51b8d4e - /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466393 - + 1.0 + 电子发票管理办法is formulated according to national tax regulations from国家税务总局. + compliance basis,regulatory framework + chunk-4f26391db1f914c1dbf43241f51b8d4e + /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466393 + - 1.0 - 第四章电子发票的归档specifies storage requirements in the electronic archives system. - archival system,storage requirements - chunk-4f26391db1f914c1dbf43241f51b8d4e - /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466393 - + 1.0 + 第四章电子发票的归档specifies storage requirements in the electronic archives system. + archival system,storage requirements + chunk-4f26391db1f914c1dbf43241f51b8d4e + /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466393 + - 1.0 - The Electronic Archive System implements backup requirements with at least two copies stored in different media or locations. - data storage,redundancy - chunk-34116b8b9f61b21eaacb3b4c95f20122 - /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466394 - + 1.0 + The Electronic Archive System implements backup requirements with at least two copies stored in different media or locations. + data storage,redundancy + chunk-34116b8b9f61b21eaacb3b4c95f20122 + /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466394 + - 1.0 - Electronic invoices must maintain archival properties of authenticity, completeness, usability, and security as specified in Article 7. - compliance requirements,data quality - chunk-34116b8b9f61b21eaacb3b4c95f20122 - /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx - 1779466394 - + 1.0 + Electronic invoices must maintain archival properties of authenticity, completeness, usability, and security as specified in Article 7. + compliance requirements,data quality + chunk-34116b8b9f61b21eaacb3b4c95f20122 + /app/server/storage/knowledge/发票管理/远光软件公司电子发票管理办法.docx + 1779466394 + - 1.0 - Tax Attachment serves as a supplementary form attached to the annual tax return form. - form attachment,supplementary documentation - chunk-bdfd18ae478b23604f1318623e8e9508 - /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf - 1779466423 - + 1.0 + Tax Attachment serves as a supplementary form attached to the annual tax return form. + form attachment,supplementary documentation + chunk-bdfd18ae478b23604f1318623e8e9508 + /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf + 1779466423 + - 1.0 - Audit Report serves as supporting documentation for the annual tax return form. - supporting document,verification evidence - chunk-bdfd18ae478b23604f1318623e8e9508 - /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf - 1779466423 - + 1.0 + Audit Report serves as supporting documentation for the annual tax return form. + supporting document,verification evidence + chunk-bdfd18ae478b23604f1318623e8e9508 + /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf + 1779466423 + - 1.0 - High-Tech Enterprise Certificate is required as supporting documentation when filing the annual tax return. - filing requirement,supporting document - chunk-bdfd18ae478b23604f1318623e8e9508 - /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf - 1779466424 - + 1.0 + High-Tech Enterprise Certificate is required as supporting documentation when filing the annual tax return. + filing requirement,supporting document + chunk-bdfd18ae478b23604f1318623e8e9508 + /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf + 1779466424 + - 1.0 - The Declaration Process includes filling out the Annual Tax Return Form as a mandatory step. - process step,sequential filing - chunk-bdfd18ae478b23604f1318623e8e9508 - /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf - 1779466424 - + 1.0 + The Declaration Process includes filling out the Annual Tax Return Form as a mandatory step. + process step,sequential filing + chunk-bdfd18ae478b23604f1318623e8e9508 + /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf + 1779466424 + - 1.0 - Tax Firm provides and conducts the tax verification service for tax filings. - professional certification,service provision - chunk-bdfd18ae478b23604f1318623e8e9508 - /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf - 1779466422 - + 1.0 + Tax Firm provides and conducts the tax verification service for tax filings. + professional certification,service provision + chunk-bdfd18ae478b23604f1318623e8e9508 + /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf + 1779466422 + - 1.0 - The Declaration Process may involve hiring a Tax Firm for verification if needed. - process step,professional involvement - chunk-bdfd18ae478b23604f1318623e8e9508 - /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf - 1779466422 - + 1.0 + The Declaration Process may involve hiring a Tax Firm for verification if needed. + process step,professional involvement + chunk-bdfd18ae478b23604f1318623e8e9508 + /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf + 1779466422 + - 1.0 - Financial Statement is typically audited and accompanied by an Audit Report. - audit documentation,financial reporting - chunk-bdfd18ae478b23604f1318623e8e9508 - /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf - 1779466422 - + 1.0 + Financial Statement is typically audited and accompanied by an Audit Report. + audit documentation,financial reporting + chunk-bdfd18ae478b23604f1318623e8e9508 + /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf + 1779466422 + - 1.0 - High-Tech Enterprise Certificate is a qualifying document that enables eligibility for R&D Expense Super Deduction. - qualification requirement,tax incentive eligibility - chunk-bdfd18ae478b23604f1318623e8e9508 - /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf - 1779466422 - + 1.0 + High-Tech Enterprise Certificate is a qualifying document that enables eligibility for R&D Expense Super Deduction. + qualification requirement,tax incentive eligibility + chunk-bdfd18ae478b23604f1318623e8e9508 + /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf + 1779466422 + - 1.0 - The Declaration Process requires preparation and submission of Supporting Materials. - documentation requirement,procedural step - chunk-bdfd18ae478b23604f1318623e8e9508 - /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf - 1779466423 - + 1.0 + The Declaration Process requires preparation and submission of Supporting Materials. + documentation requirement,procedural step + chunk-bdfd18ae478b23604f1318623e8e9508 + /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf + 1779466423 + - 1.0 - R&D Expense Super Deduction Materials belong to the category of Supporting Materials required for tax filing. - category relationship,document type - chunk-bdfd18ae478b23604f1318623e8e9508 - /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf - 1779466422 - + 1.0 + R&D Expense Super Deduction Materials belong to the category of Supporting Materials required for tax filing. + category relationship,document type + chunk-bdfd18ae478b23604f1318623e8e9508 + /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf + 1779466422 + - 1.0 - 高新技术企业优惠allows enterprises to pay corporate income tax at a reduced rate of 15% instead of the - preferential tax rate,tax reduction - chunk-c511cdd6a5cc2eea82dfb43e094b6010 - /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf - 1779466422 - + 1.0 + 高新技术企业优惠allows enterprises to pay corporate income tax at a reduced rate of 15% instead of the + preferential tax rate,tax reduction + chunk-c511cdd6a5cc2eea82dfb43e094b6010 + /app/server/storage/knowledge/税务合规/远光软件企业所得税汇算清缴操作手册.pdf + 1779466422 + - 1.0 - The Tax Management System contains the basic principles that guide tax management activities. - contains,principle framework - chunk-f61c91e28e8d0f773f83e3daf161ab1c - /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx - 1779466505 - + 1.0 + The Tax Management System contains the basic principles that guide tax management activities. + contains,principle framework + chunk-f61c91e28e8d0f773f83e3daf161ab1c + /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx + 1779466505 + - 1.0 - Tax consultants may be hired to participate in major business decisions when necessary. - consultation participation,professional assistance - chunk-7dbbc500ab3d85025ed0a40708c3585f - /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx - 1779466505 - + 1.0 + Tax consultants may be hired to participate in major business decisions when necessary. + consultation participation,professional assistance + chunk-7dbbc500ab3d85025ed0a40708c3585f + /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx + 1779466505 + - 1.0 - Professional institutions are hired to assist in handling tax disputes. - dispute resolution,professional assistance - chunk-7dbbc500ab3d85025ed0a40708c3585f - /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx - 1779466505 - + 1.0 + Professional institutions are hired to assist in handling tax disputes. + dispute resolution,professional assistance + chunk-7dbbc500ab3d85025ed0a40708c3585f + /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx + 1779466505 + - 1.0 - Tax disputes must be promptly reported to company management. - management oversight,reporting requirement - chunk-7dbbc500ab3d85025ed0a40708c3585f - /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx - 1779466505 - + 1.0 + Tax disputes must be promptly reported to company management. + management oversight,reporting requirement + chunk-7dbbc500ab3d85025ed0a40708c3585f + /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx + 1779466505 + - 1.0 - Major business decisions should undergo tax impact analysis as required by company policy. - policy requirement,tax compliance - chunk-7dbbc500ab3d85025ed0a40708c3585f - /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx - 1779466504 - + 1.0 + Major business decisions should undergo tax impact analysis as required by company policy. + policy requirement,tax compliance + chunk-7dbbc500ab3d85025ed0a40708c3585f + /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx + 1779466504 + - 1.0 - Tax risk management (Chapter 4) and supplementary provisions (Chapter 5) are distinct chapters within the same policy document. - chapter relationship,document structure - chunk-7dbbc500ab3d85025ed0a40708c3585f - /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx - 1779466505 - + 1.0 + Tax risk management (Chapter 4) and supplementary provisions (Chapter 5) are distinct chapters within the same policy document. + chapter relationship,document structure + chunk-7dbbc500ab3d85025ed0a40708c3585f + /app/server/storage/knowledge/税务合规/远光软件公司税务管理制度.docx + 1779466505 + - 1.0 - 公司管理层determines the operating objectives and budget guidance as part of the budget preparation schedule. - budget guidance,planning - chunk-6493ba2ae9f87d70ec970b53687e2557 - /app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf - 1779467007 - + 1.0 + 公司管理层determines the operating objectives and budget guidance as part of the budget preparation schedule. + budget guidance,planning + chunk-6493ba2ae9f87d70ec970b53687e2557 + /app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf + 1779467007 + - 1.0 - The Excel workbook contains the worksheet titled研发费用管理 - document organization,worksheet structure - chunk-24de3b6d9d2fc0445c2c31da82a60be1 - /app/server/storage/knowledge/税务合规/远光软件研发费用加计扣除管理办法.xlsx - 1779466539 - + 1.0 + The Excel workbook contains the worksheet titled研发费用管理 + document organization,worksheet structure + chunk-24de3b6d9d2fc0445c2c31da82a60be1 + /app/server/storage/knowledge/税务合规/远光软件研发费用加计扣除管理办法.xlsx + 1779466539 + - 1.0 - 研发费用加计扣除管理办法包含人员人工费用这一核算类别,规定其按100%比例扣除。 - 包含,核算类别 - chunk-e650a577ed84565fd87ee6422b4b82a2 - /app/server/storage/knowledge/税务合规/远光软件研发费用加计扣除管理办法.xlsx - 1779466539 - + 1.0 + 研发费用加计扣除管理办法包含人员人工费用这一核算类别,规定其按100%比例扣除。 + 包含,核算类别 + chunk-e650a577ed84565fd87ee6422b4b82a2 + /app/server/storage/knowledge/税务合规/远光软件研发费用加计扣除管理办法.xlsx + 1779466539 + - 1.0 - 工时记录作为人员人工费用的核算凭证,用于支持研发人员工资薪金等费用的核算。 - 核算凭证,费用支持 - chunk-e650a577ed84565fd87ee6422b4b82a2 - /app/server/storage/knowledge/税务合规/远光软件研发费用加计扣除管理办法.xlsx - 1779466539 - + 1.0 + 工时记录作为人员人工费用的核算凭证,用于支持研发人员工资薪金等费用的核算。 + 核算凭证,费用支持 + chunk-e650a577ed84565fd87ee6422b4b82a2 + /app/server/storage/knowledge/税务合规/远光软件研发费用加计扣除管理办法.xlsx + 1779466539 + - 1.0 - 社保缴纳记录作为人员人工费用的核算凭证,用于支持研发人员社保费用的核算。 - 核算凭证,费用支持 - chunk-e650a577ed84565fd87ee6422b4b82a2 - /app/server/storage/knowledge/税务合规/远光软件研发费用加计扣除管理办法.xlsx - 1779466540 - + 1.0 + 社保缴纳记录作为人员人工费用的核算凭证,用于支持研发人员社保费用的核算。 + 核算凭证,费用支持 + chunk-e650a577ed84565fd87ee6422b4b82a2 + /app/server/storage/knowledge/税务合规/远光软件研发费用加计扣除管理办法.xlsx + 1779466540 + - 1.0 - 研发费用加计扣除管理办法包含直接投入费用这一核算类别,要求与生产费用区分核算。 - 包含,核算类别 - chunk-e650a577ed84565fd87ee6422b4b82a2 - /app/server/storage/knowledge/税务合规/远光软件研发费用加计扣除管理办法.xlsx - 1779466539 - + 1.0 + 研发费用加计扣除管理办法包含直接投入费用这一核算类别,要求与生产费用区分核算。 + 包含,核算类别 + chunk-e650a577ed84565fd87ee6422b4b82a2 + /app/server/storage/knowledge/税务合规/远光软件研发费用加计扣除管理办法.xlsx + 1779466539 + - 1.0 - 研发费用加计扣除管理办法包含折旧费用这一核算类别,适用于研发专用设备。 - 包含,核算类别 - chunk-e650a577ed84565fd87ee6422b4b82a2 - /app/server/storage/knowledge/税务合规/远光软件研发费用加计扣除管理办法.xlsx - 1779466540 - + 1.0 + 研发费用加计扣除管理办法包含折旧费用这一核算类别,适用于研发专用设备。 + 包含,核算类别 + chunk-e650a577ed84565fd87ee6422b4b82a2 + /app/server/storage/knowledge/税务合规/远光软件研发费用加计扣除管理办法.xlsx + 1779466540 + - 1.0 - 研发费用加计扣除管理办法包含无形资产摊销这一核算类别,涉及研发软件和专利权等。 - 包含,核算类别 - chunk-e650a577ed84565fd87ee6422b4b82a2 - /app/server/storage/knowledge/税务合规/远光软件研发费用加计扣除管理办法.xlsx - 1779466556 - + 1.0 + 研发费用加计扣除管理办法包含无形资产摊销这一核算类别,涉及研发软件和专利权等。 + 包含,核算类别 + chunk-e650a577ed84565fd87ee6422b4b82a2 + /app/server/storage/knowledge/税务合规/远光软件研发费用加计扣除管理办法.xlsx + 1779466556 + - 1.0 - Software product sales require certification and recognition from the Provincial Software Industry Authority to qualify for tax rebates. - certification requirement,policy governance - chunk-2bcb956c7e2d35e45e9aba4ddacab125 - /app/server/storage/knowledge/税务合规/远光软件软件产品增值税即征即退操作指南.pdf - 1779466579 - + 1.0 + Software product sales require certification and recognition from the Provincial Software Industry Authority to qualify for tax rebates. + certification requirement,policy governance + chunk-2bcb956c7e2d35e45e9aba4ddacab125 + /app/server/storage/knowledge/税务合规/远光软件软件产品增值税即征即退操作指南.pdf + 1779466579 + - 1.0 - Software products must obtain testing proof materials from recognized software testing institutions as part of the tax rebate qualification process. - compliance verification,quality certification - chunk-2bcb956c7e2d35e45e9aba4ddacab125 - /app/server/storage/knowledge/税务合规/远光软件软件产品增值税即征即退操作指南.pdf - 1779466579 - + 1.0 + Software products must obtain testing proof materials from recognized software testing institutions as part of the tax rebate qualification process. + compliance verification,quality certification + chunk-2bcb956c7e2d35e45e9aba4ddacab125 + /app/server/storage/knowledge/税务合规/远光软件软件产品增值税即征即退操作指南.pdf + 1779466579 + - 1.0 - Software products must obtain the Software Product Registration Certificate issued by the software industry authority to qualify for tax rebates. - compliance requirement,legal certification - chunk-2bcb956c7e2d35e45e9aba4ddacab125 - /app/server/storage/knowledge/税务合规/远光软件软件产品增值税即征即退操作指南.pdf - 1779466580 - + 1.0 + Software products must obtain the Software Product Registration Certificate issued by the software industry authority to qualify for tax rebates. + compliance requirement,legal certification + chunk-2bcb956c7e2d35e45e9aba4ddacab125 + /app/server/storage/knowledge/税务合规/远光软件软件产品增值税即征即退操作指南.pdf + 1779466580 + - 1.0 - Software products must obtain the Computer Software Copyright Registration Certificate to demonstrate legitimate copyright ownership for tax rebate eligibility. - certification requirement,intellectual property protection - chunk-2bcb956c7e2d35e45e9aba4ddacab125 - /app/server/storage/knowledge/税务合规/远光软件软件产品增值税即征即退操作指南.pdf - 1779466580 - + 1.0 + Software products must obtain the Computer Software Copyright Registration Certificate to demonstrate legitimate copyright ownership for tax rebate eligibility. + certification requirement,intellectual property protection + chunk-2bcb956c7e2d35e45e9aba4ddacab125 + /app/server/storage/knowledge/税务合规/远光软件软件产品增值税即征即退操作指南.pdf + 1779466580 + - 1.0 - Finance Department prepares monthly reports under Budget Execution Reporting Rule to report to management. - management communication,reporting obligation - chunk-5c22f4a1b19ac48deafaadf184e09cd1 - /app/server/storage/knowledge/预算管理/远光软件公司预算管理制度.docx - 1779467003 - + 1.0 + Finance Department prepares monthly reports under Budget Execution Reporting Rule to report to management. + management communication,reporting obligation + chunk-5c22f4a1b19ac48deafaadf184e09cd1 + /app/server/storage/knowledge/预算管理/远光软件公司预算管理制度.docx + 1779467003 + - 1.0 - Finance Department holds supervision and control responsibilities under Budget Execution Supervision Rule. - control authority,supervision responsibility - chunk-5c22f4a1b19ac48deafaadf184e09cd1 - /app/server/storage/knowledge/预算管理/远光软件公司预算管理制度.docx - 1779467003 - + 1.0 + Finance Department holds supervision and control responsibilities under Budget Execution Supervision Rule. + control authority,supervision responsibility + chunk-5c22f4a1b19ac48deafaadf184e09cd1 + /app/server/storage/knowledge/预算管理/远光软件公司预算管理制度.docx + 1779467003 + - 1.0 - Contracts involving payment terms require the Finance Department to participate in review. - contract review,financial oversight - chunk-3c2a3406703711442c39071720a279c6 - /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf - 1779467702 - + 1.0 + Contracts involving payment terms require the Finance Department to participate in review. + contract review,financial oversight + chunk-3c2a3406703711442c39071720a279c6 + /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf + 1779467702 + - 1.0 - Major contracts valued at 500,000 yuan or above must be co-signed by the Finance Department. - co-signature requirement,financial oversight - chunk-3c2a3406703711442c39071720a279c6 - /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf - 1779467718 - + 1.0 + Major contracts valued at 500,000 yuan or above must be co-signed by the Finance Department. + co-signature requirement,financial oversight + chunk-3c2a3406703711442c39071720a279c6 + /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf + 1779467718 + - 1.0 - The Finance Department monthly withholds and remits individual income tax based on the declared deductions. - monthly processing,tax withholding - chunk-3c2a3406703711442c39071720a279c6 - /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf - 1779467718 - + 1.0 + The Finance Department monthly withholds and remits individual income tax based on the declared deductions. + monthly processing,tax withholding + chunk-3c2a3406703711442c39071720a279c6 + /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf + 1779467718 + - 1.0 - Various Departments are subject to Budget Execution Supervision Rule, requiring strict adherence to approved budgets. - organizational compliance,regulatory oversight - chunk-5c22f4a1b19ac48deafaadf184e09cd1 - /app/server/storage/knowledge/预算管理/远光软件公司预算管理制度.docx - 1779467003 - + 1.0 + Various Departments are subject to Budget Execution Supervision Rule, requiring strict adherence to approved budgets. + organizational compliance,regulatory oversight + chunk-5c22f4a1b19ac48deafaadf184e09cd1 + /app/server/storage/knowledge/预算管理/远光软件公司预算管理制度.docx + 1779467003 + - 1.0 - Various Departments must follow Budget Within Expenditure Rule for budgeted and over-budget expenditures. - expenditure management,procedural compliance - chunk-5c22f4a1b19ac48deafaadf184e09cd1 - /app/server/storage/knowledge/预算管理/远光软件公司预算管理制度.docx - 1779467003 - + 1.0 + Various Departments must follow Budget Within Expenditure Rule for budgeted and over-budget expenditures. + expenditure management,procedural compliance + chunk-5c22f4a1b19ac48deafaadf184e09cd1 + /app/server/storage/knowledge/预算管理/远光软件公司预算管理制度.docx + 1779467003 + - 1.0 - Management - information recipient,oversight role - chunk-5c22f4a1b19ac48deafaadf184e09cd1 - /app/server/storage/knowledge/预算管理/远光软件公司预算管理制度.docx - 1779467003 - + 1.0 + Management + information recipient,oversight role + chunk-5c22f4a1b19ac48deafaadf184e09cd1 + /app/server/storage/knowledge/预算管理/远光软件公司预算管理制度.docx + 1779467003 + - 1.0 - 预算管理委员会reviews the company budget draft and provides feedback for modifications during the budget preparation schedule. - deliberation,review - chunk-6493ba2ae9f87d70ec970b53687e2557 - /app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf - 1779467008 - + 1.0 + 预算管理委员会reviews the company budget draft and provides feedback for modifications during the budget preparation schedule. + deliberation,review + chunk-6493ba2ae9f87d70ec970b53687e2557 + /app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf + 1779467008 + - 1.0 - 费用预算编制包含办公费,需要根据实际需要进行编制。 - 实际需求,费用编制 - chunk-06f2e5b7b8d7365196980080ed26b760 - /app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf - 1779467008 - + 1.0 + 费用预算编制包含办公费,需要根据实际需要进行编制。 + 实际需求,费用编制 + chunk-06f2e5b7b8d7365196980080ed26b760 + /app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf + 1779467008 + - 1.0 - 预算编制注意事项为费用预算编制提供四项重要指导原则,确保预算编制的规范性和合理性。 - 原则规范,编制指导 - chunk-06f2e5b7b8d7365196980080ed26b760 - /app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf - 1779467008 - + 1.0 + 预算编制注意事项为费用预算编制提供四项重要指导原则,确保预算编制的规范性和合理性。 + 原则规范,编制指导 + chunk-06f2e5b7b8d7365196980080ed26b760 + /app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf + 1779467008 + - 1.0 - 费用预算编制需要预留适当的风险准备金,以应对潜在风险。 - 资金预留,风险管理 - chunk-06f2e5b7b8d7365196980080ed26b760 - /app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf - 1779467008 - + 1.0 + 费用预算编制需要预留适当的风险准备金,以应对潜在风险。 + 资金预留,风险管理 + chunk-06f2e5b7b8d7365196980080ed26b760 + /app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf + 1779467008 + - 1.0 - 重大资本支出在费用预算编制中需要单独编制可行性分析。 - 单独编制,投资分析 - chunk-06f2e5b7b8d7365196980080ed26b760 - /app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf - 1779467009 - + 1.0 + 重大资本支出在费用预算编制中需要单独编制可行性分析。 + 单独编制,投资分析 + chunk-06f2e5b7b8d7365196980080ed26b760 + /app/server/storage/knowledge/预算管理/远光软件年度预算编制指南.pdf + 1779467009 + - 1.0 - Software product sales (适用13%税率) are eligible for the immediate VAT refund (即征即退优惠) policy. - VAT treatment,tax benefit - chunk-6175768b05adf2e7229c16f13ee7cffd - /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf - 1779467718 - + 1.0 + Software product sales (适用13%税率) are eligible for the immediate VAT refund (即征即退优惠) policy. + VAT treatment,tax benefit + chunk-6175768b05adf2e7229c16f13ee7cffd + /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf + 1779467718 + - 1.0 - Office Equipment Procurement is a line item within the 2024 Capital Budget Table. - budget item,capital expenditure - chunk-a8b029ac9fe90e1a6bbba83306f0027d - /app/server/storage/knowledge/预算管理/远光软件预算编制模板.xlsx - 1779467084 - + 1.0 + Office Equipment Procurement is a line item within the 2024 Capital Budget Table. + budget item,capital expenditure + chunk-a8b029ac9fe90e1a6bbba83306f0027d + /app/server/storage/knowledge/预算管理/远光软件预算编制模板.xlsx + 1779467084 + - 1.0 - Server and Network Equipment is a - budget item,capital expenditure - chunk-a8b029ac9fe90e1a6bbba83306f0027d - /app/server/storage/knowledge/预算管理/远光软件预算编制模板.xlsx - 1779467084 - + 1.0 + Server and Network Equipment is a + budget item,capital expenditure + chunk-a8b029ac9fe90e1a6bbba83306f0027d + /app/server/storage/knowledge/预算管理/远光软件预算编制模板.xlsx + 1779467084 + - 1.0 - The Excel workbook contains the income - financial planning,workbook structure - chunk-570f3c034d29848862e2dbe4574e0fc9 - /app/server/storage/knowledge/预算管理/远光软件预算编制模板.xlsx - 1779467084 - + 1.0 + The Excel workbook contains the income + financial planning,workbook structure + chunk-570f3c034d29848862e2dbe4574e0fc9 + /app/server/storage/knowledge/预算管理/远光软件预算编制模板.xlsx + 1779467084 + - 1.0 - The Excel workbook contains the SLA Service Standard worksheet with service level requirements. - file structure,worksheet organization - chunk-6f1d6991d45799bc8ff24afaed39244d - /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx - 1779467114 - + 1.0 + The Excel workbook contains the SLA Service Standard worksheet with service level requirements. + file structure,worksheet organization + chunk-6f1d6991d45799bc8ff24afaed39244d + /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx + 1779467114 + - 1.0 - The SLA Service Standard document is the governing framework established by Yuan Guang Software Financial Shared Service Center to define service levels. - service governance,standard document - chunk-6f1d6991d45799bc8ff24afaed39244d - /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx - 1779467129 - + 1.0 + The SLA Service Standard document is the governing framework established by Yuan Guang Software Financial Shared Service Center to define service levels. + service governance,standard document + chunk-6f1d6991d45799bc8ff24afaed39244d + /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx + 1779467129 + - 1.0 - The financial shared service center has established the SLA service standard to define service levels. - service governance,standard documentation - chunk-af56151a803634f02e294f2d692fc1f0 - /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx - 1779467115 - + 1.0 + The financial shared service center has established the SLA service standard to define service levels. + service governance,standard documentation + chunk-af56151a803634f02e294f2d692fc1f0 + /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx + 1779467115 + - 1.0 - The SLA service standard defines the service content, response times, and availability requirements for expense reimbursement processing. - service definition,service scope - chunk-af56151a803634f02e294f2d692fc1f0 - /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx - 1779467115 - + 1.0 + The SLA service standard defines the service content, response times, and availability requirements for expense reimbursement processing. + service definition,service scope + chunk-af56151a803634f02e294f2d692fc1f0 + /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx + 1779467115 + - 1.0 - The SLA service standard defines the service content, response times, and availability requirements for general ledger accounting. - service definition,service scope - chunk-af56151a803634f02e294f2d692fc1f0 - /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx - 1779467116 - + 1.0 + The SLA service standard defines the service content, response times, and availability requirements for general ledger accounting. + service definition,service scope + chunk-af56151a803634f02e294f2d692fc1f0 + /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx + 1779467116 + - 1.0 - The SLA service standard defines the service content, response times, and availability requirements for month-end closing processing. - service definition,service scope - chunk-af56151a803634f02e294f2d692fc1f0 - /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx - 1779467132 - + 1.0 + The SLA service standard defines the service content, response times, and availability requirements for month-end closing processing. + service definition,service scope + chunk-af56151a803634f02e294f2d692fc1f0 + /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx + 1779467132 + - 1.0 - The SLA service standard defines the service content, response times, and availability requirements for financial statement preparation. - service definition,service scope - chunk-af56151a803634f02e294f2d692fc1f0 - /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx - 1779467132 - + 1.0 + The SLA service standard defines the service content, response times, and availability requirements for financial statement preparation. + service definition,service scope + chunk-af56151a803634f02e294f2d692fc1f0 + /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx + 1779467132 + - 1.0 - The SLA service standard defines the service content, response times, and availability requirements for tax declaration and payment. - service definition,service scope - chunk-af56151a803634f02e294f2d692fc1f0 - /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx - 1779467132 - + 1.0 + The SLA service standard defines the service content, response times, and availability requirements for tax declaration and payment. + service definition,service scope + chunk-af56151a803634f02e294f2d692fc1f0 + /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx + 1779467132 + - 1.0 - The SLA service standard defines the service content, response times, and availability requirements for asset management. - service definition,service scope - chunk-af56151a803634f02e294f2d692fc1f0 - /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx - 1779467133 - + 1.0 + The SLA service standard defines the service content, response times, and availability requirements for asset management. + service definition,service scope + chunk-af56151a803634f02e294f2d692fc1f0 + /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx + 1779467133 + - 1.0 - The SLA service standard defines the service content, response times, and availability requirements for bank reconciliation. - service definition,service scope - chunk-af56151a803634f02e294f2d692fc1f0 - /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx - 1779467133 - + 1.0 + The SLA service standard defines the service content, response times, and availability requirements for bank reconciliation. + service definition,service scope + chunk-af56151a803634f02e294f2d692fc1f0 + /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx + 1779467133 + - 1.0 - The SLA service standard defines the service content, response times, and availability requirements for archive management. - service definition,service scope - chunk-af56151a803634f02e294f2d692fc1f0 - /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx - 1779467133 - + 1.0 + The SLA service standard defines the service content, response times, and availability requirements for archive management. + service definition,service scope + chunk-af56151a803634f02e294f2d692fc1f0 + /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx + 1779467133 + - 1.0 - Expense Reimbursement is one of the service items provided by Yuan Guang Software Financial Shared Service Center. - financial process,service provision - chunk-6f1d6991d45799bc8ff24afaed39244d - /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx - 1779467114 - + 1.0 + Expense Reimbursement is one of the service items provided by Yuan Guang Software Financial Shared Service Center. + financial process,service provision + chunk-6f1d6991d45799bc8ff24afaed39244d + /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx + 1779467114 + - 1.0 - Archive Management is one of the service items provided by Yuan Guang Software Financial Shared Service Center, involving voucher organization and archiving with a standard turnaround of 10 business days after month-end and 100% availability requirement. - financial process,service provision - chunk-6f1d6991d45799bc8ff24afaed39244d - /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx - 1779467115 - + 1.0 + Archive Management is one of the service items provided by Yuan Guang Software Financial Shared Service Center, involving voucher organization and archiving with a standard turnaround of 10 business days after month-end and 100% availability requirement. + financial process,service provision + chunk-6f1d6991d45799bc8ff24afaed39244d + /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx + 1779467115 + - 1.0 - 财务共享服务中心provides general ledger accounting as one of its core services. - operational process,service delivery - chunk-3b77f7e8beca3e7d537d0623f97473ee - /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx - 1779467164 - + 1.0 + 财务共享服务中心provides general ledger accounting as one of its core services. + operational process,service delivery + chunk-3b77f7e8beca3e7d537d0623f97473ee + /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx + 1779467164 + - 1.0 - Report preparation has standard processing time requirements, with monthly reports due within 5 working days after month-end. - processing duration,service standard - chunk-3b77f7e8beca3e7d537d0623f97473ee - /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx - 1779467164 - + 1.0 + Report preparation has standard processing time requirements, with monthly reports due within 5 working days after month-end. + processing duration,service standard + chunk-3b77f7e8beca3e7d537d0623f97473ee + /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx + 1779467164 + - 1.0 - 远光软件operates and provides the financial shared service center. - organizational structure,service provision - chunk-af56151a803634f02e294f2d692fc1f0 - /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx - 1779467129 - + 1.0 + 远光软件operates and provides the financial shared service center. + organizational structure,service provision + chunk-af56151a803634f02e294f2d692fc1f0 + /app/server/storage/knowledge/财务共享/远光软件财务共享服务SLA标准.xlsx + 1779467129 + - 1.0 - 财务共享服务中心provides standardized financial services to all branches and subsidiaries. - financial support,service provision - chunk-3b77f7e8beca3e7d537d0623f97473ee - /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx - 1779467162 - + 1.0 + 财务共享服务中心provides standardized financial services to all branches and subsidiaries. + financial support,service provision + chunk-3b77f7e8beca3e7d537d0623f97473ee + /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx + 1779467162 + - 1.0 - 财务共享服务中心provides expense reimbursement processing as one of its core services. - operational process,service delivery - chunk-3b77f7e8beca3e7d537d0623f97473ee - /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx - 1779467163 - + 1.0 + 财务共享服务中心provides expense reimbursement processing as one of its core services. + operational process,service delivery + chunk-3b77f7e8beca3e7d537d0623f97473ee + /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx + 1779467163 + - 1.0 - 财务共享服务中心provides accounts receivable and payable management as one of its core services. - operational process,service delivery - chunk-3b77f7e8beca3e7d537d0623f97473ee - /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx - 1779467163 - + 1.0 + 财务共享服务中心provides accounts receivable and payable management as one of its core services. + operational process,service delivery + chunk-3b77f7e8beca3e7d537d0623f97473ee + /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx + 1779467163 + - 1.0 - 财务共享服务中心provides fund settlement as one of its core services. - operational process,service delivery - chunk-3b77f7e8beca3e7d537d0623f97473ee - /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx - 1779467164 - + 1.0 + 财务共享服务中心provides fund settlement as one of its core services. + operational process,service delivery + chunk-3b77f7e8beca3e7d537d0623f97473ee + /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx + 1779467164 + - 1.0 - The management measures provide the operational framework for establishing and managing the financial shared service center. - operational framework,policy document - chunk-3b77f7e8beca3e7d537d0623f97473ee - /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx - 1779467164 - + 1.0 + The management measures provide the operational framework for establishing and managing the financial shared service center. + operational framework,policy document + chunk-3b77f7e8beca3e7d537d0623f97473ee + /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx + 1779467164 + - 1.0 - The shared center provides standardized and process-based financial services to all units. - operational model,service delivery - chunk-3b77f7e8beca3e7d537d0623f97473ee - /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx - 1779467165 - + 1.0 + The shared center provides standardized and process-based financial services to all units. + operational model,service delivery + chunk-3b77f7e8beca3e7d537d0623f97473ee + /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx + 1779467165 + - 1.0 - Expense reimbursement processing has standard and urgent processing time requirements. - processing duration,service standard - chunk-3b77f7e8beca3e7d537d0623f97473ee - /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx - 1779467163 - + 1.0 + Expense reimbursement processing has standard and urgent processing time requirements. + processing duration,service standard + chunk-3b77f7e8beca3e7d537d0623f97473ee + /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx + 1779467163 + - 1.0 - Voucher processing has standard and urgent processing time requirements. - processing duration,service standard - chunk-3b77f7e8beca3e7d537d0623f97473ee - /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx - 1779467163 - + 1.0 + Voucher processing has standard and urgent processing time requirements. + processing duration,service standard + chunk-3b77f7e8beca3e7d537d0623f97473ee + /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx + 1779467163 + - 1.0 - Payment processing has standard and urgent processing time requirements. - processing duration,service standard - chunk-3b77f7e8beca3e7d537d0623f97473ee - /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx - 1779467164 - + 1.0 + Payment processing has standard and urgent processing time requirements. + processing duration,service standard + chunk-3b77f7e8beca3e7d537d0623f97473ee + /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx + 1779467164 + - 1.0 - The management measures aim to promote financial management transformation within the organization. - management purpose,strategic objective - chunk-3b77f7e8beca3e7d537d0623f97473ee - /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx - 1779467162 - + 1.0 + The management measures aim to promote financial management transformation within the organization. + management purpose,strategic objective + chunk-3b77f7e8beca3e7d537d0623f97473ee + /app/server/storage/knowledge/财务共享/远光软件财务共享服务中心运营管理办法.docx + 1779467162 + - 1.0 - The Financial Shared Services Platform includes the Expense Reimbursement Module for processing expense claims. - module inclusion,platform function - chunk-e9620692094a0b2c6a4059a9d54b156a - /app/server/storage/knowledge/财务共享/远光软件财务共享服务操作手册.pdf - 1779467213 - + 1.0 + The Financial Shared Services Platform includes the Expense Reimbursement Module for processing expense claims. + module inclusion,platform function + chunk-e9620692094a0b2c6a4059a9d54b156a + /app/server/storage/knowledge/财务共享/远光软件财务共享服务操作手册.pdf + 1779467213 + - 1.0 - The Financial Shared Services Platform includes the Payment Application Module for processing payment requests. - module inclusion,platform function - chunk-e9620692094a0b2c6a4059a9d54b156a - /app/server/storage/knowledge/财务共享/远光软件财务共享服务操作手册.pdf - 1779467213 - + 1.0 + The Financial Shared Services Platform includes the Payment Application Module for processing payment requests. + module inclusion,platform function + chunk-e9620692094a0b2c6a4059a9d54b156a + /app/server/storage/knowledge/财务共享/远光软件财务共享服务操作手册.pdf + 1779467213 + - 1.0 - The Financial - platform function,query feature - chunk-e9620692094a0b2c6a4059a9d54b156a - /app/server/storage/knowledge/财务共享/远光软件财务共享服务操作手册.pdf - 1779467213 - + 1.0 + The Financial + platform function,query feature + chunk-e9620692094a0b2c6a4059a9d54b156a + /app/server/storage/knowledge/财务共享/远光软件财务共享服务操作手册.pdf + 1779467213 + - 1.0 - The Expense Reimbursement Module is used for creating and submitting Reimbursement Forms. - document creation,module content - chunk-e9620692094a0b2c6a4059a9d54b156a - /app/server/storage/knowledge/财务共享/远光软件财务共享服务操作手册.pdf - 1779467212 - + 1.0 + The Expense Reimbursement Module is used for creating and submitting Reimbursement Forms. + document creation,module content + chunk-e9620692094a0b2c6a4059a9d54b156a + /app/server/storage/knowledge/财务共享/远光软件财务共享服务操作手册.pdf + 1779467212 + - 1.0 - Reimbursement Forms support PDF Format for uploading invoices and attachments. - attachment support,file format - chunk-e9620692094a0b2c6a4059a9d54b156a - /app/server/storage/knowledge/财务共享/远光软件财务共享服务操作手册.pdf - 1779467213 - + 1.0 + Reimbursement Forms support PDF Format for uploading invoices and attachments. + attachment support,file format + chunk-e9620692094a0b2c6a4059a9d54b156a + /app/server/storage/knowledge/财务共享/远光软件财务共享服务操作手册.pdf + 1779467213 + - 1.0 - Reimbursement Forms support JPG Format for uploading invoices and attachments. - attachment support,file format - chunk-e9620692094a0b2c6a4059a9d54b156a - /app/server/storage/knowledge/财务共享/远光软件财务共享服务操作手册.pdf - 1779467213 - + 1.0 + Reimbursement Forms support JPG Format for uploading invoices and attachments. + attachment support,file format + chunk-e9620692094a0b2c6a4059a9d54b156a + /app/server/storage/knowledge/财务共享/远光软件财务共享服务操作手册.pdf + 1779467213 + - 1.0 - 差旅费标准中包含城市分类标准,将出差目的地城市分为不同类别以确定相应的报销额度。 - 城市分级,费用分类 - chunk-5109df8302a1a8dc1d2254955e7e440f - /app/server/storage/knowledge/培训资料/远光软件新员工财务培训课件.pdf - 1779467263 - + 1.0 + 差旅费标准中包含城市分类标准,将出差目的地城市分为不同类别以确定相应的报销额度。 + 城市分级,费用分类 + chunk-5109df8302a1a8dc1d2254955e7e440f + /app/server/storage/knowledge/培训资料/远光软件新员工财务培训课件.pdf + 1779467263 + - 1.0 - 张三因公出差北京产生了往返机票费用1800元。 - 出差支出,费用发生 - chunk-89afdbbf904b60cf6494cba2638e08a8 - /app/server/storage/knowledge/培训资料/远光软件财务制度培训手册.docx - 1779467318 - + 1.0 + 张三因公出差北京产生了往返机票费用1800元。 + 出差支出,费用发生 + chunk-89afdbbf904b60cf6494cba2638e08a8 + /app/server/storage/knowledge/培训资料/远光软件财务制度培训手册.docx + 1779467318 + - 1.0 - 张三因公出差北京产生了住宿费用1200元。 - 出差支出,费用发生 - chunk-89afdbbf904b60cf6494cba2638e08a8 - /app/server/storage/knowledge/培训资料/远光软件财务制度培训手册.docx - 1779467319 - + 1.0 + 张三因公出差北京产生了住宿费用1200元。 + 出差支出,费用发生 + chunk-89afdbbf904b60cf6494cba2638e08a8 + /app/server/storage/knowledge/培训资料/远光软件财务制度培训手册.docx + 1779467319 + - 1.0 - 张三因公出差北京产生了市内交通费用200元。 - 出差支出,费用发生 - chunk-89afdbbf904b60cf6494cba2638e08a8 - /app/server/storage/knowledge/培训资料/远光软件财务制度培训手册.docx - 1779467319 - + 1.0 + 张三因公出差北京产生了市内交通费用200元。 + 出差支出,费用发生 + chunk-89afdbbf904b60cf6494cba2638e08a8 + /app/server/storage/knowledge/培训资料/远光软件财务制度培训手册.docx + 1779467319 + - 1.0 - 张三因公出差北京产生了出差补贴330元。 - 出差支出,费用发生 - chunk-89afdbbf904b60cf6494cba2638e08a8 - /app/server/storage/knowledge/培训资料/远光软件财务制度培训手册.docx - 1779467319 - + 1.0 + 张三因公出差北京产生了出差补贴330元。 + 出差支出,费用发生 + chunk-89afdbbf904b60cf6494cba2638e08a8 + /app/server/storage/knowledge/培训资料/远光软件财务制度培训手册.docx + 1779467319 + - 1.0 - YGuang Software Co., Ltd. created and maintains the YGuang Software Financial Training Course Arrangement Excel workbook for 2024. - annual planning,organizational document - chunk-b9723c3c3219580be2ddbd88932fb2f1 - /app/server/storage/knowledge/培训资料/远光软件财务培训课程安排.xlsx - 1779467342 - + 1.0 + YGuang Software Co., Ltd. created and maintains the YGuang Software Financial Training Course Arrangement Excel workbook for 2024. + annual planning,organizational document + chunk-b9723c3c3219580be2ddbd88932fb2f1 + /app/server/storage/knowledge/培训资料/远光软件财务培训课程安排.xlsx + 1779467342 + - 1.0 - The Finance Department Manager serves as the instructor for the Financial System General Training course. - course instruction,internal training - chunk-b9723c3c3219580be2ddbd88932fb2f1 - /app/server/storage/knowledge/培训资料/远光软件财务培训课程安排.xlsx - 1779467342 - + 1.0 + The Finance Department Manager serves as the instructor for the Financial System General Training course. + course instruction,internal training + chunk-b9723c3c3219580be2ddbd88932fb2f1 + /app/server/storage/knowledge/培训资料/远光软件财务培训课程安排.xlsx + 1779467342 + - 1.0 - The Finance Department Specialist serves as the instructor for the Expense Reimbursement Practical Training course. - course instruction,internal training - chunk-b9723c3c3219580be2ddbd88932fb2f1 - /app/server/storage/knowledge/培训资料/远光软件财务培训课程安排.xlsx - 1779467342 - + 1.0 + The Finance Department Specialist serves as the instructor for the Expense Reimbursement Practical Training course. + course instruction,internal training + chunk-b9723c3c3219580be2ddbd88932fb2f1 + /app/server/storage/knowledge/培训资料/远光软件财务培训课程安排.xlsx + 1779467342 + - 1.0 - The Audit Department Manager serves as the instructor for the Internal Audit Knowledge Training course. - course instruction,internal training - chunk-b9723c3c3219580be2ddbd88932fb2f1 - /app/server/storage/knowledge/培训资料/远光软件财务培训课程安排.xlsx - 1779467342 - + 1.0 + The Audit Department Manager serves as the instructor for the Internal Audit Knowledge Training course. + course instruction,internal training + chunk-b9723c3c3219580be2ddbd88932fb2f1 + /app/server/storage/knowledge/培训资料/远光软件财务培训课程安排.xlsx + 1779467342 + - 1.0 - The External Lecturer serves as the instructor for the Excel Financial Application training course. - course instruction,external training - chunk-b9723c3c3219580be2ddbd88932fb2f1 - /app/server/storage/knowledge/培训资料/远光软件财务培训课程安排.xlsx - 1779467342 - + 1.0 + The External Lecturer serves as the instructor for the Excel Financial Application training course. + course instruction,external training + chunk-b9723c3c3219580be2ddbd88932fb2f1 + /app/server/storage/knowledge/培训资料/远光软件财务培训课程安排.xlsx + 1779467342 + - 1.0 - 远光软件报销问题处理指引categorizes invoice-related issues as发票问题problem type. - categorization,contains - chunk-74de48577772db0161356fc844026b4e - /app/server/storage/knowledge/常见问答/远光软件报销问题处理指引.xlsx - 1779467382 - + 1.0 + 远光软件报销问题处理指引categorizes invoice-related issues as发票问题problem type. + categorization,contains + chunk-74de48577772db0161356fc844026b4e + /app/server/storage/knowledge/常见问答/远光软件报销问题处理指引.xlsx + 1779467382 + - 1.0 - 发票金额与实际不符is an instance of发票问题problem category. - instance of,problem type - chunk-74de48577772db0161356fc844026b4e - /app/server/storage/knowledge/常见问答/远光软件报销问题处理指引.xlsx - 1779467383 - + 1.0 + 发票金额与实际不符is an instance of发票问题problem category. + instance of,problem type + chunk-74de48577772db0161356fc844026b4e + /app/server/storage/knowledge/常见问答/远光软件报销问题处理指引.xlsx + 1779467383 + - 1.0 - 电子发票重复提交is an instance of发票问题problem category. - instance of,problem type - chunk-74de48577772db0161356fc844026b4e - /app/server/storage/knowledge/常见问答/远光软件报销问题处理指引.xlsx - 1779467368 - + 1.0 + 电子发票重复提交is an instance of发票问题problem category. + instance of,problem type + chunk-74de48577772db0161356fc844026b4e + /app/server/storage/knowledge/常见问答/远光软件报销问题处理指引.xlsx + 1779467368 + - 1.0 - 发票超过报销时限is an instance of发票问题problem category. - instance of,problem type - chunk-74de48577772db0161356fc844026b4e - /app/server/storage/knowledge/常见问答/远光软件报销问题处理指引.xlsx - 1779467368 - + 1.0 + 发票超过报销时限is an instance of发票问题problem category. + instance of,problem type + chunk-74de48577772db0161356fc844026b4e + /app/server/storage/knowledge/常见问答/远光软件报销问题处理指引.xlsx + 1779467368 + - 1.0 - 远光软件报销问题处理指引categorizes procedural issues as流程问题problem type. - categorization,contains - chunk-74de48577772db0161356fc844026b4e - /app/server/storage/knowledge/常见问答/远光软件报销问题处理指引.xlsx - 1779467383 - + 1.0 + 远光软件报销问题处理指引categorizes procedural issues as流程问题problem type. + categorization,contains + chunk-74de48577772db0161356fc844026b4e + /app/server/storage/knowledge/常见问答/远光软件报销问题处理指引.xlsx + 1779467383 + - 1.0 - 远光软件报销问题处理指引categorizes special circumstances as其他problem type. - categorization,contains - chunk-74de48577772db0161356fc844026b4e - /app/server/storage/knowledge/常见问答/远光软件报销问题处理指引.xlsx - 1779467383 - + 1.0 + 远光软件报销问题处理指引categorizes special circumstances as其他problem type. + categorization,contains + chunk-74de48577772db0161356fc844026b4e + /app/server/storage/knowledge/常见问答/远光软件报销问题处理指引.xlsx + 1779467383 + - 1.0 - Employees use the individual income tax app to independently declare special additional deductions. - self-service declaration,tax filing - chunk-3c2a3406703711442c39071720a279c6 - /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf - 1779467702 - + 1.0 + Employees use the individual income tax app to independently declare special additional deductions. + self-service declaration,tax filing + chunk-3c2a3406703711442c39071720a279c6 + /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf + 1779467702 + - 1.0 - The company's value-added tax rate is determined to be 6%. - business tax,tax rate specification - chunk-3c2a3406703711442c39071720a279c6 - /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf - 1779467702 - + 1.0 + The company's value-added tax rate is determined to be 6%. + business tax,tax rate specification + chunk-3c2a3406703711442c39071720a279c6 + /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf + 1779467702 + - 1.0 - Software services, as the company's main business, are subject to a 6% value-added tax rate. - business activity,tax classification - chunk-3c2a3406703711442c39071720a279c6 - /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf - 1779467718 - + 1.0 + Software services, as the company's main business, are subject to a 6% value-added tax rate. + business activity,tax classification + chunk-3c2a3406703711442c39071720a279c6 + /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf + 1779467718 + - 1.0 - Company equipment assigned to individuals must be returned when the person leaves the company. - equipment management,policy compliance - chunk-6175768b05adf2e7229c16f13ee7cffd - /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf - 1779467703 - + 1.0 + Company equipment assigned to individuals must be returned when the person leaves the company. + equipment management,policy compliance + chunk-6175768b05adf2e7229c16f13ee7cffd + /app/server/storage/knowledge/常见问答/远光软件财务制度问答汇总.pdf + 1779467703 + - 1.0 - The FAQ document includes a first section covering basic reimbursement topics. - document structure,topic coverage - chunk-cfac1ddf5942f8fe2d5a296380818faf - /app/server/storage/knowledge/常见问答/远光软件财务报销常见问题解答.docx - 1779467726 - + 1.0 + The FAQ document includes a first section covering basic reimbursement topics. + document structure,topic coverage + chunk-cfac1ddf5942f8fe2d5a296380818faf + /app/server/storage/knowledge/常见问答/远光软件财务报销常见问题解答.docx + 1779467726 + - 1.0 - The FAQ document includes a second section covering travel expense reimbursement topics. - document structure,topic coverage - chunk-cfac1ddf5942f8fe2d5a296380818faf - /app/server/storage/knowledge/常见问答/远光软件财务报销常见问题解答.docx - 1779467726 - + 1.0 + The FAQ document includes a second section covering travel expense reimbursement topics. + document structure,topic coverage + chunk-cfac1ddf5942f8fe2d5a296380818faf + /app/server/storage/knowledge/常见问答/远光软件财务报销常见问题解答.docx + 1779467726 + - 1.0 - The FAQ document includes a third section covering invoice-related topics. - document structure,topic coverage - chunk-cfac1ddf5942f8fe2d5a296380818faf - /app/server/storage/knowledge/常见问答/远光软件财务报销常见问题解答.docx - 1779467726 - + 1.0 + The FAQ document includes a third section covering invoice-related topics. + document structure,topic coverage + chunk-cfac1ddf5942f8fe2d5a296380818faf + /app/server/storage/knowledge/常见问答/远光软件财务报销常见问题解答.docx + 1779467726 + diff --git a/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_doc_status.json b/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_doc_status.json index c379bc4..eadbe3d 100644 --- a/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_doc_status.json +++ b/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_doc_status.json @@ -82,23 +82,6 @@ "processing_end_time": 1779441745 } }, - "b0277cd76034437997fbf5219662725a": { - "status": "processed", - "chunks_count": 1, - "chunks_list": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43" - ], - "content_summary": "远光软件股份有限公司\n财务基础知识手册\n第一部分 会计基础知识\n一、会计要素\n会计要素包括:资产、负债、所有者权益、收入、费用和利润。\n会计恒等式:资产 = 负债 + 所有者权益\n二、常用会计科目\n科目类别\n科目名称\n说明\n资产类\n库存现金\n公司持有的现金\n资产类\n银行存款\n存放在银行的资金\n资产类\n应收账款\n因销售商品或提供劳务应收的款项\n资产类\n固定资产\n使用年限超过一年的有形资产\n负债类\n应付账款\n因购买商品或接受劳务应付的款项\n负债类\n应交税费\n应缴纳的各种税费\n负债类\n应付职工薪酬\n...", - "content_length": 1082, - "created_at": "2026-05-22T09:22:31.538281+00:00", - "updated_at": "2026-05-22T09:22:52.110824+00:00", - "file_path": "/app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx", - "track_id": "insert_20260522_092231_e1b9d415", - "metadata": { - "processing_start_time": 1779441751, - "processing_end_time": 1779441772 - } - }, "23f56f159a3e4bc3b2338056544120dd": { "status": "processed", "chunks_count": 1, @@ -688,5 +671,23 @@ "processing_start_time": 1779467725, "processing_end_time": 1779467727 } + }, + "b0277cd76034437997fbf5219662725a": { + "status": "processed", + "chunks_count": 2, + "chunks_list": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b", + "chunk-f894acfbb6c681d00f75cf9c486d491b" + ], + "content_summary": "远光软件股份有限公司 财务基础知识手册\n\n第一部分 会计基础知识\n\n一、会计要素\n\n会计要素包括:资产、负债、所有者权益、收入、费用和利润。\n\n会计恒等式:资产 = 负债 + 所有者权益\n\n二、常用会计科目\n\n| 科目类别 | 科目名称 | 说明 |\n| --- | --- | --- |\n| 资产类 | 库存现金 | 公司持有的现金 |\n| 资产类 | 银行存款 | 存放在银行的资金 |\n| 资产类 | 应收账款 | 因销售商品或提供劳务应收的款项 |\n| 资产类 | 固定资产 | 使用年限超...", + "content_length": 1641, + "created_at": "2026-05-23T14:29:37.233751+00:00", + "updated_at": "2026-05-23T14:30:33.605531+00:00", + "file_path": "/app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx", + "track_id": "insert_20260523_142937_5cd25327", + "metadata": { + "processing_start_time": 1779546577, + "processing_end_time": 1779546633 + } } } \ No newline at end of file diff --git a/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_entity_chunks.json b/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_entity_chunks.json index d4a82a4..c01816e 100644 --- a/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_entity_chunks.json +++ b/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_entity_chunks.json @@ -6,7 +6,6 @@ "chunk-dd87aa5bc62cc9587ecb4c26d35a5263", "chunk-31ff57cf79d009c378478f065eda9d4d", "chunk-e726f44fb0287c5192cf61b350f18abb", - "chunk-78edb0c8ccc8238159196ecaeeb08d43", "chunk-2ee7e2a66cb544bdfe1b09e133863ad1", "chunk-2c8384b328272063de4dac306a52d21e", "chunk-6c549250b13b7728acb37eb6082bc178", @@ -44,8 +43,9 @@ "chunk-6175768b05adf2e7229c16f13ee7cffd", "chunk-cfac1ddf5942f8fe2d5a296380818faf" ], - "count": 42, - "update_time": 1779467739, + "count": 41, + "updated_at": 1779546575, + "update_time": 1779546575, "_id": "远光软件股份有限公司" }, "第一章总则": { @@ -3504,31 +3504,31 @@ }, "库存现金": { "chunk_ids": [ - "chunk-31ff57cf79d009c378478f065eda9d4d", - "chunk-78edb0c8ccc8238159196ecaeeb08d43" + "chunk-31ff57cf79d009c378478f065eda9d4d" ], - "count": 2, - "update_time": 1779441756, + "count": 1, + "updated_at": 1779546575, + "update_time": 1779546575, "_id": "库存现金" }, "银行存款": { "chunk_ids": [ - "chunk-31ff57cf79d009c378478f065eda9d4d", - "chunk-78edb0c8ccc8238159196ecaeeb08d43" + "chunk-31ff57cf79d009c378478f065eda9d4d" ], - "count": 2, - "update_time": 1779441756, + "count": 1, + "updated_at": 1779546575, + "update_time": 1779546575, "_id": "银行存款" }, "应收账款": { "chunk_ids": [ "chunk-31ff57cf79d009c378478f065eda9d4d", - "chunk-78edb0c8ccc8238159196ecaeeb08d43", "chunk-6f1d6991d45799bc8ff24afaed39244d", - "chunk-af56151a803634f02e294f2d692fc1f0" + "chunk-af56151a803634f02e294f2d692fc1f0", + "chunk-f894acfbb6c681d00f75cf9c486d491b" ], "count": 4, - "update_time": 1779467128, + "update_time": 1779546632, "_id": "应收账款" }, "其他应收款": { @@ -3552,12 +3552,12 @@ "固定资产": { "chunk_ids": [ "chunk-31ff57cf79d009c378478f065eda9d4d", - "chunk-78edb0c8ccc8238159196ecaeeb08d43", "chunk-4e95fc3e38b2bf65fcb3f6f0664fd9df", "chunk-4287121b009a169fe4155526bfe413ea" ], - "count": 4, - "update_time": 1779465910, + "count": 3, + "updated_at": 1779546575, + "update_time": 1779546575, "_id": "固定资产" }, "累计折旧": { @@ -3572,39 +3572,39 @@ "应付账款": { "chunk_ids": [ "chunk-31ff57cf79d009c378478f065eda9d4d", - "chunk-78edb0c8ccc8238159196ecaeeb08d43", "chunk-6f1d6991d45799bc8ff24afaed39244d", "chunk-af56151a803634f02e294f2d692fc1f0" ], - "count": 4, - "update_time": 1779467128, + "count": 3, + "updated_at": 1779546575, + "update_time": 1779546575, "_id": "应付账款" }, "应交税费": { "chunk_ids": [ - "chunk-31ff57cf79d009c378478f065eda9d4d", - "chunk-78edb0c8ccc8238159196ecaeeb08d43" + "chunk-31ff57cf79d009c378478f065eda9d4d" ], - "count": 2, - "update_time": 1779441756, + "count": 1, + "updated_at": 1779546575, + "update_time": 1779546575, "_id": "应交税费" }, "应付职工薪酬": { "chunk_ids": [ - "chunk-31ff57cf79d009c378478f065eda9d4d", - "chunk-78edb0c8ccc8238159196ecaeeb08d43" + "chunk-31ff57cf79d009c378478f065eda9d4d" ], - "count": 2, - "update_time": 1779441756, + "count": 1, + "updated_at": 1779546575, + "update_time": 1779546575, "_id": "应付职工薪酬" }, "主营业务收入": { "chunk_ids": [ - "chunk-31ff57cf79d009c378478f065eda9d4d", - "chunk-78edb0c8ccc8238159196ecaeeb08d43" + "chunk-31ff57cf79d009c378478f065eda9d4d" ], - "count": 2, - "update_time": 1779441756, + "count": 1, + "updated_at": 1779546575, + "update_time": 1779546575, "_id": "主营业务收入" }, "主营业务成本": { @@ -3618,20 +3618,20 @@ }, "管理费用": { "chunk_ids": [ - "chunk-31ff57cf79d009c378478f065eda9d4d", - "chunk-78edb0c8ccc8238159196ecaeeb08d43" + "chunk-31ff57cf79d009c378478f065eda9d4d" ], - "count": 2, - "update_time": 1779441756, + "count": 1, + "updated_at": 1779546575, + "update_time": 1779546575, "_id": "管理费用" }, "销售费用": { "chunk_ids": [ - "chunk-31ff57cf79d009c378478f065eda9d4d", - "chunk-78edb0c8ccc8238159196ecaeeb08d43" + "chunk-31ff57cf79d009c378478f065eda9d4d" ], - "count": 2, - "update_time": 1779441756, + "count": 1, + "updated_at": 1779546575, + "update_time": 1779546575, "_id": "销售费用" }, "财务费用": { @@ -3667,11 +3667,11 @@ "资产类": { "chunk_ids": [ "chunk-31ff57cf79d009c378478f065eda9d4d", - "chunk-e726f44fb0287c5192cf61b350f18abb" + "chunk-e726f44fb0287c5192cf61b350f18abb", + "chunk-f894acfbb6c681d00f75cf9c486d491b" ], - "count": 2, - "create_time": 1779441742, - "update_time": 1779441742, + "count": 3, + "update_time": 1779546632, "_id": "资产类" }, "负债类": { @@ -3811,192 +3811,48 @@ "update_time": 1779441742, "_id": "1221其他应收款" }, - "财务基础知识手册": { - "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43" - ], - "count": 1, - "create_time": 1779441755, - "update_time": 1779441755, - "_id": "财务基础知识手册" - }, - "会计要素": { - "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43" - ], - "count": 1, - "create_time": 1779441755, - "update_time": 1779441755, - "_id": "会计要素" - }, - "资产": { - "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43" - ], - "count": 1, - "create_time": 1779441755, - "update_time": 1779441755, - "_id": "资产" - }, - "负债": { - "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43" - ], - "count": 1, - "create_time": 1779441755, - "update_time": 1779441755, - "_id": "负债" - }, - "所有者权益": { - "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43" - ], - "count": 1, - "create_time": 1779441755, - "update_time": 1779441755, - "_id": "所有者权益" - }, - "收入": { - "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43" - ], - "count": 1, - "create_time": 1779441755, - "update_time": 1779441755, - "_id": "收入" - }, - "费用": { - "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43" - ], - "count": 1, - "create_time": 1779441755, - "update_time": 1779441755, - "_id": "费用" - }, - "利润": { - "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43" - ], - "count": 1, - "create_time": 1779441756, - "update_time": 1779441756, - "_id": "利润" - }, - "会计恒等式": { - "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43" - ], - "count": 1, - "create_time": 1779441756, - "update_time": 1779441756, - "_id": "会计恒等式" - }, "增值税": { "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43", "chunk-2c8384b328272063de4dac306a52d21e", "chunk-f61c91e28e8d0f773f83e3daf161ab1c", "chunk-570642e8a00db7819c2b4048ebf1b279", "chunk-89afdbbf904b60cf6494cba2638e08a8" ], - "count": 5, - "update_time": 1779467303, - "_id": "增值税" - }, - "企业所得税": { - "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43", - "chunk-2c8384b328272063de4dac306a52d21e", - "chunk-f61c91e28e8d0f773f83e3daf161ab1c" - ], - "count": 3, - "update_time": 1779466482, - "_id": "企业所得税" - }, - "个人所得税": { - "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43", - "chunk-f61c91e28e8d0f773f83e3daf161ab1c", - "chunk-570642e8a00db7819c2b4048ebf1b279", - "chunk-89afdbbf904b60cf6494cba2638e08a8" - ], "count": 4, - "update_time": 1779467303, + "updated_at": 1779546575, + "update_time": 1779546575, + "_id": "增值税" + }, + "企业所得税": { + "chunk_ids": [ + "chunk-2c8384b328272063de4dac306a52d21e", + "chunk-f61c91e28e8d0f773f83e3daf161ab1c" + ], + "count": 2, + "updated_at": 1779546575, + "update_time": 1779546575, + "_id": "企业所得税" + }, + "个人所得税": { + "chunk_ids": [ + "chunk-f61c91e28e8d0f773f83e3daf161ab1c", + "chunk-570642e8a00db7819c2b4048ebf1b279", + "chunk-89afdbbf904b60cf6494cba2638e08a8" + ], + "count": 3, + "updated_at": 1779546575, + "update_time": 1779546575, "_id": "个人所得税" }, "印花税": { "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43", "chunk-f61c91e28e8d0f773f83e3daf161ab1c" ], - "count": 2, - "update_time": 1779466482, + "count": 1, + "updated_at": 1779546575, + "update_time": 1779546575, "_id": "印花税" }, - "三大财务报表": { - "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43" - ], - "count": 1, - "create_time": 1779441756, - "update_time": 1779441756, - "_id": "三大财务报表" - }, - "资产负债表": { - "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43" - ], - "count": 1, - "create_time": 1779441756, - "update_time": 1779441756, - "_id": "资产负债表" - }, - "利润表": { - "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43" - ], - "count": 1, - "create_time": 1779441756, - "update_time": 1779441756, - "_id": "利润表" - }, - "现金流量表": { - "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43" - ], - "count": 1, - "create_time": 1779441756, - "update_time": 1779441756, - "_id": "现金流量表" - }, - "会计基础知识": { - "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43" - ], - "count": 1, - "create_time": 1779441756, - "update_time": 1779441756, - "_id": "会计基础知识" - }, - "税务基础知识": { - "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43" - ], - "count": 1, - "create_time": 1779441757, - "update_time": 1779441757, - "_id": "税务基础知识" - }, - "财务报表解读": { - "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43" - ], - "count": 1, - "create_time": 1779441757, - "update_time": 1779441757, - "_id": "财务报表解读" - }, "财务术语解释手册": { "chunk_ids": [ "chunk-2ee7e2a66cb544bdfe1b09e133863ad1" @@ -4181,10 +4037,11 @@ "Corporate Income Tax": { "chunk_ids": [ "chunk-93d2389cdb74257e90201dccbc3f6539", - "chunk-bdfd18ae478b23604f1318623e8e9508" + "chunk-bdfd18ae478b23604f1318623e8e9508", + "chunk-6fdc554482754c7c662adc7804d3cf0b" ], - "count": 2, - "update_time": 1779466433, + "count": 3, + "update_time": 1779546632, "_id": "Corporate Income Tax" }, "Venture Capital Deduction": { @@ -5896,11 +5753,11 @@ }, "Yuan Guang Software Co., Ltd.": { "chunk_ids": [ - "chunk-96ab661ad24e0cb4c468128a58a76b6d" + "chunk-96ab661ad24e0cb4c468128a58a76b6d", + "chunk-6fdc554482754c7c662adc7804d3cf0b" ], - "count": 1, - "create_time": 1779465962, - "update_time": 1779465962, + "count": 2, + "update_time": 1779546631, "_id": "Yuan Guang Software Co., Ltd." }, "Procurement Management Methods": { @@ -12387,5 +12244,302 @@ "create_time": 1779467740, "update_time": 1779467740, "_id": "第三部分发票问题" + }, + "Accounting Elements": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546631, + "update_time": 1779546631, + "_id": "Accounting Elements" + }, + "Assets": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546631, + "update_time": 1779546631, + "_id": "Assets" + }, + "Liabilities": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546631, + "update_time": 1779546631, + "_id": "Liabilities" + }, + "Owner's Equity": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546631, + "update_time": 1779546631, + "_id": "Owner's Equity" + }, + "Revenue": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546631, + "update_time": 1779546631, + "_id": "Revenue" + }, + "Expenses": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546631, + "update_time": 1779546631, + "_id": "Expenses" + }, + "Profit": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546631, + "update_time": 1779546631, + "_id": "Profit" + }, + "Accounting Equation": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546631, + "update_time": 1779546631, + "_id": "Accounting Equation" + }, + "Common Accounting Items": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546631, + "update_time": 1779546631, + "_id": "Common Accounting Items" + }, + "Assets Category": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546631, + "update_time": 1779546631, + "_id": "Assets Category" + }, + "Liabilities Category": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546631, + "update_time": 1779546631, + "_id": "Liabilities Category" + }, + "Income And Expense Category": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546631, + "update_time": 1779546631, + "_id": "Income And Expense Category" + }, + "Cash": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546631, + "update_time": 1779546631, + "_id": "Cash" + }, + "Bank Deposits": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546631, + "update_time": 1779546631, + "_id": "Bank Deposits" + }, + "Accounts Receivable": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546631, + "update_time": 1779546631, + "_id": "Accounts Receivable" + }, + "Fixed Assets": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546631, + "update_time": 1779546631, + "_id": "Fixed Assets" + }, + "Accounts Payable": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546631, + "update_time": 1779546631, + "_id": "Accounts Payable" + }, + "Taxes Payable": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546631, + "update_time": 1779546631, + "_id": "Taxes Payable" + }, + "Employee Compensation Payable": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546631, + "update_time": 1779546631, + "_id": "Employee Compensation Payable" + }, + "Main Business Revenue": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546631, + "update_time": 1779546631, + "_id": "Main Business Revenue" + }, + "Management Expenses": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546631, + "update_time": 1779546631, + "_id": "Management Expenses" + }, + "Sales Expenses": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546631, + "update_time": 1779546631, + "_id": "Sales Expenses" + }, + "Tax Fundamentals": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546631, + "update_time": 1779546631, + "_id": "Tax Fundamentals" + }, + "Major Tax Types": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546632, + "update_time": 1779546632, + "_id": "Major Tax Types" + }, + "Value Added Tax": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546632, + "update_time": 1779546632, + "_id": "Value Added Tax" + }, + "Individual Income Tax": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546632, + "update_time": 1779546632, + "_id": "Individual Income Tax" + }, + "Stamp Duty": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546632, + "update_time": 1779546632, + "_id": "Stamp Duty" + }, + "Software Services Tax Rate 6%": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546632, + "update_time": 1779546632, + "_id": "Software Services Tax Rate 6%" + }, + "Software Product Sales Tax Rate 13%": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546632, + "update_time": 1779546632, + "_id": "Software Product Sales Tax Rate 13%" + }, + "Corporate Income Tax Rate 25%": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546632, + "update_time": 1779546632, + "_id": "Corporate Income Tax Rate 25%" + }, + "High-Tech Enterprise Preferential Tax Rate 15%": { + "chunk_ids": [ + "chunk-6fdc554482754c7c662adc7804d3cf0b" + ], + "count": 1, + "create_time": 1779546632, + "update_time": 1779546632, + "_id": "High-Tech Enterprise Preferential Tax Rate 15%" + }, + "所有者权益": { + "chunk_ids": [ + "chunk-f894acfbb6c681d00f75cf9c486d491b" + ], + "count": 1, + "create_time": 1779546632, + "update_time": 1779546632, + "_id": "所有者权益" + }, + "常用会计科目": { + "chunk_ids": [ + "chunk-f894acfbb6c681d00f75cf9c486d491b" + ], + "count": 1, + "create_time": 1779546632, + "update_time": 1779546632, + "_id": "常用会计科目" } } \ No newline at end of file diff --git a/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_full_docs.json b/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_full_docs.json index 498a951..b011990 100644 --- a/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_full_docs.json +++ b/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_full_docs.json @@ -20,13 +20,6 @@ "update_time": 1779441661, "_id": "c7601043d9944ef2bcf4d3f67ed253f7" }, - "b0277cd76034437997fbf5219662725a": { - "content": "远光软件股份有限公司\n财务基础知识手册\n第一部分 会计基础知识\n一、会计要素\n会计要素包括:资产、负债、所有者权益、收入、费用和利润。\n会计恒等式:资产 = 负债 + 所有者权益\n二、常用会计科目\n科目类别\n科目名称\n说明\n资产类\n库存现金\n公司持有的现金\n资产类\n银行存款\n存放在银行的资金\n资产类\n应收账款\n因销售商品或提供劳务应收的款项\n资产类\n固定资产\n使用年限超过一年的有形资产\n负债类\n应付账款\n因购买商品或接受劳务应付的款项\n负债类\n应交税费\n应缴纳的各种税费\n负债类\n应付职工薪酬\n应付给职工的工资、福利等\n损益类\n主营业务收入\n主要经营业务产生的收入\n损益类\n管理费用\n为管理生产经营发生的费用\n损益类\n销售费用\n为销售产品发生的费用\n第二部分 税务基础知识\n三、主要税种介绍\n(一)增值税:公司为一般纳税人,软件服务适用6%税率,软件产品销售适用13%税率。\n(二)企业所得税:税率为25%,高新技术企业享受15%优惠税率。\n(三)个人所得税:按累进税率3%-45%,由公司代扣代缴。\n(四)印花税:对经济活动中的应税凭证征收。\n第三部分 财务报表解读\n四、三大财务报表\n(一)资产负债表:反映企业在某一特定日期的财务状况。\n(二)利润表:反映企业在一定期间的经营成果。\n(三)现金流量表:反映企业在一定期间现金和现金等价物的流入和流出。\n\n# 章节导航\n\n以下内容由入库阶段从制度原文中提取,供检索时优先理解制度层级、条目和标准所在章节。\n\n- 一、会计要素\n- 二、常用会计科目\n- (四)印花税:对经济活动中的应税凭证征收。\n\n# 重点章节摘录\n\n## 一、会计要素\n\n会计要素包括:资产、负债、所有者权益、收入、费用和利润。;会计恒等式:资产 = 负债 + 所有者权益\n\n## 二、常用会计科目\n\n科目类别;科目名称;说明\n\n## (四)印花税:对经济活动中的应税凭证征收。\n\n第三部分 财务报表解读\n\n# 问答线索补充\n\n以下内容由入库阶段根据章节标题、条款、列表、键值对与相邻正文提炼,供问答检索时优先命中更短、更直接的制度依据。\n\n- 一、会计要素:会计要素包括:资产、负债、所有者权益、收入、费用和利润\n- 一、会计要素:会计恒等式:资产 = 负债 + 所有者权益\n- 二、常用会计科目:因销售商品或提供劳务应收的款项\n- 二、常用会计科目:因购买商品或接受劳务应付的款项\n- 二、常用会计科目:应缴纳的各种税费\n- 二、常用会计科目:应付职工薪酬\n- (四)印花税:对经济活动中的应税凭证征收。:第三部分 财务报表解读", - "file_path": "/app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx", - "create_time": 1779441751, - "update_time": 1779441751, - "_id": "b0277cd76034437997fbf5219662725a" - }, "23f56f159a3e4bc3b2338056544120dd": { "content": "远光软件股份有限公司\n财务术语解释手册\n权责发生制\n以权利和责任的发生来决定收入和费用归属期的会计基础。即凡是当期已经实现的收入和已经发生或应当负担的费用,不论款项是否收付,都应当作为当期的收入和费用。\n收付实现制\n以现金收到或付出为标准来记录收入的实现和费用的发生。即凡是当期收到和支付的现金,都作为当期的收入和费用。\n固定资产折旧\n固定资产在使用过程中因磨损而逐渐转移的价值。公司采用年限平均法计提折旧。\n摊销\n将无形资产或长期待摊费用按照规定期限分期计入当期损益的过程。\n增值税进项税额\n企业购进货物、接受应税劳务或应税服务支付的增值税额,可以从销项税额中抵扣。\n增值税销项税额\n企业销售货物、提供应税劳务或应税服务收取的增值税额。\n预算\n企业对未来一定时期内经营活动的数量化计划,包括收入预算、支出预算、资本预算等。\n现金流\n企业在一定期间内现金和现金等价物流入和流出的数量。\n毛利率\n毛利润占营业收入的百分比,反映企业产品或服务的初始盈利能力。计算公式:毛利率 = (营业收入 - 营业成本)/ 营业收入 × 100%\n净资产收益率(ROE)\n净利润占股东权益的百分比,反映股东投入资金的获利能力。计算公式:ROE = 净利润 / 股东权益 × 100%\n成本中心\n企业内部只发生成本费用而不产生收入的组织单位,用于成本核算和控制。\n利润中心\n企业内部既发生成本费用又产生收入的组织单位,用于考核盈利能力。\n\n# 问答线索补充\n\n以下内容由入库阶段根据章节标题、条款、列表、键值对与相邻正文提炼,供问答检索时优先命中更短、更直接的制度依据。\n\n- 正文:以权利和责任的发生来决定收入和费用归属期的会计基础\n- 正文:即凡是当期已经实现的收入和已经发生或应当负担的费用,不论款项是否收付,都应当作为当期的收入和费用\n- 正文:以现金收到或付出为标准来记录收入的实现和费用的发生\n- 正文:即凡是当期收到和支付的现金,都作为当期的收入和费用\n- 正文:企业购进货物、接受应税劳务或应税服务支付的增值税额,可以从销项税额中抵扣\n- 正文:企业销售货物、提供应税劳务或应税服务收取的增值税额\n- 正文:毛利润占营业收入的百分比,反映企业产品或服务的初始盈利能力\n- 正文:计算公式:毛利率 = (营业收入 - 营业成本)/ 营业收入 × 100%\n- 正文:净利润占股东权益的百分比,反映股东投入资金的获利能力\n- 正文:计算公式:ROE = 净利润 / 股东权益 × 100%", "file_path": "/app/server/storage/knowledge/财务知识库/远光软件财务术语解释手册.docx", @@ -257,5 +250,12 @@ "create_time": 1779467725, "update_time": 1779467725, "_id": "3acd9c2df63b4a438c7eab876269b25d" + }, + "b0277cd76034437997fbf5219662725a": { + "content": "远光软件股份有限公司 财务基础知识手册\n\n第一部分 会计基础知识\n\n一、会计要素\n\n会计要素包括:资产、负债、所有者权益、收入、费用和利润。\n\n会计恒等式:资产 = 负债 + 所有者权益\n\n二、常用会计科目\n\n| 科目类别 | 科目名称 | 说明 |\n| --- | --- | --- |\n| 资产类 | 库存现金 | 公司持有的现金 |\n| 资产类 | 银行存款 | 存放在银行的资金 |\n| 资产类 | 应收账款 | 因销售商品或提供劳务应收的款项 |\n| 资产类 | 固定资产 | 使用年限超过一年的有形资产 |\n| 负债类 | 应付账款 | 因购买商品或接受劳务应付的款项 |\n| 负债类 | 应交税费 | 应缴纳的各种税费 |\n| 负债类 | 应付职工薪酬 | 应付给职工的工资、福利等 |\n| 损益类 | 主营业务收入 | 主要经营业务产生的收入 |\n| 损益类 | 管理费用 | 为管理生产经营发生的费用 |\n| 损益类 | 销售费用 | 为销售产品发生的费用 |\n\n### 表格行级检索线索\n\n- 表格第 2 行:科目类别=资产类;科目名称=库存现金;说明=公司持有的现金\n\n- 表格第 3 行:科目类别=资产类;科目名称=银行存款;说明=存放在银行的资金\n\n- 表格第 4 行:科目类别=资产类;科目名称=应收账款;说明=因销售商品或提供劳务应收的款项\n\n- 表格第 5 行:科目类别=资产类;科目名称=固定资产;说明=使用年限超过一年的有形资产\n\n- 表格第 6 行:科目类别=负债类;科目名称=应付账款;说明=因购买商品或接受劳务应付的款项\n\n- 表格第 7 行:科目类别=负债类;科目名称=应交税费;说明=应缴纳的各种税费\n\n- 表格第 8 行:科目类别=负债类;科目名称=应付职工薪酬;说明=应付给职工的工资、福利等\n\n- 表格第 9 行:科目类别=损益类;科目名称=主营业务收入;说明=主要经营业务产生的收入\n\n- 表格第 10 行:科目类别=损益类;科目名称=管理费用;说明=为管理生产经营发生的费用\n\n- 表格第 11 行:科目类别=损益类;科目名称=销售费用;说明=为销售产品发生的费用\n\n第二部分 税务基础知识\n\n三、主要税种介绍\n\n(一)增值税:公司为一般纳税人,软件服务适用6%税率,软件产品销售适用13%税率。\n\n(二)企业所得税:税率为25%,高新技术企业享受15%优惠税率。\n\n(三)个人所得税:按累进税率3%-45%,由公司代扣代缴。\n\n(四)印花税:对经济活动中的应税凭证征收。\n\n第三部分 财务报表解读\n\n四、三大财务报表\n\n(一)资产负债表:反映企业在某一特定日期的财务状况。\n\n(二)利润表:反映企业在一定期间的经营成果。\n\n(三)现金流量表:反映企业在一定期间现金和现金等价物的流入和流出。\n\n# 章节导航\n\n以下内容由入库阶段从制度原文中提取,供检索时优先理解制度层级、条目和标准所在章节。\n\n- 一、会计要素\n- 二、常用会计科目\n\n# 重点章节摘录\n\n## 一、会计要素\n\n会计要素包括:资产、负债、所有者权益、收入、费用和利润。;会计恒等式:资产 = 负债 + 所有者权益\n\n## 二、常用会计科目\n\n| 科目类别 | 科目名称 | 说明 |;| --- | --- | --- |;| 资产类 | 库存现金 | 公司持有的现金 |\n\n# 问答线索补充\n\n以下内容由入库阶段根据章节标题、条款、列表、键值对与相邻正文提炼,供问答检索时优先命中更短、更直接的制度依据。\n\n- 一、会计要素:会计要素包括:资产、负债、所有者权益、收入、费用和利润\n- 一、会计要素:会计恒等式:资产 = 负债 + 所有者权益\n- 二、常用会计科目:表格第 2 行:科目类别=资产类\n- 二、常用会计科目:表格第 3 行:科目类别=资产类\n- 二、常用会计科目:表格第 4 行:科目类别=资产类\n- 二、常用会计科目:科目名称=应收账款", + "file_path": "/app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx", + "create_time": 1779546577, + "update_time": 1779546577, + "_id": "b0277cd76034437997fbf5219662725a" } } \ No newline at end of file diff --git a/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_full_entities.json b/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_full_entities.json index e5e1747..39deaa6 100644 --- a/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_full_entities.json +++ b/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_full_entities.json @@ -432,45 +432,6 @@ "update_time": 1779441745, "_id": "c7601043d9944ef2bcf4d3f67ed253f7" }, - "b0277cd76034437997fbf5219662725a": { - "entity_names": [ - "固定资产", - "财务报表解读", - "银行存款", - "收入", - "负债", - "现金流量表", - "企业所得税", - "三大财务报表", - "会计恒等式", - "库存现金", - "所有者权益", - "费用", - "财务基础知识手册", - "应付账款", - "利润表", - "会计基础知识", - "应收账款", - "应交税费", - "主营业务收入", - "资产", - "管理费用", - "税务基础知识", - "应付职工薪酬", - "销售费用", - "印花税", - "资产负债表", - "个人所得税", - "会计要素", - "远光软件股份有限公司", - "利润", - "增值税" - ], - "count": 31, - "create_time": 1779441772, - "update_time": 1779441772, - "_id": "b0277cd76034437997fbf5219662725a" - }, "23f56f159a3e4bc3b2338056544120dd": { "entity_names": [ "净利润", @@ -1890,5 +1851,50 @@ "create_time": 1779467727, "update_time": 1779467727, "_id": "3acd9c2df63b4a438c7eab876269b25d" + }, + "b0277cd76034437997fbf5219662725a": { + "entity_names": [ + "Fixed Assets", + "Stamp Duty", + "Liabilities", + "Revenue", + "Management Expenses", + "Accounts Receivable", + "Profit", + "Income And Expense Category", + "Software Product Sales Tax Rate 13%", + "Expenses", + "High-Tech Enterprise Preferential Tax Rate 15%", + "Software Services Tax Rate 6%", + "应收账款", + "所有者权益", + "Accounting Equation", + "资产类", + "Main Business Revenue", + "Accounts Payable", + "Employee Compensation Payable", + "Individual Income Tax", + "Liabilities Category", + "Value Added Tax", + "Bank Deposits", + "Common Accounting Items", + "常用会计科目", + "Owner's Equity", + "Accounting Elements", + "Assets Category", + "Corporate Income Tax Rate 25%", + "Yuan Guang Software Co., Ltd.", + "Assets", + "Taxes Payable", + "Corporate Income Tax", + "Tax Fundamentals", + "Cash", + "Sales Expenses", + "Major Tax Types" + ], + "count": 37, + "create_time": 1779546633, + "update_time": 1779546633, + "_id": "b0277cd76034437997fbf5219662725a" } } \ No newline at end of file diff --git a/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_full_relations.json b/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_full_relations.json index dd32edc..9e1ea8c 100644 --- a/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_full_relations.json +++ b/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_full_relations.json @@ -355,34 +355,6 @@ "update_time": 1779441745, "_id": "c7601043d9944ef2bcf4d3f67ed253f7" }, - "b0277cd76034437997fbf5219662725a": { - "relation_pairs": [ - [ - "会计要素", - "资产" - ], - [ - "财务基础知识手册", - "远光软件股份有限公司" - ], - [ - "财务基础知识手册", - "财务报表解读" - ], - [ - "税务基础知识", - "财务基础知识手册" - ], - [ - "会计基础知识", - "财务基础知识手册" - ] - ], - "count": 5, - "create_time": 1779441772, - "update_time": 1779441772, - "_id": "b0277cd76034437997fbf5219662725a" - }, "23f56f159a3e4bc3b2338056544120dd": { "relation_pairs": [ [ @@ -2194,5 +2166,21 @@ "create_time": 1779467727, "update_time": 1779467727, "_id": "3acd9c2df63b4a438c7eab876269b25d" + }, + "b0277cd76034437997fbf5219662725a": { + "relation_pairs": [ + [ + "应收账款", + "资产类" + ], + [ + "常用会计科目", + "资产类" + ] + ], + "count": 2, + "create_time": 1779546633, + "update_time": 1779546633, + "_id": "b0277cd76034437997fbf5219662725a" } } \ No newline at end of file diff --git a/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_relation_chunks.json b/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_relation_chunks.json index a230af9..6683781 100644 --- a/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_relation_chunks.json +++ b/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_relation_chunks.json @@ -746,51 +746,6 @@ "update_time": 1779441745, "_id": "1221其他应收款远光软件股份有限公司" }, - "财务基础知识手册远光软件股份有限公司": { - "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43" - ], - "count": 1, - "create_time": 1779441770, - "update_time": 1779441770, - "_id": "财务基础知识手册远光软件股份有限公司" - }, - "会计要素资产": { - "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43" - ], - "count": 1, - "create_time": 1779441770, - "update_time": 1779441770, - "_id": "会计要素资产" - }, - "会计基础知识财务基础知识手册": { - "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43" - ], - "count": 1, - "create_time": 1779441771, - "update_time": 1779441771, - "_id": "会计基础知识财务基础知识手册" - }, - "税务基础知识财务基础知识手册": { - "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43" - ], - "count": 1, - "create_time": 1779441771, - "update_time": 1779441771, - "_id": "税务基础知识财务基础知识手册" - }, - "财务基础知识手册财务报表解读": { - "chunk_ids": [ - "chunk-78edb0c8ccc8238159196ecaeeb08d43" - ], - "count": 1, - "create_time": 1779441771, - "update_time": 1779441771, - "_id": "财务基础知识手册财务报表解读" - }, "财务术语解释手册远光软件股份有限公司": { "chunk_ids": [ "chunk-2ee7e2a66cb544bdfe1b09e133863ad1" @@ -4230,5 +4185,23 @@ "create_time": 1779467726, "update_time": 1779467726, "_id": "第三部分发票问题财务报销常见问题解答" + }, + "常用会计科目资产类": { + "chunk_ids": [ + "chunk-f894acfbb6c681d00f75cf9c486d491b" + ], + "count": 1, + "create_time": 1779546632, + "update_time": 1779546632, + "_id": "常用会计科目资产类" + }, + "应收账款资产类": { + "chunk_ids": [ + "chunk-f894acfbb6c681d00f75cf9c486d491b" + ], + "count": 1, + "create_time": 1779546633, + "update_time": 1779546633, + "_id": "应收账款资产类" } } \ No newline at end of file diff --git a/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_text_chunks.json b/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_text_chunks.json index 698db4f..edae30a 100644 --- a/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_text_chunks.json +++ b/server/storage/knowledge/.lightrag/x_financial_knowledge/kv_store_text_chunks.json @@ -197,17 +197,6 @@ "update_time": 1779441661, "_id": "chunk-e726f44fb0287c5192cf61b350f18abb" }, - "chunk-78edb0c8ccc8238159196ecaeeb08d43": { - "tokens": 839, - "content": "远光软件股份有限公司\n财务基础知识手册\n第一部分 会计基础知识\n一、会计要素\n会计要素包括:资产、负债、所有者权益、收入、费用和利润。\n会计恒等式:资产 = 负债 + 所有者权益\n二、常用会计科目\n科目类别\n科目名称\n说明\n资产类\n库存现金\n公司持有的现金\n资产类\n银行存款\n存放在银行的资金\n资产类\n应收账款\n因销售商品或提供劳务应收的款项\n资产类\n固定资产\n使用年限超过一年的有形资产\n负债类\n应付账款\n因购买商品或接受劳务应付的款项\n负债类\n应交税费\n应缴纳的各种税费\n负债类\n应付职工薪酬\n应付给职工的工资、福利等\n损益类\n主营业务收入\n主要经营业务产生的收入\n损益类\n管理费用\n为管理生产经营发生的费用\n损益类\n销售费用\n为销售产品发生的费用\n第二部分 税务基础知识\n三、主要税种介绍\n(一)增值税:公司为一般纳税人,软件服务适用6%税率,软件产品销售适用13%税率。\n(二)企业所得税:税率为25%,高新技术企业享受15%优惠税率。\n(三)个人所得税:按累进税率3%-45%,由公司代扣代缴。\n(四)印花税:对经济活动中的应税凭证征收。\n第三部分 财务报表解读\n四、三大财务报表\n(一)资产负债表:反映企业在某一特定日期的财务状况。\n(二)利润表:反映企业在一定期间的经营成果。\n(三)现金流量表:反映企业在一定期间现金和现金等价物的流入和流出。\n\n# 章节导航\n\n以下内容由入库阶段从制度原文中提取,供检索时优先理解制度层级、条目和标准所在章节。\n\n- 一、会计要素\n- 二、常用会计科目\n- (四)印花税:对经济活动中的应税凭证征收。\n\n# 重点章节摘录\n\n## 一、会计要素\n\n会计要素包括:资产、负债、所有者权益、收入、费用和利润。;会计恒等式:资产 = 负债 + 所有者权益\n\n## 二、常用会计科目\n\n科目类别;科目名称;说明\n\n## (四)印花税:对经济活动中的应税凭证征收。\n\n第三部分 财务报表解读\n\n# 问答线索补充\n\n以下内容由入库阶段根据章节标题、条款、列表、键值对与相邻正文提炼,供问答检索时优先命中更短、更直接的制度依据。\n\n- 一、会计要素:会计要素包括:资产、负债、所有者权益、收入、费用和利润\n- 一、会计要素:会计恒等式:资产 = 负债 + 所有者权益\n- 二、常用会计科目:因销售商品或提供劳务应收的款项\n- 二、常用会计科目:因购买商品或接受劳务应付的款项\n- 二、常用会计科目:应缴纳的各种税费\n- 二、常用会计科目:应付职工薪酬\n- (四)印花税:对经济活动中的应税凭证征收。:第三部分 财务报表解读", - "chunk_order_index": 0, - "full_doc_id": "b0277cd76034437997fbf5219662725a", - "file_path": "/app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx", - "llm_cache_list": [], - "create_time": 1779441751, - "update_time": 1779441751, - "_id": "chunk-78edb0c8ccc8238159196ecaeeb08d43" - }, "chunk-2ee7e2a66cb544bdfe1b09e133863ad1": { "tokens": 760, "content": "远光软件股份有限公司\n财务术语解释手册\n权责发生制\n以权利和责任的发生来决定收入和费用归属期的会计基础。即凡是当期已经实现的收入和已经发生或应当负担的费用,不论款项是否收付,都应当作为当期的收入和费用。\n收付实现制\n以现金收到或付出为标准来记录收入的实现和费用的发生。即凡是当期收到和支付的现金,都作为当期的收入和费用。\n固定资产折旧\n固定资产在使用过程中因磨损而逐渐转移的价值。公司采用年限平均法计提折旧。\n摊销\n将无形资产或长期待摊费用按照规定期限分期计入当期损益的过程。\n增值税进项税额\n企业购进货物、接受应税劳务或应税服务支付的增值税额,可以从销项税额中抵扣。\n增值税销项税额\n企业销售货物、提供应税劳务或应税服务收取的增值税额。\n预算\n企业对未来一定时期内经营活动的数量化计划,包括收入预算、支出预算、资本预算等。\n现金流\n企业在一定期间内现金和现金等价物流入和流出的数量。\n毛利率\n毛利润占营业收入的百分比,反映企业产品或服务的初始盈利能力。计算公式:毛利率 = (营业收入 - 营业成本)/ 营业收入 × 100%\n净资产收益率(ROE)\n净利润占股东权益的百分比,反映股东投入资金的获利能力。计算公式:ROE = 净利润 / 股东权益 × 100%\n成本中心\n企业内部只发生成本费用而不产生收入的组织单位,用于成本核算和控制。\n利润中心\n企业内部既发生成本费用又产生收入的组织单位,用于考核盈利能力。\n\n# 问答线索补充\n\n以下内容由入库阶段根据章节标题、条款、列表、键值对与相邻正文提炼,供问答检索时优先命中更短、更直接的制度依据。\n\n- 正文:以权利和责任的发生来决定收入和费用归属期的会计基础\n- 正文:即凡是当期已经实现的收入和已经发生或应当负担的费用,不论款项是否收付,都应当作为当期的收入和费用\n- 正文:以现金收到或付出为标准来记录收入的实现和费用的发生\n- 正文:即凡是当期收到和支付的现金,都作为当期的收入和费用\n- 正文:企业购进货物、接受应税劳务或应税服务支付的增值税额,可以从销项税额中抵扣\n- 正文:企业销售货物、提供应税劳务或应税服务收取的增值税额\n- 正文:毛利润占营业收入的百分比,反映企业产品或服务的初始盈利能力\n- 正文:计算公式:毛利率 = (营业收入 - 营业成本)/ 营业收入 × 100%\n- 正文:净利润占股东权益的百分比,反映股东投入资金的获利能力\n- 正文:计算公式:ROE = 净利润 / 股东权益 × 100%", @@ -889,5 +878,27 @@ "create_time": 1779467725, "update_time": 1779467725, "_id": "chunk-cfac1ddf5942f8fe2d5a296380818faf" + }, + "chunk-6fdc554482754c7c662adc7804d3cf0b": { + "tokens": 1195, + "content": "远光软件股份有限公司 财务基础知识手册\n\n第一部分 会计基础知识\n\n一、会计要素\n\n会计要素包括:资产、负债、所有者权益、收入、费用和利润。\n\n会计恒等式:资产 = 负债 + 所有者权益\n\n二、常用会计科目\n\n| 科目类别 | 科目名称 | 说明 |\n| --- | --- | --- |\n| 资产类 | 库存现金 | 公司持有的现金 |\n| 资产类 | 银行存款 | 存放在银行的资金 |\n| 资产类 | 应收账款 | 因销售商品或提供劳务应收的款项 |\n| 资产类 | 固定资产 | 使用年限超过一年的有形资产 |\n| 负债类 | 应付账款 | 因购买商品或接受劳务应付的款项 |\n| 负债类 | 应交税费 | 应缴纳的各种税费 |\n| 负债类 | 应付职工薪酬 | 应付给职工的工资、福利等 |\n| 损益类 | 主营业务收入 | 主要经营业务产生的收入 |\n| 损益类 | 管理费用 | 为管理生产经营发生的费用 |\n| 损益类 | 销售费用 | 为销售产品发生的费用 |\n\n### 表格行级检索线索\n\n- 表格第 2 行:科目类别=资产类;科目名称=库存现金;说明=公司持有的现金\n\n- 表格第 3 行:科目类别=资产类;科目名称=银行存款;说明=存放在银行的资金\n\n- 表格第 4 行:科目类别=资产类;科目名称=应收账款;说明=因销售商品或提供劳务应收的款项\n\n- 表格第 5 行:科目类别=资产类;科目名称=固定资产;说明=使用年限超过一年的有形资产\n\n- 表格第 6 行:科目类别=负债类;科目名称=应付账款;说明=因购买商品或接受劳务应付的款项\n\n- 表格第 7 行:科目类别=负债类;科目名称=应交税费;说明=应缴纳的各种税费\n\n- 表格第 8 行:科目类别=负债类;科目名称=应付职工薪酬;说明=应付给职工的工资、福利等\n\n- 表格第 9 行:科目类别=损益类;科目名称=主营业务收入;说明=主要经营业务产生的收入\n\n- 表格第 10 行:科目类别=损益类;科目名称=管理费用;说明=为管理生产经营发生的费用\n\n- 表格第 11 行:科目类别=损益类;科目名称=销售费用;说明=为销售产品发生的费用\n\n第二部分 税务基础知识\n\n三、主要税种介绍\n\n(一)增值税:公司为一般纳税人,软件服务适用6%税率,软件产品销售适用13%税率。\n\n(二)企业所得税:税率为25%,高新技术企业享受15%优惠税率。\n\n(三)个人所得税:按累进税率3%-45%,由公司代扣代缴。\n\n(四)印花税:对经济活动中的应税凭证征收。\n\n第三部分 财务报表解读\n\n四、三大财务报表\n\n(一)资产负债表:反映企业在某一特定日期的财务状况。\n\n(二)利润表:反映企业在一定期间的经营成果。\n\n(三)现金流量表:反映企业在一定期间现金和现金等价物的流入和流出。\n\n# 章节导航\n\n以下内容由入库阶段从制度原文中提取,供检索时优先理解制度层级、条目和标准所在章节。\n\n- 一、会计要素\n- 二、常用会计科目\n\n# 重点章节摘录\n\n## 一、会计要素\n\n会计要素包括:资产、负债、所有者权益、收入、费用和利润。;会计恒等式:资产 = 负债 + 所有者权益\n\n## 二、常用会计科目\n\n| 科目类别 | 科目名称 | 说明 |;| --- | --- | --- |;| 资产类 | 库存现金 | 公司持有的现金 |\n\n# 问答线索补充\n\n以下内容由入库阶段根据章节标题、条款、列表、键值对与相邻正文提炼,供问答检索时优先命中更短、更直接的制度依据。\n\n- 一、会计要素:会计要素包括:资产、负债、所有者权益、收入、费用和利润\n- 一、会计要素:会计恒等式:资产 = 负债 + 所有者权益\n- 二、常用会计科目:表格第 2 行:科目类别=资产类\n- 二、常用会计科目:表格第 3 行:科目类别=资产类\n- 二、常用会计科目:表格第 4 行:科目类别=资产类\n- 二、常用会计科目:科目名称=应收账款", + "chunk_order_index": 0, + "full_doc_id": "b0277cd76034437997fbf5219662725a", + "file_path": "/app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx", + "llm_cache_list": [], + "create_time": 1779546577, + "update_time": 1779546577, + "_id": "chunk-6fdc554482754c7c662adc7804d3cf0b" + }, + "chunk-f894acfbb6c681d00f75cf9c486d491b": { + "tokens": 95, + "content": "所有者权益\n- 二、常用会计科目:表格第 2 行:科目类别=资产类\n- 二、常用会计科目:表格第 3 行:科目类别=资产类\n- 二、常用会计科目:表格第 4 行:科目类别=资产类\n- 二、常用会计科目:科目名称=应收账款", + "chunk_order_index": 1, + "full_doc_id": "b0277cd76034437997fbf5219662725a", + "file_path": "/app/server/storage/knowledge/财务知识库/远光软件财务基础知识手册.docx", + "llm_cache_list": [], + "create_time": 1779546577, + "update_time": 1779546577, + "_id": "chunk-f894acfbb6c681d00f75cf9c486d491b" } } \ No newline at end of file diff --git a/server/tests/test_knowledge_document_extractors.py b/server/tests/test_knowledge_document_extractors.py index 341448e..8b4c6f6 100644 --- a/server/tests/test_knowledge_document_extractors.py +++ b/server/tests/test_knowledge_document_extractors.py @@ -5,6 +5,38 @@ from zipfile import ZipFile from app.services.knowledge_document_extractors import _extract_document_text_from_path +def test_extract_docx_document_text_preserves_tables_as_markdown(tmp_path) -> None: + file_path = tmp_path / "financial-basic.docx" + _write_minimal_docx_with_table( + file_path, + paragraphs=[ + "远光软件股份有限公司", + "财务基础知识手册", + "二、常用会计科目", + ], + table=[ + ["科目类别", "科目名称", "说明"], + ["资产类", "库存现金", "公司持有的现金"], + ["负债类", "应付账款", "因购买商品或接受劳务应付的款项"], + ["损益类", "销售费用", "为销售产品发生的费用"], + ], + ) + + text = _extract_document_text_from_path( + file_path=file_path, + original_name="远光软件财务基础知识手册.docx", + mime_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document", + ) + + assert "二、常用会计科目" in text + assert "| 科目类别 | 科目名称 | 说明 |" in text + assert "| 资产类 | 库存现金 | 公司持有的现金 |" in text + assert "| 负债类 | 应付账款 | 因购买商品或接受劳务应付的款项 |" in text + assert "| 损益类 | 销售费用 | 为销售产品发生的费用 |" in text + assert "表格第 2 行:科目类别=资产类;科目名称=库存现金;说明=公司持有的现金" in text + assert "科目类别\n科目名称\n说明" not in text + + def test_extract_xlsx_document_text_builds_markdown_with_row_clues(tmp_path) -> None: file_path = tmp_path / "company-expense-rules.xlsx" _write_minimal_xlsx( @@ -58,6 +90,39 @@ def test_extract_pptx_document_text_builds_markdown_slides(tmp_path) -> None: assert "- 发票、审批、预算三项要素必须齐全" in text +def _write_minimal_docx_with_table( + file_path, + *, + paragraphs: list[str], + table: list[list[str]], +) -> None: + paragraph_xml = "\n".join(f"{_docx_text_run(text)}" for text in paragraphs) + table_xml = ( + "" + + "".join( + "" + + "".join(f"{_docx_text_run(cell)}" for cell in row) + + "" + for row in table + ) + + "" + ) + document_xml = f""" + + + {paragraph_xml} + {table_xml} + + +""" + with ZipFile(file_path, "w") as archive: + archive.writestr("word/document.xml", document_xml) + + +def _docx_text_run(text: str) -> str: + return f"{text}" + + def _write_minimal_xlsx(file_path, *, sheet_name: str, rows: list[list[str]]) -> None: workbook_xml = f""" None: assert [item["candidate_id"] for item in hits] == ["ent-1", "travel-1"] +def test_build_hits_keeps_long_query_anchor_terms_for_accounting_table() -> None: + hits = KnowledgeRagService._build_hits_from_query_data( + query="远光软件财务基础知识手册里的常用会计科目是什么?", + chunks=[ + { + "chunk_id": "generic-1", + "file_path": "/tmp/doc-1__远光软件财务制度培训手册.docx", + "content": "远光软件股份有限公司财务培训内容,介绍费用报销和财务制度。", + }, + { + "chunk_id": "accounts-1", + "file_path": "/tmp/doc-2__远光软件财务基础知识手册.docx", + "content": ( + "二、常用会计科目\n\n" + "| 科目类别 | 科目名称 | 说明 |\n" + "| --- | --- | --- |\n" + "| 资产类 | 库存现金 | 公司持有的现金 |\n" + "| 损益类 | 销售费用 | 为销售产品发生的费用 |" + ), + }, + ], + entities=[], + limit=2, + ) + + assert [item["candidate_id"] for item in hits] == ["accounts-1", "generic-1"] + + def test_build_hits_prioritizes_answer_clue_appendix_for_rule_queries() -> None: hits = KnowledgeRagService._build_hits_from_query_data( query="报销时限是多少?", diff --git a/server/tests/test_ontology_service.py b/server/tests/test_ontology_service.py index fbb96f1..3efcb7a 100644 --- a/server/tests/test_ontology_service.py +++ b/server/tests/test_ontology_service.py @@ -589,6 +589,66 @@ def test_semantic_ontology_service_covers_common_expense_scene_keywords( ) +def test_semantic_ontology_service_connects_expense_application_to_ontology() -> None: + session_factory = build_session_factory() + with session_factory() as db: + result = SemanticOntologyService(db).parse( + OntologyParseRequest( + query="申请2026-06-01 ~ 2026-06-03去北京做客户现场验收,差旅预算18000元", + user_id="pytest", + context_json={ + "document_type": "expense_application", + "application_stage": "pre_approval", + "entry_source": "documents_application", + }, + ) + ) + + assert result.scenario == "expense" + assert result.intent == "draft" + assert any( + item.type == "document_type" and item.normalized_value == "expense_application" + for item in result.entities + ) + assert any( + item.type == "workflow_stage" and item.normalized_value == "pre_approval" + for item in result.entities + ) + assert any( + item.field == "document_type" and item.value == "expense_application" + for item in result.constraints + ) + assert any( + item.type == "expense_type" and item.normalized_value == "travel" + for item in result.entities + ) + + +def test_semantic_ontology_service_requires_attachment_for_meeting_application() -> None: + session_factory = build_session_factory() + with session_factory() as db: + result = SemanticOntologyService(db).parse( + OntologyParseRequest( + query="发起会务申请,2026-06-01 ~ 2026-06-02上海产品发布会,预算32000元", + user_id="pytest", + context_json={ + "document_type": "expense_application", + "application_stage": "pre_approval", + "entry_source": "documents_application", + "attachment_count": 0, + }, + ) + ) + + assert result.scenario == "expense" + assert result.intent == "draft" + assert any( + item.type == "expense_type" and item.normalized_value == "meeting" + for item in result.entities + ) + assert "attachments" in result.missing_slots + + def test_semantic_ontology_service_uses_model_parse_when_available(monkeypatch) -> None: session_factory = build_session_factory() with session_factory() as db: diff --git a/server/tests/test_risk_rule_generation.py b/server/tests/test_risk_rule_generation.py index 1ff6902..aeec1b1 100644 --- a/server/tests/test_risk_rule_generation.py +++ b/server/tests/test_risk_rule_generation.py @@ -1,18 +1,32 @@ from __future__ import annotations import json +from datetime import UTC, datetime +from decimal import Decimal from sqlalchemy import create_engine from sqlalchemy.orm import Session, sessionmaker from sqlalchemy.pool import StaticPool -from app.core.agent_enums import AgentAssetDomain, AgentAssetStatus +from app.core.agent_enums import AgentAssetDomain, AgentAssetStatus, AgentReviewStatus from app.db.base import Base from app.models.agent_asset import AgentAsset -from app.schemas.agent_asset import AgentAssetRiskRuleGenerateRequest +from app.models.financial_record import ExpenseClaim +from app.schemas.agent_asset import ( + AgentAssetReviewCreate, + AgentAssetRiskRuleGenerateRequest, + AgentAssetRiskRuleReportRequest, + AgentAssetRiskRuleSampleTestRequest, + AgentAssetRiskRuleScenarioTestRequest, + AgentAssetRiskRuleSimulationRequest, +) from app.services.agent_asset_rule_library import AgentAssetRuleLibraryManager from app.services.agent_asset_spreadsheet import RISK_RULES_LIBRARY -from app.services.risk_rule_flow_diagram import RiskRuleFlowDiagramRenderer, RiskRuleFlowDiagramSpec +from app.services.agent_assets import AgentAssetService +from app.services.risk_rule_flow_diagram import ( + RiskRuleFlowDiagramRenderer, + RiskRuleFlowDiagramSpec, +) from app.services.risk_rule_generation import RiskRuleGenerationService @@ -43,6 +57,7 @@ def test_generate_risk_rule_asset_creates_draft_json_rule(tmp_path) -> None: asset_id = service.generate_rule_asset( AgentAssetRiskRuleGenerateRequest( business_domain=AgentAssetDomain.EXPENSE, + expense_category="travel", risk_level="high", natural_language="住宿城市必须出现在本次差旅行程城市中,否则提示高风险。", ), @@ -54,12 +69,18 @@ def test_generate_risk_rule_asset_creates_draft_json_rule(tmp_path) -> None: assert asset.status == AgentAssetStatus.DRAFT.value assert asset.config_json["detail_mode"] == "json_risk" assert asset.config_json["evaluator"] == "template_rule" + assert asset.config_json["expense_category"] == "travel" + assert asset.config_json["risk_category"] == "差旅费" + assert asset.scenario_json == ["差旅费"] assert asset.current_version == "v0.1.0" file_name = asset.config_json["rule_document"]["file_name"] rule_path = tmp_path / "rules" / RISK_RULES_LIBRARY / file_name payload = json.loads(rule_path.read_text(encoding="utf-8")) assert payload["rule_code"] == asset.code + assert payload["applies_to"]["expense_categories"] == ["travel"] + assert payload["risk_category"] == "差旅费" + assert payload["metadata"]["expense_category"] == "travel" assert payload["outcomes"]["fail"]["severity"] == "high" assert payload["template_key"] == "field_compare_v1" assert payload["metadata"]["natural_language"].startswith("住宿城市") @@ -104,3 +125,206 @@ def test_risk_rule_flow_diagram_uses_risk_level_palette() -> None: assert "#dc2626" in high_svg assert high_svg.count("#dc2626") == 1 assert "#10a37f" not in high_svg + + +def test_risk_rule_requires_test_report_before_review_and_publish(tmp_path) -> None: + with build_session() as db: + manager = AgentAssetRuleLibraryManager(rule_root=tmp_path / "rules") + generator = RiskRuleGenerationService( + db, + rule_library_manager=manager, + runtime_chat_service=NullRuntimeChatService(), + ) + asset_id = generator.generate_rule_asset( + AgentAssetRiskRuleGenerateRequest( + business_domain=AgentAssetDomain.EXPENSE, + risk_level="high", + natural_language="酒店发票城市必须与行程城市一致,不一致时标记高风险。", + ), + actor="pytest", + ) + service = AgentAssetService(db) + service.rule_library_manager = manager + + asset = db.get(AgentAsset, asset_id) + assert asset is not None + try: + service.create_review( + asset_id, + AgentAssetReviewCreate( + version=asset.working_version or "v0.1.0", + reviewer="manager", + review_status=AgentReviewStatus.PENDING, + review_note="送审", + ), + actor="pytest", + ) + except PermissionError as exc: + assert "测试通过" in str(exc) + else: + raise AssertionError("未测试通过的风险规则不应允许提交审核") + + simulation = service.simulate_risk_rule_message( + asset_id, + AgentAssetRiskRuleSimulationRequest( + message="我想仿真一张酒店报销单,酒店发票城市上海,申报目的地北京,金额580元。", + ), + ) + assert simulation.execution_mode == "risk_rule_simulation" + assert simulation.ready is True + assert simulation.hit is True + assert simulation.severity == "high" + assert "不创建业务单据" in simulation.summary + assert service.get_latest_risk_rule_test_summary(asset_id).sample is None + + blocked_simulation = service.simulate_risk_rule_message( + asset_id, + AgentAssetRiskRuleSimulationRequest( + message="请识别上传单据是否命中风险规则。", + attachments=[{"name": "hotel-invoice.pdf", "content_type": "application/pdf"}], + ), + ) + assert blocked_simulation.ready is False + assert blocked_simulation.stage == "needs_recognition" + assert blocked_simulation.hit is False + assert "尚未完成识别" in blocked_simulation.summary + + db.add( + ExpenseClaim( + claim_no="TEST-CLAIM-001", + employee_name="张三", + department_name="财务部", + expense_type="住宿费", + reason="北京出差住宿", + location="北京", + amount=Decimal("300.00"), + currency="CNY", + invoice_count=0, + occurred_at=datetime.now(UTC), + created_at=datetime.now(UTC), + status="draft", + ) + ) + db.commit() + + sample = service.run_risk_rule_sample_test( + asset_id, + AgentAssetRiskRuleSampleTestRequest(), + actor="pytest", + ) + assert sample.passed is True + + scenario = service.run_risk_rule_scenario_test( + asset_id, + AgentAssetRiskRuleScenarioTestRequest(intent="用最近30天的住宿报销单试运行"), + actor="pytest", + ) + assert scenario.passed is True + assert scenario.result_json["total_count"] == 1 + + report = service.confirm_risk_rule_test_report( + asset_id, + AgentAssetRiskRuleReportRequest(confirm_passed=True), + actor="pytest", + ) + assert report.passed is True + + review = service.create_review( + asset_id, + AgentAssetReviewCreate( + version=asset.working_version or "v0.1.0", + reviewer="manager", + review_status=AgentReviewStatus.PENDING, + review_note="送审", + ), + actor="pytest", + ) + assert review.review_status == AgentReviewStatus.PENDING.value + published = service.publish_risk_rule(asset_id, actor="manager") + assert published.status == AgentAssetStatus.ACTIVE.value + assert published.published_version == asset.working_version + + disabled = service.set_risk_rule_enabled( + asset_id, + enabled=False, + actor="manager", + ) + assert disabled.config_json["enabled"] is False + rule_document = disabled.config_json["rule_document"] + manifest = manager.read_rule_library_json( + library=RISK_RULES_LIBRARY, + file_name=rule_document["file_name"], + ) + assert manifest["enabled"] is False + + attachment_required_id = generator.generate_rule_asset( + AgentAssetRiskRuleGenerateRequest( + business_domain=AgentAssetDomain.EXPENSE, + risk_level="medium", + natural_language="发票号码不能为空,缺失时进入中风险复核。", + requires_attachment=True, + ), + actor="pytest", + ) + attachment_required_asset = db.get(AgentAsset, attachment_required_id) + assert attachment_required_asset is not None + assert attachment_required_asset.config_json["requires_attachment"] is True + attachment_rule_document = attachment_required_asset.config_json["rule_document"] + attachment_manifest = manager.read_rule_library_json( + library=RISK_RULES_LIBRARY, + file_name=attachment_rule_document["file_name"], + ) + assert attachment_manifest["requires_attachment"] is True + no_attachment_simulation = service.simulate_risk_rule_message( + attachment_required_id, + AgentAssetRiskRuleSimulationRequest(message="请测试这条规则。"), + ) + assert no_attachment_simulation.ready is False + assert no_attachment_simulation.stage == "needs_attachment" + + attachment_only_simulation = service.simulate_risk_rule_message( + attachment_required_id, + AgentAssetRiskRuleSimulationRequest( + message="请识别上传单据是否命中风险规则。", + attachments=[ + { + "name": "invoice.pdf", + "content_type": "application/pdf", + "document_fields": [ + {"key": "invoice_no", "label": "发票号码", "value": "INV-001"} + ], + } + ], + ), + ) + assert attachment_only_simulation.ready is False + assert attachment_only_simulation.stage == "needs_test_intent" + + +def test_delete_unpublished_risk_rule_removes_asset_and_json_file(tmp_path) -> None: + with build_session() as db: + manager = AgentAssetRuleLibraryManager(rule_root=tmp_path / "rules") + asset_id = RiskRuleGenerationService( + db, + rule_library_manager=manager, + runtime_chat_service=NullRuntimeChatService(), + ).generate_rule_asset( + AgentAssetRiskRuleGenerateRequest( + business_domain=AgentAssetDomain.EXPENSE, + risk_level="medium", + natural_language="报销事由不能为空,缺失时进入中风险复核。", + ), + actor="pytest", + ) + asset = db.get(AgentAsset, asset_id) + assert asset is not None + file_name = asset.config_json["rule_document"]["file_name"] + rule_path = tmp_path / "rules" / RISK_RULES_LIBRARY / file_name + assert rule_path.exists() + + service = AgentAssetService(db) + service.rule_library_manager = manager + service.delete_unpublished_asset(asset_id, actor="pytest") + + assert db.get(AgentAsset, asset_id) is None + assert not rule_path.exists() diff --git a/server/tests/test_user_agent_service.py b/server/tests/test_user_agent_service.py index 946cea2..ac7220c 100644 --- a/server/tests/test_user_agent_service.py +++ b/server/tests/test_user_agent_service.py @@ -131,6 +131,8 @@ def test_user_agent_knowledge_prompt_enforces_knowledge_boundary() -> None: assert "不能用常识、外部知识或主观推断补齐缺失条件" in messages[0]["content"] assert "不能只依赖排在最前面的片段" in messages[0]["content"] assert "不能把第一列的数值直接套给后面的列名" in messages[0]["content"] + assert "最终答复必须像助手在认真回答问题" in messages[0]["content"] + assert "禁止使用“已命中”“答案整理阶段”“稍后重试”" in messages[0]["content"] assert "knowledge_evidence_blocks" in messages[0]["content"] assert '"knowledge_answer_evidence": []' in messages[1]["content"] @@ -162,8 +164,9 @@ def test_user_agent_knowledge_fallback_is_honest_and_personalized() -> None: ) assert answer.startswith("张三,您好。") - assert "答案整理阶段本轮没有及时返回" in answer - assert "先给你当前最直接的依据" in answer + assert "我先根据当前制度依据给出可以确认的部分" in answer + assert "已命中" not in answer + assert "答案整理阶段本轮没有及时返回" not in answer assert "《差旅费制度》" in answer @@ -241,6 +244,40 @@ def test_user_agent_prefers_relevant_raw_hit_over_generic_appendix() -> None: assert "组织人事部" in selected[0]["content"] +def test_user_agent_model_hit_selection_keeps_later_relevant_hits() -> None: + selected = UserAgentService._select_knowledge_model_hits( + { + "hits": [ + {"content": "一般说明一"}, + {"content": "一般说明二"}, + {"content": "一般说明三"}, + {"content": "一般说明四"}, + {"content": "一般说明五"}, + {"content": "一般说明六"}, + {"content": "一般说明七"}, + { + "content": ( + "# 问答线索补充\n\n" + "- 第二章 报销时限:差旅费应在行程结束三个月内提交;逾期不予报销出差补贴。" + ) + }, + ] + }, + question="差旅费报销时限是多少?", + ) + + assert "三个月内提交" in selected[0]["content"] + + +def test_user_agent_knowledge_terms_keep_accounting_subject_in_long_query() -> None: + terms = UserAgentService._extract_knowledge_query_terms( + "远光软件财务基础知识手册里的常用会计科目是什么?" + ) + + assert "常用会计科目" in terms + assert "会计科目" in terms + + def test_user_agent_uses_fast_knowledge_answer_without_model(monkeypatch) -> None: session_factory = build_session_factory() with session_factory() as db: @@ -286,12 +323,170 @@ def test_user_agent_uses_fast_knowledge_answer_without_model(monkeypatch) -> Non ) assert response.answer.startswith("张三,您好。") - assert "当前能直接确认的是" in response.answer + assert "**结论**" in response.answer assert "30 日内提交报销申请" in response.answer assert "## 依据" not in response.answer assert "答案整理阶段本轮没有及时返回" not in response.answer +def test_user_agent_fast_knowledge_answer_focuses_inline_section_items() -> None: + session_factory = build_session_factory() + with session_factory() as db: + ontology = SemanticOntologyService(db).parse( + OntologyParseRequest( + query="主要税种介绍", + user_id="pytest", + context_json={"session_type": "knowledge"}, + ) + ) + service = UserAgentService(db) + + answer = service._build_fast_knowledge_answer( + UserAgentRequest( + run_id=ontology.run_id, + user_id="pytest", + message="主要税种介绍", + ontology=ontology, + context_json={ + "session_type": "knowledge", + "user_input_text": "主要税种介绍", + }, + tool_payload={ + "result_type": "knowledge_search", + "hits": [ + { + "title": "财务基础知识", + "content": ( + "资产类 银行存款 企业存放在银行的款项 负债类 应付账款 " + "因购买商品或接受劳务应付的款项 负债类 应交税费 应缴纳的各种税费 " + "第二部分 税务基础知识 三、主要税种介绍 " + "(一)增值税:公司为一般纳税人,软件服务适用6%税率,软件产品销售适用13%税率。 " + "(二)企业所得税:税率为25%,高新技术企业享受15%优惠税率。 " + "(三)个人所得税:员工工资薪金由公司代扣代缴。 " + "(四)印花税:购销合同、账簿等按规定缴纳。" + ), + } + ], + }, + ), + citations=[], + ) + + assert answer is not None + assert "主要税种介绍包括:增值税、企业所得税、个人所得税、印花税" in answer + assert "软件服务适用6%税率" in answer + assert "软件产品销售适用13%税率" in answer + assert "高新技术企业享受15%优惠税率" in answer + assert "员工工资薪金由公司代扣代缴" in answer + assert "购销合同、账簿等按规定缴纳" in answer + assert "应付账款" not in answer + assert "银行存款" not in answer + + +def test_user_agent_fast_knowledge_answer_summarizes_financial_statements() -> None: + session_factory = build_session_factory() + with session_factory() as db: + ontology = SemanticOntologyService(db).parse( + OntologyParseRequest( + query="三大财务报表 是什么?", + user_id="pytest", + context_json={"session_type": "knowledge"}, + ) + ) + service = UserAgentService(db) + + answer = service._build_fast_knowledge_answer( + UserAgentRequest( + run_id=ontology.run_id, + user_id="pytest", + message="三大财务报表 是什么?", + ontology=ontology, + context_json={ + "session_type": "knowledge", + "user_input_text": "三大财务报表 是什么?", + }, + tool_payload={ + "result_type": "knowledge_search", + "hits": [ + { + "title": "财务基础知识", + "content": ( + "第三部分 财务报表解读 四、三大财务报表 " + "(一)资产负债表:反映企业在某一特定日期的财务状况。 " + "(二)利润表:反映企业在一定期间的经营成果。 " + "(三)现金流量表:反映企业在一定期间现金和现金等价物的流入和流出。" + ), + } + ], + }, + ), + citations=[], + ) + + assert answer is not None + assert "三大财务报表包括:资产负债表、利润表、现金流量表" in answer + assert "资产负债表:反映企业在某一特定日期的财务状况" in answer + assert "利润表:反映企业在一定期间的经营成果" in answer + assert "现金流量表:反映企业在一定期间现金和现金等价物的流入和流出" in answer + assert "第三部分 财务报表解读" not in answer + + +def test_user_agent_fast_knowledge_answer_expands_broad_accounting_table() -> None: + session_factory = build_session_factory() + with session_factory() as db: + ontology = SemanticOntologyService(db).parse( + OntologyParseRequest( + query="常用会计科目是什么?", + user_id="pytest", + context_json={"session_type": "knowledge"}, + ) + ) + service = UserAgentService(db) + + answer = service._build_fast_knowledge_answer( + UserAgentRequest( + run_id=ontology.run_id, + user_id="pytest", + message="常用会计科目是什么?", + ontology=ontology, + context_json={ + "session_type": "knowledge", + "user_input_text": "常用会计科目是什么?", + }, + tool_payload={ + "result_type": "knowledge_search", + "hits": [ + { + "title": "财务基础知识", + "content": ( + "二、常用会计科目\n\n" + "| 科目类别 | 科目名称 | 说明 |\n" + "| --- | --- | --- |\n" + "| 资产类 | 库存现金 | 公司持有的现金 |\n" + "| 资产类 | 银行存款 | 存放在银行的资金 |\n" + "| 资产类 | 应收账款 | 因销售商品或提供劳务应收的款项 |\n" + "| 资产类 | 固定资产 | 使用年限超过一年的有形资产 |\n" + "| 负债类 | 应付账款 | 因购买商品或接受劳务应付的款项 |\n" + "| 负债类 | 应交税费 | 应缴纳的各种税费 |\n" + "| 负债类 | 应付职工薪酬 | 应付给职工的工资、福利等 |\n" + "| 损益类 | 主营业务收入 | 主要经营业务产生的收入 |\n" + "| 损益类 | 管理费用 | 为管理生产经营发生的费用 |\n" + "| 损益类 | 销售费用 | 为销售产品发生的费用 |\n" + ), + } + ], + }, + ), + citations=[], + ) + + assert answer is not None + assert "| 科目类别 | 科目名称 | 说明 |" in answer + assert "| 资产类 | 库存现金 | 公司持有的现金 |" in answer + assert "| 负债类 | 应付职工薪酬 | 应付给职工的工资、福利等 |" in answer + assert "| 损益类 | 销售费用 | 为销售产品发生的费用 |" in answer + + def test_user_agent_fast_knowledge_answer_renders_relevant_table_preview() -> None: session_factory = build_session_factory() with session_factory() as db: @@ -337,9 +532,65 @@ def test_user_agent_fast_knowledge_answer_renders_relevant_table_preview() -> No assert answer is not None assert "| 项目 | 港澳台 | 其他地区 | 国外 |" in answer assert "| 餐补 | 75 | 55 | 140 |" in answer + assert "餐补的标准为" in answer assert "## 依据" not in answer +def test_user_agent_fast_knowledge_answer_uses_user_grade_for_table_row() -> None: + session_factory = build_session_factory() + with session_factory() as db: + ontology = SemanticOntologyService(db).parse( + OntologyParseRequest( + query="我的住宿费标准是多少?", + user_id="pytest", + context_json={"session_type": "knowledge"}, + ) + ) + service = UserAgentService(db) + + answer = service._build_fast_knowledge_answer( + UserAgentRequest( + run_id=ontology.run_id, + user_id="pytest", + message="我的住宿费标准是多少?", + ontology=ontology, + context_json={ + "name": "张三", + "grade": "P5", + "position": "实施经理", + "session_type": "knowledge", + "user_input_text": "我的住宿费标准是多少?", + }, + tool_payload={ + "result_type": "knowledge_search", + "hits": [ + { + "title": "费用报销制度", + "content": ( + "# 结构化表格补充\n\n" + "## 国内住宿限额标准\n\n" + "| 职级 | 直辖市/特区/港澳台 | 省会城市 | 其他地区 |\n" + "| --- | --- | --- | --- |\n" + "| 公司领导(P8及以上) | 800 | 500 | 400 |\n" + "| 高层经理(P7) | 700 | 450 | 400 |\n" + "| 中层经理、基层经理(P4~P6、外聘专家) | 600 | 400 | 350 |\n" + "| 其他员工 | 500 | 350 | 300 |\n" + ), + } + ], + }, + ), + citations=[], + ) + + assert answer is not None + assert answer.startswith("张三,您好。") + assert "中层经理、基层经理(P4~P6、外聘专家)的标准为" in answer + assert "| 中层经理、基层经理(P4~P6、外聘专家) | 600 | 400 | 350 |" in answer + assert "| 公司领导(P8及以上) | 800 | 500 | 400 |" not in answer + assert "| 高层经理(P7) | 700 | 450 | 400 |" not in answer + + def test_user_agent_fast_knowledge_answer_notes_missing_location_grounding() -> None: session_factory = build_session_factory() with session_factory() as db: @@ -384,6 +635,7 @@ def test_user_agent_fast_knowledge_answer_notes_missing_location_grounding() -> assert answer is not None assert "没有直接写出“北京”对应的地区档位或映射关系" in answer + assert "**说明**" in answer assert "## 依据" not in answer @@ -429,7 +681,7 @@ def test_user_agent_fast_knowledge_answer_expands_lead_in_list_items() -> None: ) assert answer is not None - assert "当前能直接确认的是" in answer + assert "**结论**" in answer assert "登机牌、高速道路通行记录" in answer assert "支付记录" in answer assert "出差审批邮件、短信、微信等" in answer diff --git a/web/src/assets/styles/app.css b/web/src/assets/styles/app.css index 6a0246f..2af0ff2 100644 --- a/web/src/assets/styles/app.css +++ b/web/src/assets/styles/app.css @@ -94,6 +94,7 @@ grid-template-rows: auto minmax(0, 1fr); overflow: hidden; } +.main.documents-main, .main.requests-main, .main.approval-main, .main.archive-main, @@ -114,6 +115,7 @@ } .workarea { min-height: 0; overflow: auto; padding: 24px; } .workarea.requests-workarea, +.workarea.documents-workarea, .workarea.approval-workarea, .workarea.archive-workarea, .workarea.policies-workarea, diff --git a/web/src/assets/styles/components/expense-application-dialog.css b/web/src/assets/styles/components/expense-application-dialog.css new file mode 100644 index 0000000..0b2a654 --- /dev/null +++ b/web/src/assets/styles/components/expense-application-dialog.css @@ -0,0 +1,330 @@ +.expense-application-mask { + position: fixed; + inset: 0; + z-index: 120; + display: flex; + align-items: center; + justify-content: center; + padding: 28px; + background: rgba(15, 23, 42, 0.26); + backdrop-filter: blur(10px); +} + +.expense-application-dialog { + width: min(1040px, calc(100vw - 56px)); + max-height: calc(100vh - 56px); + display: flex; + flex-direction: column; + overflow: hidden; + border: 1px solid #dbe5ee; + border-radius: 8px; + background: #fff; + box-shadow: 0 24px 60px rgba(15, 23, 42, 0.18); +} + +.application-dialog-header, +.application-dialog-footer { + display: flex; + align-items: center; + justify-content: space-between; + padding: 18px 22px; + border-bottom: 1px solid #e8eef4; +} + +.application-dialog-footer { + justify-content: flex-end; + gap: 12px; + border-top: 1px solid #e8eef4; + border-bottom: 0; +} + +.application-dialog-eyebrow { + display: block; + margin-bottom: 4px; + color: #059669; + font-size: 12px; + font-weight: 800; +} + +.application-dialog-header h2 { + margin: 0; + color: #102033; + font-size: 20px; + font-weight: 850; +} + +.dialog-icon-btn { + width: 36px; + height: 36px; + display: inline-flex; + align-items: center; + justify-content: center; + border: 1px solid #dbe5ee; + border-radius: 8px; + background: #fff; + color: #4b5f73; + cursor: pointer; +} + +.application-dialog-body { + display: grid; + grid-template-columns: minmax(320px, 0.92fr) minmax(420px, 1.08fr); + gap: 18px; + min-height: 0; + padding: 20px 22px; + overflow: auto; + background: #f7fafc; +} + +.application-input-panel, +.application-ontology-panel { + border: 1px solid #e1e9f0; + border-radius: 8px; + background: #fff; + padding: 18px; +} + +.application-field-label { + display: block; + margin-bottom: 10px; + color: #425466; + font-size: 13px; + font-weight: 800; +} + +.application-input-panel textarea { + width: 100%; + min-height: 132px; + resize: vertical; + border: 1px solid #cfd9e3; + border-radius: 8px; + padding: 12px; + color: #182536; + font: inherit; + line-height: 1.55; + outline: none; +} + +.application-input-panel textarea:focus { + border-color: #10b981; + box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.12); +} + +.application-example-row { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin: 14px 0; +} + +.application-example-chip { + border: 1px solid #dbe5ee; + border-radius: 8px; + background: #f8fbfd; + color: #395066; + padding: 7px 10px; + font-size: 12px; + cursor: pointer; +} + +.primary-parse-btn, +.confirm-btn, +.secondary-btn { + min-height: 38px; + display: inline-flex; + align-items: center; + justify-content: center; + gap: 8px; + border-radius: 8px; + padding: 0 16px; + font-weight: 850; + cursor: pointer; +} + +.primary-parse-btn, +.confirm-btn { + border: 0; + background: #059669; + color: #fff; +} + +.primary-parse-btn { + width: 100%; +} + +.secondary-btn { + border: 1px solid #dbe5ee; + background: #fff; + color: #395066; +} + +.primary-parse-btn:disabled, +.confirm-btn:disabled { + background: #b7c5d1; + cursor: not-allowed; +} + +.application-error { + margin: 12px 0 0; + color: #dc2626; + font-size: 13px; +} + +.ontology-panel-head { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 14px; + color: #425466; + font-size: 13px; + font-weight: 850; +} + +.ontology-panel-head strong { + color: #059669; +} + +.ontology-empty-state { + min-height: 300px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 12px; + color: #6b7c8f; + text-align: center; +} + +.ontology-empty-state i { + color: #94a3b8; + font-size: 34px; +} + +.ontology-empty-state p { + max-width: 360px; + margin: 0; + line-height: 1.6; +} + +.ontology-chip-row { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-bottom: 14px; +} + +.ontology-chip { + border-radius: 8px; + background: #eefbf5; + color: #047857; + padding: 6px 10px; + font-size: 12px; + font-weight: 800; +} + +.application-field-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 10px; +} + +.application-field-card { + min-height: 76px; + border: 1px solid #e4ebf2; + border-radius: 8px; + padding: 12px; + background: #fbfdff; +} + +.application-field-card span, +.application-reason-block span, +.application-missing-block span { + display: block; + margin-bottom: 7px; + color: #6b7c8f; + font-size: 12px; + font-weight: 800; +} + +.application-field-card strong { + color: #182536; + font-size: 15px; +} + +.application-policy-strip, +.application-reason-block, +.application-missing-block { + margin-top: 12px; + border: 1px solid #dbe5ee; + border-radius: 8px; + padding: 12px; + background: #fff; +} + +.application-policy-strip { + display: flex; + gap: 12px; + align-items: flex-start; +} + +.application-policy-strip i { + margin-top: 2px; + color: #059669; + font-size: 20px; +} + +.application-policy-strip.required { + border-color: #fed7aa; + background: #fff7ed; +} + +.application-policy-strip.required i { + color: #ea580c; +} + +.application-policy-strip strong { + color: #182536; +} + +.application-policy-strip p, +.application-reason-block p { + margin: 5px 0 0; + color: #4b5f73; + line-height: 1.55; +} + +.application-missing-block div { + display: flex; + flex-wrap: wrap; + gap: 8px; +} + +.application-missing-block em { + border-radius: 8px; + background: #fff7ed; + color: #c2410c; + padding: 5px 8px; + font-style: normal; + font-size: 12px; + font-weight: 800; +} + +@media (max-width: 860px) { + .expense-application-mask { + align-items: stretch; + padding: 14px; + } + + .expense-application-dialog { + width: 100%; + max-height: calc(100vh - 28px); + } + + .application-dialog-body { + grid-template-columns: 1fr; + } + + .application-field-grid { + grid-template-columns: 1fr; + } +} diff --git a/web/src/assets/styles/components/risk-rule-test-dialog.css b/web/src/assets/styles/components/risk-rule-test-dialog.css new file mode 100644 index 0000000..2ba56f7 --- /dev/null +++ b/web/src/assets/styles/components/risk-rule-test-dialog.css @@ -0,0 +1,741 @@ +.risk-sim-backdrop { + position: fixed; + inset: 0; + z-index: 1200; + display: flex; + align-items: center; + justify-content: center; + padding: 18px; + background: rgba(15, 23, 42, 0.44); + backdrop-filter: blur(12px); +} + +.risk-sim-modal { + width: min(1180px, 100%); + height: min(820px, calc(100vh - 36px)); + display: grid; + grid-template-rows: auto auto minmax(0, 1fr) auto; + overflow: hidden; + border: 1px solid rgba(203, 213, 225, 0.88); + border-radius: 18px; + background: #f8fafc; + box-shadow: 0 26px 70px rgba(15, 23, 42, 0.26); +} + +.risk-sim-head { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 18px; + padding: 18px 20px 14px; + border-bottom: 1px solid #e2e8f0; + background: linear-gradient(180deg, #ffffff 0%, #f8fafc 100%); +} + +.risk-sim-title span, +.risk-sim-context-panel span, +.risk-sim-result-head span, +.risk-sim-evidence span, +.risk-sim-file-strip > span { + color: #64748b; + font-size: 12px; + font-weight: 850; +} + +.risk-sim-title h3 { + margin: 4px 0 5px; + color: #0f172a; + font-size: 19px; + font-weight: 900; + line-height: 1.25; +} + +.risk-sim-title p { + margin: 0; + color: #475569; + font-size: 13px; + line-height: 1.55; +} + +.risk-sim-icon-btn, +.risk-sim-tool-btn, +.risk-sim-send-btn { + display: grid; + place-items: center; + border: 1px solid #dbe5ef; + background: #fff; + color: #475569; + cursor: pointer; +} + +.risk-sim-icon-btn { + width: 38px; + height: 38px; + border-radius: 12px; +} + +.risk-sim-meta { + display: flex; + align-items: center; + gap: 8px; + flex-wrap: wrap; + padding: 10px 20px; + border-bottom: 1px solid #e5edf5; + background: #fff; +} + +.risk-sim-meta span { + min-height: 28px; + display: inline-flex; + align-items: center; + padding: 0 10px; + border: 1px solid #e2e8f0; + border-radius: 999px; + background: #f8fafc; + color: #475569; + font-size: 12px; + font-weight: 800; +} + +.risk-sim-meta .tone-low { + border-color: #bfdbfe; + background: #eff6ff; + color: #1d4ed8; +} + +.risk-sim-meta .tone-medium { + border-color: #fed7aa; + background: #fff7ed; + color: #c2410c; +} + +.risk-sim-meta .tone-high { + border-color: #fecaca; + background: #fef2f2; + color: #b91c1c; +} + +.risk-sim-main { + min-height: 0; + display: grid; + grid-template-columns: minmax(0, 1fr) 300px; + gap: 14px; + padding: 14px; +} + +.risk-sim-dialog-panel, +.risk-sim-context-panel { + min-height: 0; + border: 1px solid #dfe8f1; + border-radius: 14px; + background: #fff; +} + +.risk-sim-dialog-panel { + display: grid; + grid-template-rows: minmax(0, 1fr) auto auto; + overflow: hidden; +} + +.risk-sim-message-list { + min-height: 0; + display: grid; + align-content: start; + gap: 14px; + overflow-y: auto; + padding: 18px; + background: #f8fafc; +} + +.risk-sim-message-row { + display: grid; + grid-template-columns: 34px minmax(0, 1fr); + gap: 10px; + align-items: start; +} + +.risk-sim-message-row.user { + grid-template-columns: minmax(0, 1fr) 34px; +} + +.risk-sim-message-row.user .risk-sim-avatar { + grid-column: 2; + grid-row: 1; +} + +.risk-sim-message-row.user .risk-sim-bubble { + grid-column: 1; + justify-self: end; + background: #0f766e; + color: #fff; +} + +.risk-sim-message-row.user .risk-sim-bubble header, +.risk-sim-message-row.user .risk-sim-bubble p { + color: #fff; +} + +.risk-sim-avatar { + width: 34px; + height: 34px; + display: grid; + place-items: center; + border: 1px solid #dbe5ef; + border-radius: 12px; + background: #fff; + color: #0f766e; +} + +.risk-sim-message-row.user .risk-sim-avatar { + color: #2563eb; +} + +.risk-sim-bubble { + max-width: min(100%, 760px); + padding: 11px 13px; + border: 1px solid #e2e8f0; + border-radius: 14px; + background: #fff; + box-shadow: 0 8px 18px rgba(15, 23, 42, 0.05); +} + +.risk-sim-bubble header { + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 6px; + color: #64748b; + font-size: 11px; +} + +.risk-sim-bubble header strong { + color: #0f172a; + font-size: 12px; + font-weight: 850; +} + +.risk-sim-bubble p { + margin: 0; + color: #1e293b; + font-size: 13px; + line-height: 1.65; + white-space: pre-wrap; +} + +.risk-sim-thinking { + display: inline-flex; + align-items: center; + gap: 8px; +} + +.risk-sim-message-files, +.risk-sim-file-strip div { + display: flex; + align-items: center; + gap: 8px; + flex-wrap: wrap; +} + +.risk-sim-message-files { + margin-top: 9px; +} + +.risk-sim-message-files span, +.risk-sim-file-chip { + min-width: 0; + max-width: 260px; + display: inline-flex; + align-items: center; + gap: 5px; + min-height: 28px; + padding: 0 9px; + border: 1px solid rgba(191, 219, 254, 0.8); + border-radius: 999px; + background: #eff6ff; + color: #1d4ed8; + font-size: 12px; + font-weight: 750; +} + +.risk-sim-message-files span { + color: #dbeafe; + border-color: rgba(219, 234, 254, 0.38); + background: rgba(255, 255, 255, 0.12); +} + +.risk-sim-result-card { + margin-top: 12px; + overflow: hidden; + border: 1px solid #e2e8f0; + border-radius: 12px; + background: #fff; +} + +.risk-sim-result-card.high { + border-color: #fecaca; +} + +.risk-sim-result-card.medium { + border-color: #fed7aa; +} + +.risk-sim-result-card.low { + border-color: #bfdbfe; +} + +.risk-sim-result-head { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + padding: 11px 12px; + border-bottom: 1px solid #edf2f7; +} + +.risk-sim-result-head strong { + display: block; + margin-top: 3px; + color: #0f172a; + font-size: 14px; + font-weight: 900; +} + +.risk-sim-result-head b { + padding: 5px 9px; + border-radius: 999px; + background: #f1f5f9; + color: #475569; + font-size: 12px; +} + +.risk-sim-result-card.high .risk-sim-result-head b { + background: #fef2f2; + color: #b91c1c; +} + +.risk-sim-result-card.medium .risk-sim-result-head b { + background: #fff7ed; + color: #c2410c; +} + +.risk-sim-result-card.low .risk-sim-result-head b { + background: #eff6ff; + color: #1d4ed8; +} + +.risk-sim-result-message { + padding: 10px 12px 0; +} + +.risk-sim-blocking-message { + padding: 10px 12px 0; + color: #92400e; +} + +.risk-sim-field-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 8px; + padding: 12px; +} + +.risk-sim-field-grid div { + min-width: 0; + padding: 9px 10px; + border: 1px solid #edf2f7; + border-radius: 10px; + background: #f8fafc; +} + +.risk-sim-field-grid span { + display: block; + color: #64748b; + font-size: 11px; + font-weight: 800; +} + +.risk-sim-field-grid strong { + display: block; + margin-top: 4px; + overflow: hidden; + color: #0f172a; + font-size: 12px; + text-overflow: ellipsis; + white-space: nowrap; +} + +.risk-sim-evidence { + display: grid; + gap: 6px; + padding: 0 12px 12px; +} + +.risk-sim-missing-fields { + display: flex; + gap: 7px; + flex-wrap: wrap; + padding: 0 12px 12px; +} + +.risk-sim-missing-fields span { + flex: 0 0 100%; + color: #92400e; + font-size: 12px; + font-weight: 850; +} + +.risk-sim-missing-fields b { + min-height: 26px; + display: inline-flex; + align-items: center; + padding: 0 8px; + border: 1px solid #fed7aa; + border-radius: 999px; + background: #fff7ed; + color: #c2410c; + font-size: 11px; + font-weight: 850; +} + +.risk-sim-evidence ul { + display: grid; + gap: 5px; + margin: 0; + padding-left: 18px; + color: #334155; + font-size: 12px; + line-height: 1.55; +} + +.risk-sim-file-strip { + display: grid; + gap: 8px; + padding: 10px 14px; + border-top: 1px solid #e2e8f0; + background: #fff; +} + +.risk-sim-file-chip { + cursor: pointer; +} + +.risk-sim-file-chip span { + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.risk-sim-file-chip em { + color: inherit; + font-size: 11px; + font-style: normal; + opacity: 0.78; + white-space: nowrap; +} + +.risk-sim-file-chip.pending { + border-color: #dbe5ef; + background: #f8fafc; + color: #475569; +} + +.risk-sim-file-chip.recognizing { + border-color: #dbeafe; + background: #eff6ff; + color: #2563eb; +} + +.risk-sim-file-chip.recognized { + border-color: #bbf7d0; + background: #ecfdf5; + color: #047857; +} + +.risk-sim-file-chip.failed { + border-color: #fed7aa; + background: #fff7ed; + color: #c2410c; +} + +.risk-sim-composer { + display: grid; + grid-template-columns: 42px minmax(0, 1fr) 42px; + gap: 10px; + align-items: center; + padding: 12px 14px 14px; + border-top: 1px solid #e2e8f0; + background: #fff; +} + +.risk-sim-composer.text-only { + grid-template-columns: minmax(0, 1fr) 42px; +} + +.risk-sim-file-input { + display: none; +} + +.risk-sim-tool-btn, +.risk-sim-send-btn { + width: 42px; + height: 42px; + border-radius: 999px; +} + +.risk-sim-send-btn { + border-color: #0f766e; + background: #0f766e; + color: #fff; +} + +.risk-sim-tool-btn:disabled, +.risk-sim-send-btn:disabled, +.risk-sim-primary-btn:disabled, +.risk-sim-secondary-btn:disabled { + opacity: 0.48; + cursor: not-allowed; +} + +.risk-sim-composer-shell { + min-height: 42px; + display: flex; + align-items: center; + border: 1px solid #cbd5e1; + border-radius: 999px; + background: #fff; +} + +.risk-sim-composer-shell:focus-within { + border-color: rgba(15, 118, 110, 0.58); + box-shadow: 0 0 0 3px rgba(15, 118, 110, 0.1); +} + +.risk-sim-composer-shell textarea { + width: 100%; + min-height: 34px; + max-height: 110px; + resize: none; + border: 0; + padding: 8px 14px; + background: transparent; + color: #0f172a; + font-size: 13px; + line-height: 1.45; +} + +.risk-sim-composer-shell textarea:focus { + outline: none; +} + +.risk-sim-context-panel { + display: grid; + align-content: start; + gap: 12px; + padding: 14px; +} + +.risk-sim-context-panel section { + display: grid; + gap: 7px; + padding: 12px; + border: 1px solid #edf2f7; + border-radius: 12px; + background: #f8fafc; +} + +.risk-sim-step-list, +.risk-sim-recognition-list { + display: grid; + gap: 9px; +} + +.risk-sim-step { + display: grid; + grid-template-columns: 28px minmax(0, 1fr); + gap: 9px; + align-items: flex-start; + padding: 9px; + border: 1px solid #e2e8f0; + border-radius: 10px; + background: #fff; +} + +.risk-sim-step i { + width: 28px; + height: 28px; + display: grid; + place-items: center; + border-radius: 10px; + background: #f1f5f9; + color: #64748b; +} + +.risk-sim-step.done i { + background: #ecfdf5; + color: #047857; +} + +.risk-sim-step.running i { + background: #eff6ff; + color: #2563eb; +} + +.risk-sim-step.warning i { + background: #fff7ed; + color: #c2410c; +} + +.risk-sim-step strong { + color: #0f172a; + font-size: 12px; + font-weight: 900; +} + +.risk-sim-step p, +.risk-sim-recognition-list p, +.risk-sim-recognition-list small { + margin: 2px 0 0; + color: #64748b; + font-size: 11px; + line-height: 1.45; +} + +.risk-sim-recognition-list article { + min-width: 0; + padding: 9px; + border: 1px solid #e2e8f0; + border-radius: 10px; + background: #fff; +} + +.risk-sim-recognition-list article strong { + display: block; + color: #0f172a; + font-size: 12px; + font-weight: 900; +} + +.risk-sim-recognition-list small { + display: block; +} + +.risk-sim-error-text { + color: #c2410c; +} + +.risk-sim-context-panel strong { + color: #0f172a; + font-size: 14px; + font-weight: 900; +} + +.risk-sim-context-panel p, +.risk-sim-field-list em { + margin: 0; + color: #475569; + font-size: 12px; + line-height: 1.55; +} + +.risk-sim-field-list { + display: flex; + gap: 7px; + flex-wrap: wrap; +} + +.risk-sim-field-list b { + max-width: 100%; + min-height: 26px; + display: inline-flex; + align-items: center; + padding: 0 8px; + overflow: hidden; + border: 1px solid #dbe5ef; + border-radius: 999px; + background: #fff; + color: #334155; + font-size: 11px; + font-weight: 800; + text-overflow: ellipsis; + white-space: nowrap; +} + +.risk-sim-foot { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + padding: 12px 14px; + border-top: 1px solid #dfe8f1; + background: #fff; +} + +.risk-sim-foot > span { + color: #64748b; + font-size: 12px; + font-weight: 750; +} + +.risk-sim-foot div { + display: flex; + align-items: center; + gap: 10px; +} + +.risk-sim-primary-btn, +.risk-sim-secondary-btn { + min-height: 36px; + display: inline-flex; + align-items: center; + gap: 7px; + padding: 0 13px; + border-radius: 10px; + font-size: 13px; + font-weight: 850; +} + +.risk-sim-primary-btn { + border: 1px solid #0f766e; + background: #0f766e; + color: #fff; +} + +.risk-sim-secondary-btn { + border: 1px solid #dbe5ef; + background: #f8fafc; + color: #334155; +} + +.risk-sim-dialog-enter-active, +.risk-sim-dialog-leave-active { + transition: opacity 0.18s ease; +} + +.risk-sim-dialog-enter-from, +.risk-sim-dialog-leave-to { + opacity: 0; +} + +@media (max-width: 920px) { + .risk-sim-main { + grid-template-columns: 1fr; + } + + .risk-sim-context-panel { + display: none; + } + + .risk-sim-field-grid { + grid-template-columns: 1fr; + } + + .risk-sim-foot { + align-items: stretch; + flex-direction: column; + } + + .risk-sim-foot div { + justify-content: flex-end; + } +} diff --git a/web/src/assets/styles/views/audit-view-part2.css b/web/src/assets/styles/views/audit-view-part2.css index ee62fdd..a638365 100644 --- a/web/src/assets/styles/views/audit-view-part2.css +++ b/web/src/assets/styles/views/audit-view-part2.css @@ -155,6 +155,53 @@ box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.12); } +.review-submit-test-state, +.risk-rule-action-confirm, +.risk-rule-action-note { + display: grid; + gap: 6px; + padding: 10px 12px; + border: 1px solid #e2e8f0; + border-radius: 8px; + background: #f8fafc; +} + +.review-submit-test-state span, +.risk-rule-action-confirm span, +.risk-rule-action-note span { + color: #64748b; + font-size: 12px; + font-weight: 800; +} + +.review-submit-test-state strong, +.risk-rule-action-confirm strong { + color: #b45309; + font-size: 13px; + font-weight: 850; +} + +.review-submit-test-state strong.passed { + color: #047857; +} + +.review-submit-test-state p { + margin: 0; + color: #64748b; + font-size: 12px; + line-height: 1.5; +} + +.risk-rule-action-note textarea { + width: 100%; + padding: 10px 12px; + border: 1px solid #cbd5e1; + border-radius: 8px; + resize: vertical; + color: #0f172a; + font-size: 13px; +} + .review-submit-hint { margin: 0; padding: 10px 12px; @@ -847,6 +894,41 @@ grid-column: 1 / -1; } +.risk-rule-create-toggle { + display: flex !important; + align-items: flex-start; + gap: 10px; + padding: 12px; + border: 1px solid #dbe5ef; + border-radius: 10px; + background: #f8fafc; +} + +.risk-rule-create-toggle input { + width: 16px; + height: 16px; + margin-top: 3px; + accent-color: #0f766e; +} + +.risk-rule-create-toggle span { + display: grid; + gap: 3px; + min-width: 0; +} + +.risk-rule-create-toggle strong { + color: #0f172a; + font-size: 13px; + font-weight: 850; +} + +.risk-rule-create-toggle small { + color: #64748b; + font-size: 12px; + line-height: 1.5; +} + .risk-rule-create-form label span { color: #475569; font-size: 12px; @@ -949,6 +1031,20 @@ color: #059669; } +.minor-action.enable-action { + border-color: rgba(100, 116, 139, 0.26); + color: #64748b; +} + +.minor-action.enable-action.is-on { + border-color: rgba(5, 150, 105, 0.26); + color: #059669; +} + +.minor-action.enable-action i { + font-size: 18px; +} + .minor-action.danger-action { border-color: rgba(220, 38, 38, 0.2); color: #dc2626; @@ -1009,6 +1105,16 @@ color: #fff; } +.mini-btn.danger { + border-color: rgba(220, 38, 38, 0.24); + color: #dc2626; +} + +.mini-btn.warning { + border-color: rgba(245, 158, 11, 0.28); + color: #b45309; +} + @media (max-width: 1320px) { .detail-hero { grid-template-columns: 1fr; @@ -1325,16 +1431,18 @@ padding-bottom: 2px; } +.json-risk-summary-card, +.json-risk-flow-card, +.json-risk-description-card { + background: #ffffff; + border: 1px solid #e2e8f0; +} + .json-risk-flow-card { min-width: 0; overflow: hidden; } -.json-risk-description-card { - border-color: #fecdd3; - background: linear-gradient(180deg, #fffafb 0%, #ffffff 100%); -} - .json-risk-description-text { margin: 0; padding: 0 4px 8px; @@ -1348,36 +1456,109 @@ .json-risk-description-source { margin: 0; padding: 8px 12px 4px; - border-top: 1px solid #ffe4e6; + border-top: 1px solid #e2e8f0; color: #94a3b8; font-size: 12px; line-height: 1.5; } -.json-risk-summary-grid { +.json-risk-meta-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: 10px; + column-gap: 36px; + row-gap: 0; } -.json-risk-summary-grid span { - min-height: 34px; +.json-risk-meta-item { display: flex; - flex-direction: column; - gap: 4px; - padding: 10px 12px; - border-radius: 10px; - background: #f8fafc; - color: #475569; - font-size: 12px; + align-items: center; + padding: 10px 0; + border-bottom: 1px solid #f1f5f9; + font-size: 13px; + min-height: 40px; } -.json-risk-summary-grid strong { +.json-risk-meta-item.full-width { + grid-column: span 2; +} + +.json-risk-meta-label { + width: 84px; + flex-shrink: 0; + color: #64748b; + font-weight: 500; +} + +.json-risk-meta-value { color: #0f172a; + font-weight: 600; + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 6px; + min-width: 0; +} + +.meta-value-hint { + color: #64748b; + font-size: 11.5px; + font-weight: 400; + margin-left: 2px; +} + +.json-risk-meta-badge { + display: inline-flex; + align-items: center; + padding: 2px 8px; + border-radius: 999px; font-size: 11px; font-weight: 800; - text-transform: uppercase; - letter-spacing: 0.04em; + line-height: 1.2; +} + +.json-risk-meta-badge.high { + background: #fef2f2; + color: #dc2626; +} + +.json-risk-meta-badge.medium { + background: #fff7ed; + color: #ea580c; +} + +.json-risk-meta-badge.low { + background: #ecfdf5; + color: #059669; +} + +.json-risk-meta-badge.test-passed { + background: #ecfdf5; + color: #047857; +} + +.json-risk-meta-badge.test-pending { + background: #fff7ed; + color: #b45309; +} + +.meta-status-indicator { + display: inline-flex; + align-items: center; + gap: 6px; + font-size: 12.5px; + font-weight: 600; +} + +.meta-status-indicator .indicator-dot { + width: 6px; + height: 6px; + border-radius: 50%; + background: #94a3b8; +} + +.meta-status-indicator.is-active .indicator-dot { + background: #10b981; + box-shadow: 0 0 4px rgba(16, 185, 129, 0.4); } .json-risk-editor-toolbar { @@ -1403,9 +1584,12 @@ @media (max-width: 760px) { .risk-rule-create-form, - .json-risk-summary-grid { + .json-risk-meta-grid { grid-template-columns: 1fr; } + .json-risk-meta-item.full-width { + grid-column: span 1; + } } @media (max-width: 860px) { @@ -1417,4 +1601,5 @@ .json-risk-editor-actions { justify-content: flex-start; } + } diff --git a/web/src/assets/styles/views/audit-view.css b/web/src/assets/styles/views/audit-view.css index 3a792c1..ec4ed08 100644 --- a/web/src/assets/styles/views/audit-view.css +++ b/web/src/assets/styles/views/audit-view.css @@ -423,11 +423,11 @@ font-weight: 700; } -table { - width: 100%; - min-width: 1120px; - border-collapse: collapse; -} +table { + width: 100%; + min-width: 1260px; + border-collapse: collapse; +} th, td { diff --git a/web/src/assets/styles/views/documents-center-view.css b/web/src/assets/styles/views/documents-center-view.css new file mode 100644 index 0000000..dab36cd --- /dev/null +++ b/web/src/assets/styles/views/documents-center-view.css @@ -0,0 +1,720 @@ +.documents-page { + height: 100%; + min-height: 0; + display: grid; + grid-template-rows: minmax(0, 1fr); + animation: fadeUp 220ms var(--ease) both; + overflow: hidden; +} + +.documents-list { + min-height: 0; + display: grid; + grid-template-rows: auto auto minmax(0, 1fr) auto; + padding: 16px 18px; + overflow: hidden; +} + +.status-tabs { + display: flex; + gap: 28px; + margin-top: 14px; + border-bottom: 1px solid #dbe4ee; +} + +.status-tabs button { + position: relative; + min-height: 36px; + display: inline-flex; + align-items: center; + gap: 7px; + border: 0; + background: transparent; + color: #64748b; + font-size: 14px; + font-weight: 750; +} + +.status-tabs button.active { + color: #059669; +} + +.status-tabs button.active::after { + content: ""; + position: absolute; + left: 0; + right: 0; + bottom: -1px; + height: 3px; + border-radius: 999px 999px 0 0; + background: #10b981; +} + +.scope-tab-badge { + min-width: 18px; + height: 18px; + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0 5px; + border-radius: 999px; + background: #ef4444; + color: #fff; + font-size: 11px; + font-weight: 850; + line-height: 1; + box-shadow: 0 6px 14px rgba(239, 68, 68, 0.22); +} + +.document-toolbar { + display: flex; + align-items: center; + justify-content: space-between; + gap: 16px; + margin-top: 14px; +} + +.filter-set, +.document-actions { + display: flex; + align-items: center; + gap: 12px; + flex-wrap: wrap; +} + +.list-search { + position: relative; + width: 280px; +} + +.list-search .mdi { + position: absolute; + left: 12px; + top: 50%; + transform: translateY(-50%); + color: #64748b; + font-size: 15px; +} + +.list-search input { + width: 100%; + height: 38px; + padding: 0 12px 0 36px; + border: 1px solid #d7e0ea; + border-radius: 8px; + background: #fff; + color: #0f172a; + font-size: 13px; + transition: border-color 160ms ease, box-shadow 160ms ease; +} + +.list-search input::placeholder { + color: #8da0b4; +} + +.list-search input:focus { + border-color: #10b981; + box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.14); + outline: none; +} + +.filter-btn, +.page-size { + min-height: 38px; + display: inline-flex; + align-items: center; + justify-content: center; + gap: 9px; + padding: 0 14px; + border: 1px solid #d7e0ea; + border-radius: 8px; + background: #fff; + color: #334155; + font-size: 14px; + font-weight: 750; + white-space: nowrap; +} + +.filter-btn { + min-width: 120px; + justify-content: space-between; +} + +.filter-btn:hover, +.page-size:hover { + border-color: rgba(16, 185, 129, .32); + color: #0f9f78; +} + +.document-filter, +.date-range-filter { + position: relative; +} + +.document-filter-menu, +.date-range-popover, +.page-size-dropdown { + position: absolute; + z-index: 40; + border: 1px solid #d7e0ea; + border-radius: 10px; + background: #fff; + box-shadow: 0 16px 32px rgba(15, 23, 42, 0.12); + overflow: hidden; +} + +.document-filter-menu { + top: calc(100% + 8px); + left: 0; + min-width: 150px; + max-height: 280px; + padding: 6px; + overflow-y: auto; +} + +.document-filter-menu button, +.page-size-dropdown button { + display: block; + width: 100%; + min-height: 36px; + padding: 0 12px; + border: 0; + border-radius: 8px; + background: transparent; + color: #334155; + font-size: 13px; + font-weight: 650; + text-align: left; + white-space: nowrap; +} + +.document-filter-menu button:hover, +.document-filter-menu button.active { + background: rgba(16, 185, 129, 0.1); + color: #047857; +} + +.date-range-trigger { + min-width: 150px; +} + +.date-range-label { + max-width: 104px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.date-range-popover { + top: calc(100% + 8px); + left: 0; + width: 320px; + display: grid; + gap: 14px; + padding: 16px; +} + +.date-range-popover header, +.date-range-popover footer { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; +} + +.date-range-popover header strong { + color: #0f172a; + font-size: 15px; +} + +.date-range-popover header button { + width: 30px; + height: 30px; + display: grid; + place-items: center; + border: 0; + border-radius: 8px; + background: transparent; + color: #64748b; +} + +.date-range-fields { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 10px; +} + +.date-range-fields label { + display: grid; + gap: 6px; +} + +.date-range-fields span { + color: #64748b; + font-size: 12px; + font-weight: 700; +} + +.date-range-fields input { + width: 100%; + height: 38px; + padding: 0 9px; + border: 1px solid #d7e0ea; + border-radius: 8px; + color: #0f172a; + font-size: 13px; +} + +.ghost-btn, +.apply-btn { + height: 36px; + padding: 0 14px; + border-radius: 8px; + font-size: 13px; + font-weight: 750; +} + +.ghost-btn { + border: 1px solid #d7e0ea; + background: #fff; + color: #334155; +} + +.apply-btn { + border: 0; + background: #10b981; + color: #fff; +} + +.apply-btn:disabled { + cursor: not-allowed; + background: #cbd5e1; +} + +.create-request-btn { + min-height: 40px; + display: inline-flex; + align-items: center; + justify-content: center; + gap: 8px; + padding: 0 18px; + border: 0; + border-radius: 10px; + background: linear-gradient(135deg, #10b981, #059669); + color: #fff; + font-size: 14px; + font-weight: 800; + white-space: nowrap; + box-shadow: 0 10px 24px rgba(5, 150, 105, 0.2); + transition: transform 160ms ease, box-shadow 160ms ease, filter 160ms ease; +} + +.create-request-btn.secondary { + border: 1px solid #d7e0ea; + background: #fff; + color: #334155; + box-shadow: none; +} + +.create-request-btn:hover { + transform: translateY(-1px); + box-shadow: 0 14px 28px rgba(5, 150, 105, 0.24); + filter: saturate(1.02); +} + +.create-request-btn.secondary:hover { + border-color: rgba(16, 185, 129, .32); + color: #047857; + box-shadow: 0 8px 18px rgba(15, 23, 42, 0.08); +} + +.document-status-filter { + display: inline-flex; + align-items: center; + justify-content: flex-start; + gap: 10px; + min-height: 38px; +} + +.status-dropdown-filter { + min-width: 154px; +} + +.status-filter-trigger { + min-width: 154px; +} + +.status-filter-trigger > .mdi:first-child { + color: #10b981; +} + +.status-filter-menu { + min-width: 154px; +} + +.table-wrap { + min-height: 400px; + margin-top: 10px; + overflow-x: auto; + overflow-y: auto; + border: 1px solid #edf2f7; + border-radius: 10px; + background: linear-gradient(180deg, #fcfefd 0%, #f4f8f6 100%); + display: flex; + flex-direction: column; +} + +.table-wrap.is-empty { + align-items: center; + justify-content: center; +} + +.table-wrap table { + width: 100%; + align-self: flex-start; +} + +.table-state { + width: 100%; + min-height: 260px; + display: grid; + place-items: center; + gap: 10px; + padding: 28px 20px; + text-align: center; + color: #64748b; + background: linear-gradient(180deg, #fcfffd 0%, #f5f9f7 100%); +} + +.table-state .mdi { + font-size: 28px; + color: #10b981; +} + +.table-state strong { + color: #0f172a; + font-size: 15px; +} + +.table-state p { + max-width: 420px; + margin: 0; + font-size: 13px; + line-height: 1.6; +} + +.table-state.error { + background: linear-gradient(180deg, #fffdfd 0%, #fff6f6 100%); +} + +.table-state.error .mdi { + color: #ef4444; +} + +.retry-btn { + height: 36px; + padding: 0 14px; + border: 1px solid #f1c5c5; + border-radius: 8px; + background: #fff; + color: #b91c1c; + font-size: 13px; + font-weight: 750; +} + +table { + width: 100%; + min-width: 1320px; + border-collapse: collapse; + table-layout: fixed; +} + +.col-id { width: 11%; } +.col-created { width: 10%; } +.col-stay { width: 9%; } +.col-doc-type { width: 9%; } +.col-scene { width: 10%; } +.col-title { width: 18%; } +.col-amount { width: 9%; } +.col-node { width: 12%; } +.col-status { width: 8%; } +.col-updated { width: 9%; } + +th, +td { + padding: 13px 12px; + border-bottom: 1px solid #edf2f7; + color: #24324a; + font-size: 14px; + line-height: 1.35; + text-align: center; + vertical-align: middle; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +th { + position: sticky; + top: 0; + z-index: 1; + background: #f7fafc; + color: #64748b; + font-size: 13px; + font-weight: 800; +} + +tbody tr { + cursor: pointer; +} + +tbody tr:hover { + background: linear-gradient(90deg, rgba(16, 185, 129, .08), rgba(16, 185, 129, .03)); +} + +tbody tr:last-child td { + border-bottom: 0; +} + +.doc-id { + color: #059669; + font-weight: 800; +} + +.doc-kind-tag, +.type-tag, +.status-tag { + display: inline-flex; + align-items: center; + justify-content: center; + white-space: nowrap; +} + +.doc-kind-tag { + min-height: 26px; + padding: 0 10px; + border-radius: 7px; + font-size: 12px; + font-weight: 800; +} + +.doc-kind-tag.reimbursement { + background: #ecfdf5; + color: #059669; +} + +.doc-kind-tag.application { + background: #eff6ff; + color: #2563eb; +} + +.type-tag { + min-height: 26px; + padding: 0 10px; + border-radius: 999px; + font-size: 12px; + font-weight: 800; +} + +.type-tag.travel, +.type-tag.hotel, +.type-tag.transport { + background: #ecfdf5; + color: #047857; +} + +.type-tag.entertainment, +.type-tag.meal { + background: #fff7ed; + color: #ea580c; +} + +.type-tag.office { + background: #eff6ff; + color: #2563eb; +} + +.type-tag.meeting, +.type-tag.training { + background: #eef2ff; + color: #4f46e5; +} + +.type-tag.other { + background: #f8fafc; + color: #475569; +} + +.status-tag { + min-height: 24px; + padding: 0 9px; + border: 1px solid transparent; + border-radius: 6px; + font-size: 12px; + font-weight: 750; +} + +.status-tag.info { + border-color: #bfdbfe; + background: #eff6ff; + color: #2563eb; +} + +.status-tag.success, +.status-tag.archived { + border-color: #bbf7d0; + background: #ecfdf5; + color: #059669; +} + +.status-tag.warning, +.status-tag.draft { + border-color: #fed7aa; + background: #fff7ed; + color: #f97316; +} + +.status-tag.danger { + border-color: #fecaca; + background: #fef2f2; + color: #dc2626; +} + +.status-tag.neutral { + border-color: #cbd5e1; + background: #f8fafc; + color: #475569; +} + +.list-foot { + display: grid; + grid-template-columns: 1fr auto 1fr; + align-items: center; + gap: 16px; + margin-top: 12px; +} + +.page-summary { + color: #64748b; + font-size: 14px; + font-weight: 650; +} + +.pager { + display: inline-flex; + justify-content: center; + gap: 6px; + padding: 4px; + border: 1px solid #e2e8f0; + border-radius: 12px; + background: #f8fafc; +} + +.pager button { + width: 32px; + height: 32px; + border: 0; + border-radius: 9px; + background: transparent; + color: #334155; + font-size: 14px; + font-weight: 800; +} + +.pager button:hover:not(.active) { + background: #fff; + color: #059669; + box-shadow: 0 1px 4px rgba(15, 23, 42, .08); +} + +.pager button.active { + background: #059669; + color: #fff; + box-shadow: 0 8px 16px rgba(5, 150, 105, .20); +} + +.pager button:disabled { + color: #cbd5e1; + cursor: not-allowed; +} + +.page-size-wrap { + position: relative; + justify-self: end; +} + +.page-size { + min-width: 112px; + border-radius: 10px; + background: #fff; + box-shadow: 0 1px 2px rgba(15, 23, 42, .04); +} + +.page-size-dropdown { + right: 0; + bottom: calc(100% + 6px); + display: grid; +} + +.page-size-dropdown button { + border-radius: 0; + text-align: center; + padding: 0 20px; +} + +.page-size-dropdown button:hover { + background: #f0fdf4; + color: #059669; +} + +.page-size-dropdown button.active { + background: #059669; + color: #fff; +} + +@media (max-width: 1200px) { + .document-toolbar, + .list-foot { + grid-template-columns: 1fr; + } + + .document-toolbar { + align-items: stretch; + flex-direction: column; + } + + .document-actions { + justify-content: flex-start; + } +} + +@media (max-width: 760px) { + .documents-list { + padding: 16px; + } + + .status-tabs { + gap: 18px; + overflow-x: auto; + } + + .filter-set, + .document-actions, + .document-status-filter, + .list-search, + .filter-btn, + .page-size { + width: 100%; + } + + .document-status-filter { + align-items: stretch; + flex-direction: column; + gap: 6px; + } + + .list-foot { + display: grid; + justify-items: stretch; + } +} diff --git a/web/src/assets/styles/views/logs-view.css b/web/src/assets/styles/views/logs-view.css index 035bf1b..7a8c4e6 100644 --- a/web/src/assets/styles/views/logs-view.css +++ b/web/src/assets/styles/views/logs-view.css @@ -237,7 +237,7 @@ color: #475569; font-size: 12px; font-weight: 800; - text-align: left; + text-align: center; white-space: nowrap; } @@ -260,11 +260,13 @@ border-bottom: 1px solid #eef3f8; color: #0f172a; font-size: 13px; - vertical-align: top; + text-align: center; + vertical-align: middle; } .summary-cell { min-width: 220px; + text-align: left; } .summary-cell strong, @@ -301,6 +303,7 @@ display: grid; gap: 5px; align-content: start; + justify-items: center; } .status-note { @@ -632,52 +635,60 @@ display: inline-flex; align-items: center; justify-content: center; - min-width: 56px; - padding: 4px 9px; - border-radius: 999px; + padding: 3px 8px; + border-radius: 6px; font-size: 12px; - font-weight: 800; + font-weight: 600; white-space: nowrap; + border: 1px solid transparent; } .status-pill.success { background: rgba(22, 163, 74, 0.12); + border-color: rgba(22, 163, 74, 0.2); color: #166534; } .status-pill.warning { background: rgba(245, 158, 11, 0.14); + border-color: rgba(245, 158, 11, 0.25); color: #b45309; } .status-pill.danger { background: rgba(239, 68, 68, 0.14); + border-color: rgba(239, 68, 68, 0.25); color: #b91c1c; } .status-pill.muted { background: rgba(148, 163, 184, 0.14); + border-color: rgba(148, 163, 184, 0.25); color: #475569; } .status-pill.info, .level-pill.info { background: rgba(37, 99, 235, 0.12); + border-color: rgba(37, 99, 235, 0.25); color: #1d4ed8; } .level-pill.warning { background: rgba(245, 158, 11, 0.14); + border-color: rgba(245, 158, 11, 0.25); color: #b45309; } .level-pill.danger { background: rgba(239, 68, 68, 0.14); + border-color: rgba(239, 68, 68, 0.25); color: #b91c1c; } .level-pill.muted { background: rgba(148, 163, 184, 0.14); + border-color: rgba(148, 163, 184, 0.25); color: #475569; } diff --git a/web/src/components/layout/SidebarRail.vue b/web/src/components/layout/SidebarRail.vue index 13616cb..ad18a6c 100644 --- a/web/src/components/layout/SidebarRail.vue +++ b/web/src/components/layout/SidebarRail.vue @@ -84,6 +84,7 @@ const { const sidebarMeta = { overview: { label: '财务总览' }, workbench: { label: '个人工作台' }, + documents: { label: '单据中心' }, requests: { label: '报销中心' }, approval: { label: '审批中心' }, archive: { label: '归档中心' }, diff --git a/web/src/components/layout/TopBar.vue b/web/src/components/layout/TopBar.vue index 0dbfe35..0cdee3e 100644 --- a/web/src/components/layout/TopBar.vue +++ b/web/src/components/layout/TopBar.vue @@ -109,6 +109,16 @@ + + @@ -294,10 +416,9 @@ const displaySvg = computed(() => { width: 100%; min-height: 0; overflow: hidden; - border: 1px solid #e2e8f0; - border-radius: 8px; - background: #ffffff; - padding: 14px; + border: none; + background: transparent; + padding: 0; cursor: default; } @@ -442,30 +563,84 @@ const displaySvg = computed(() => { justify-content: flex-start; } -.risk-rule-flow-image, -.risk-rule-flow-svg { +.risk-rule-flow-svg-viewport { + position: relative; + width: 100%; + height: 280px; + overflow: hidden; + border-radius: 6px; + background: #ffffff; + border: 1px solid #e2e8f0; + display: flex; + align-items: center; + justify-content: center; + user-select: none; + cursor: grab; +} + +.risk-rule-flow-svg-viewport:active { + cursor: grabbing; +} + +.risk-rule-flow-svg-canvas { + width: 760px; + height: 280px; + flex-shrink: 0; +} + +.risk-rule-flow-svg-canvas :deep(svg) { + width: 100%; + height: 100%; + display: block; +} + +.diagram-zoom-controls { + position: absolute; + bottom: 12px; + right: 12px; + display: flex; + flex-direction: column; + gap: 6px; + background: rgba(255, 255, 255, 0.85); + backdrop-filter: blur(8px); + border: 1px solid #e2e8f0; + border-radius: 8px; + padding: 4px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); + z-index: 10; +} + +.zoom-btn { + width: 28px; + height: 28px; + display: grid; + place-items: center; + border: none; + border-radius: 6px; + background: transparent; + color: #475569; + cursor: pointer; + transition: all 0.2s ease; +} + +.zoom-btn:hover { + background: #f1f5f9; + color: #0f172a; +} + +.zoom-btn i { + font-size: 16px; +} + +.risk-rule-flow-image { width: min(760px, 100%); display: block; pointer-events: none; user-select: none; -} - -.risk-rule-flow-image { height: auto; object-fit: contain; } -.risk-rule-flow-svg :deep(svg) { - width: 100%; - height: auto; - display: block; -} - -.risk-rule-flow-svg :deep(*) { - pointer-events: none !important; - user-select: none; -} - @media (max-width: 980px) { .risk-rule-flow-content { grid-template-columns: 1fr; diff --git a/web/src/components/shared/RiskRuleTestDialog.vue b/web/src/components/shared/RiskRuleTestDialog.vue new file mode 100644 index 0000000..1a39929 --- /dev/null +++ b/web/src/components/shared/RiskRuleTestDialog.vue @@ -0,0 +1,792 @@ + + + + + + diff --git a/web/src/components/shared/riskRuleTestDialogUtils.js b/web/src/components/shared/riskRuleTestDialogUtils.js new file mode 100644 index 0000000..0588d1a --- /dev/null +++ b/web/src/components/shared/riskRuleTestDialogUtils.js @@ -0,0 +1,28 @@ +export function createId() { + if (typeof crypto !== 'undefined' && crypto.randomUUID) { + return crypto.randomUUID() + } + return `${Date.now()}-${Math.random().toString(16).slice(2)}` +} + +export function formatFileSize(size) { + const value = Number(size || 0) + if (value < 1024) return `${value}B` + if (value < 1024 * 1024) return `${(value / 1024).toFixed(1)}KB` + return `${(value / 1024 / 1024).toFixed(1)}MB` +} + +export function formatTestError(error, fallback) { + const message = String(error?.message || '').trim() + if (/not\s*found/i.test(message)) { + return '测试接口暂未加载或规则详情已失效,请刷新规则详情后再试。' + } + return message || fallback +} + +export function formatTime() { + return new Intl.DateTimeFormat('zh-CN', { + hour: '2-digit', + minute: '2-digit' + }).format(new Date()) +} diff --git a/web/src/composables/useAppShell.js b/web/src/composables/useAppShell.js index 3707001..09ded81 100644 --- a/web/src/composables/useAppShell.js +++ b/web/src/composables/useAppShell.js @@ -6,29 +6,30 @@ import { useNavigation, navItems } from './useNavigation.js' import { useRequests } from './useRequests.js' import { useSystemState } from './useSystemState.js' import { useToast } from './useToast.js' -import { fetchLatestConversation } from '../services/orchestrator.js' -import { clearAssistantSessionSnapshotForDraftClaim } from '../utils/assistantSessionSnapshot.js' -import { buildDetailAlerts } from '../utils/detailAlerts.js' -import { normalizeRequestForUi } from '../utils/requestViewModel.js' -import { buildWorkbenchSummary } from '../utils/workbenchSummary.js' - -const SESSION_TYPE_EXPENSE = 'expense' - -export function useAppShell() { +import { fetchLatestConversation } from '../services/orchestrator.js' +import { clearAssistantSessionSnapshotForDraftClaim } from '../utils/assistantSessionSnapshot.js' +import { buildDetailAlerts } from '../utils/detailAlerts.js' +import { normalizeRequestForUi } from '../utils/requestViewModel.js' +import { buildWorkbenchSummary } from '../utils/workbenchSummary.js' + +const SESSION_TYPE_EXPENSE = 'expense' + +export function useAppShell() { const route = useRoute() const router = useRouter() const smartEntryOpen = ref(false) - const smartEntryContext = ref({ - prompt: '', - source: 'requests', - request: null, - files: [], - conversation: null, - scope: null - }) + const smartEntryContext = ref({ + prompt: '', + source: 'requests', + request: null, + files: [], + conversation: null, + scope: null + }) const smartEntrySessionId = ref(0) const smartEntryInvalidatedDraftClaimId = ref('') + const selectedRequestSnapshot = ref(null) const { activeView, currentView, setView } = useNavigation() const { @@ -60,14 +61,32 @@ export function useAppShell() { const rawRequest = requests.value.find( (item) => String(item.claimId || '').trim() === requestId || String(item.id || '').trim() === requestId ) - return normalizeRequestForUi(rawRequest) + const normalizedRequest = normalizeRequestForUi(rawRequest) + if (normalizedRequest) { + return normalizedRequest + } + + const snapshot = normalizeRequestForUi(selectedRequestSnapshot.value) + if ( + snapshot + && ( + String(snapshot.claimId || '').trim() === requestId + || String(snapshot.id || '').trim() === requestId + || String(snapshot.documentNo || '').trim() === requestId + ) + ) { + return snapshot + } + + return null }) - const detailMode = computed(() => route.name === 'app-request-detail') + const detailMode = computed(() => ['app-request-detail', 'app-document-detail'].includes(route.name)) const logDetailMode = computed(() => route.name === 'app-log-detail') const detailAlerts = computed(() => (detailMode.value ? buildDetailAlerts(selectedRequest.value) : [])) const requestsListActive = computed(() => activeView.value === 'requests' && !detailMode.value) + const documentsListActive = computed(() => activeView.value === 'documents' && !detailMode.value) const workbenchActive = computed(() => activeView.value === 'workbench') watch(requestsListActive, (isActive, wasActive) => { @@ -76,6 +95,12 @@ export function useAppShell() { } }) + watch(documentsListActive, (isActive, wasActive) => { + if (isActive && !wasActive) { + void reloadRequests() + } + }) + watch(workbenchActive, (isActive, wasActive) => { if (isActive && !wasActive) { void reloadRequests() @@ -145,56 +170,56 @@ export function useAppShell() { setView(view) } - function openTravelCreate() { - smartEntryOpen.value = true - smartEntryContext.value = { - prompt: '', - source: 'topbar', - request: null, - files: [], - conversation: null, - scope: null - } - smartEntrySessionId.value += 1 - } + function openTravelCreate() { + smartEntryOpen.value = true + smartEntryContext.value = { + prompt: '', + source: 'topbar', + request: null, + files: [], + conversation: null, + scope: null + } + smartEntrySessionId.value += 1 + } - function resolveCurrentUserId() { - const user = currentUser.value || {} - return String(user.username || user.name || 'anonymous').trim() || 'anonymous' - } - - function resolveSmartEntryClaimScope(payload = {}) { - const request = payload.request && typeof payload.request === 'object' ? payload.request : null - const payloadScope = payload.scope && typeof payload.scope === 'object' ? payload.scope : null - const claimId = String( - payloadScope?.claimId || - payloadScope?.claim_id || - request?.claimId || - request?.claim_id || - '' - ).trim() - if (!claimId) { - return null - } - return { type: 'claim', claimId } - } - - function isDetailClaimScopedPayload(payload = {}) { - return String(payload.source || '').trim() === 'detail' && Boolean(resolveSmartEntryClaimScope(payload)) - } - - async function resolveSmartEntryConversation(payload = {}) { - if (payload.conversation) { - return payload.conversation - } - - if (isDetailClaimScopedPayload(payload)) { - return null - } - - if (!payload.restoreLatestConversation) { - return null - } + function resolveCurrentUserId() { + const user = currentUser.value || {} + return String(user.username || user.name || 'anonymous').trim() || 'anonymous' + } + + function resolveSmartEntryClaimScope(payload = {}) { + const request = payload.request && typeof payload.request === 'object' ? payload.request : null + const payloadScope = payload.scope && typeof payload.scope === 'object' ? payload.scope : null + const claimId = String( + payloadScope?.claimId || + payloadScope?.claim_id || + request?.claimId || + request?.claim_id || + '' + ).trim() + if (!claimId) { + return null + } + return { type: 'claim', claimId } + } + + function isDetailClaimScopedPayload(payload = {}) { + return String(payload.source || '').trim() === 'detail' && Boolean(resolveSmartEntryClaimScope(payload)) + } + + async function resolveSmartEntryConversation(payload = {}) { + if (payload.conversation) { + return payload.conversation + } + + if (isDetailClaimScopedPayload(payload)) { + return null + } + + if (!payload.restoreLatestConversation) { + return null + } try { const latestPayload = await fetchLatestConversation(resolveCurrentUserId(), SESSION_TYPE_EXPENSE, { @@ -208,19 +233,19 @@ export function useAppShell() { } } - async function openSmartEntry(payload = {}) { - const conversation = await resolveSmartEntryConversation(payload) - const scope = resolveSmartEntryClaimScope(payload) - smartEntryOpen.value = true - - smartEntryContext.value = { - prompt: payload.prompt ?? '', - source: payload.source ?? 'workbench', - request: payload.request ?? selectedRequest.value, - files: Array.isArray(payload.files) ? payload.files : [], - conversation, - scope - } + async function openSmartEntry(payload = {}) { + const conversation = await resolveSmartEntryConversation(payload) + const scope = resolveSmartEntryClaimScope(payload) + smartEntryOpen.value = true + + smartEntryContext.value = { + prompt: payload.prompt ?? '', + source: payload.source ?? 'workbench', + request: payload.request ?? selectedRequest.value, + files: Array.isArray(payload.files) ? payload.files : [], + conversation, + scope + } smartEntrySessionId.value += 1 } @@ -237,21 +262,23 @@ export function useAppShell() { smartEntryOpen.value = false void refreshApprovalInbox() toast(`${claimNo || '该'}单据已完成 AI预审${approvalStage ? `,当前节点:${approvalStage}` : ',并已提交审批'}。`) - router.push({ name: 'app-requests' }) + router.push({ name: activeView.value === 'documents' ? 'app-documents' : 'app-requests' }) return } toast(`${claimNo || '该'}单据已保存为草稿,可继续上传票据或补充信息。`) } function openRequestDetail(request) { + selectedRequestSnapshot.value = request || null + const routeName = activeView.value === 'documents' ? 'app-document-detail' : 'app-request-detail' router.push({ - name: 'app-request-detail', + name: routeName, params: { requestId: request.claimId || request.id } }) } function closeRequestDetail() { - router.push({ name: 'app-requests' }) + router.push({ name: activeView.value === 'documents' ? 'app-documents' : 'app-requests' }) } async function handleRequestUpdated() { @@ -268,7 +295,8 @@ export function useAppShell() { await reloadRequests() void refreshApprovalInbox() - router.push({ name: 'app-requests' }) + selectedRequestSnapshot.value = null + router.push({ name: activeView.value === 'documents' ? 'app-documents' : 'app-requests' }) } return { diff --git a/web/src/composables/useNavigation.js b/web/src/composables/useNavigation.js index 631288e..415a293 100644 --- a/web/src/composables/useNavigation.js +++ b/web/src/composables/useNavigation.js @@ -3,7 +3,7 @@ import { useRoute, useRouter } from 'vue-router' import { icons } from '../data/icons.js' -export const appViews = ['overview', 'workbench', 'requests', 'approval', 'archive', 'policies', 'audit', 'employees', 'logs', 'settings'] +export const appViews = ['overview', 'workbench', 'documents', 'requests', 'approval', 'archive', 'policies', 'audit', 'employees', 'logs', 'settings'] export const navItems = [ { @@ -22,6 +22,14 @@ export const navItems = [ title: '个人工作台', desc: '聚焦当前待办、快捷操作与助手入口。' }, + { + id: 'documents', + label: '单据中心', + navHint: '统一查看申请、报销、审批与归档', + icon: icons.file, + title: '单据中心', + desc: '统一查看申请、报销、审批与归档。' + }, { id: 'requests', label: '报销中心', @@ -91,6 +99,7 @@ export const navItems = [ const viewRouteNames = { overview: 'app-overview', workbench: 'app-workbench', + documents: 'app-documents', requests: 'app-requests', approval: 'app-approval', archive: 'app-archive', @@ -106,6 +115,7 @@ const routeNameViews = Object.fromEntries( ) routeNameViews['app-request-detail'] = 'requests' +routeNameViews['app-document-detail'] = 'documents' routeNameViews['app-log-detail'] = 'logs' export function resolveAppViewFromRoute(route) { diff --git a/web/src/composables/useSettings.js b/web/src/composables/useSettings.js index 975a21e..9db9464 100644 --- a/web/src/composables/useSettings.js +++ b/web/src/composables/useSettings.js @@ -114,6 +114,7 @@ export function useSettings() { adminForm: { ...pageState.value.adminForm }, sessionForm: { ...pageState.value.sessionForm }, llmForm: buildLlmPayload(pageState.value.llmForm), + hermesForm: { ...pageState.value.hermesForm }, renderForm: buildRenderPayload(pageState.value.renderForm), logForm: { ...pageState.value.logForm }, mailForm: { ...pageState.value.mailForm } diff --git a/web/src/router/index.js b/web/src/router/index.js index e4907b1..25cb501 100644 --- a/web/src/router/index.js +++ b/web/src/router/index.js @@ -10,7 +10,7 @@ import LoginRouteView from '../views/LoginRouteView.vue' import SetupRouteView from '../views/SetupRouteView.vue' const appChildRoutes = appViews - .filter((view) => view !== 'requests') + .filter((view) => view !== 'requests' && view !== 'documents') .map((view) => ({ path: view, name: `app-${view}`, @@ -51,6 +51,24 @@ const router = createRouter({ path: '/app', redirect: { name: 'app-overview' } }, + { + path: '/app/documents', + name: 'app-documents', + component: AppShellRouteView, + meta: { + requiresAuth: true, + appView: 'documents' + } + }, + { + path: '/app/documents/:requestId', + name: 'app-document-detail', + component: AppShellRouteView, + meta: { + requiresAuth: true, + appView: 'documents' + } + }, { path: '/app/requests', name: 'app-requests', diff --git a/web/src/services/agentAssets.js b/web/src/services/agentAssets.js index da11683..cca6f2a 100644 --- a/web/src/services/agentAssets.js +++ b/web/src/services/agentAssets.js @@ -154,6 +154,72 @@ export function generateRiskRuleAsset(payload, options = {}) { }) } +export function fetchRiskRuleLatestTest(assetId) { + return apiRequest(`/agent-assets/${assetId}/risk-rule-tests/latest`) +} + +export function runRiskRuleSampleTest(assetId, payload, options = {}) { + return apiRequest(`/agent-assets/${assetId}/risk-rule-tests/sample`, { + method: 'POST', + body: JSON.stringify(payload || {}), + headers: buildWriteHeaders(options) + }) +} + +export function simulateRiskRuleTest(assetId, payload, options = {}) { + return apiRequest(`/agent-assets/${assetId}/risk-rule-tests/simulate`, { + method: 'POST', + body: JSON.stringify(payload || {}), + headers: buildWriteHeaders(options) + }) +} + +export function runRiskRuleScenarioTest(assetId, payload, options = {}) { + return apiRequest(`/agent-assets/${assetId}/risk-rule-tests/scenario`, { + method: 'POST', + body: JSON.stringify(payload || {}), + headers: buildWriteHeaders(options) + }) +} + +export function confirmRiskRuleTestReport(assetId, payload, options = {}) { + return apiRequest(`/agent-assets/${assetId}/risk-rule-tests/report`, { + method: 'POST', + body: JSON.stringify(payload || {}), + headers: buildWriteHeaders(options) + }) +} + +export function deleteAgentAsset(assetId, options = {}) { + return apiRequest(`/agent-assets/${assetId}`, { + method: 'DELETE', + headers: buildWriteHeaders(options) + }) +} + +export function returnRiskRuleAsset(assetId, payload, options = {}) { + return apiRequest(`/agent-assets/${assetId}/return`, { + method: 'POST', + body: JSON.stringify(payload || {}), + headers: buildWriteHeaders(options) + }) +} + +export function publishRiskRuleAsset(assetId, options = {}) { + return apiRequest(`/agent-assets/${assetId}/publish`, { + method: 'POST', + headers: buildWriteHeaders(options) + }) +} + +export function setRiskRuleAssetEnabled(assetId, enabled, options = {}) { + return apiRequest(`/agent-assets/${assetId}/risk-rule-enabled`, { + method: 'POST', + body: JSON.stringify({ enabled: Boolean(enabled) }), + headers: buildWriteHeaders(options) + }) +} + export function fetchAgentAssetSpreadsheetChangeRecords(assetId, limit = 30) { return apiRequest( `/agent-assets/${assetId}/spreadsheet/change-records${buildQuery({ limit })}` diff --git a/web/src/utils/accessControl.js b/web/src/utils/accessControl.js index d866917..7761ffa 100644 --- a/web/src/utils/accessControl.js +++ b/web/src/utils/accessControl.js @@ -1,6 +1,7 @@ export const DEFAULT_APP_VIEW_ORDER = [ 'overview', 'workbench', + 'documents', 'requests', 'approval', 'archive', @@ -11,7 +12,7 @@ export const DEFAULT_APP_VIEW_ORDER = [ 'settings' ] -const ALWAYS_VISIBLE_VIEWS = new Set(['workbench', 'requests', 'policies']) +const ALWAYS_VISIBLE_VIEWS = new Set(['workbench', 'documents', 'requests', 'policies']) const VIEW_ROLE_RULES = { overview: ['finance', 'executive'], approval: ['approver', 'finance', 'executive'], diff --git a/web/src/utils/documentCenterTime.js b/web/src/utils/documentCenterTime.js new file mode 100644 index 0000000..489bae6 --- /dev/null +++ b/web/src/utils/documentCenterTime.js @@ -0,0 +1,76 @@ +function toDate(value) { + if (!value) { + return null + } + + const nextDate = new Date(value) + return Number.isNaN(nextDate.getTime()) ? null : nextDate +} + +export function extractDateText(value) { + const matched = String(value || '').match(/\d{4}-\d{2}-\d{2}/) + return matched ? matched[0] : '' +} + +export function formatDocumentListTime(value) { + const raw = String(value || '').trim() + if (!raw || raw === '待补充') { + return '待补充' + } + + const date = toDate(raw) + if (date) { + const month = String(date.getMonth() + 1).padStart(2, '0') + const day = String(date.getDate()).padStart(2, '0') + const hour = String(date.getHours()).padStart(2, '0') + const minute = String(date.getMinutes()).padStart(2, '0') + return `${month}-${day} ${hour}:${minute}` + } + + return raw.replace(/^\d{4}-/, '').slice(0, 11) +} + +export function resolveDocumentSortTime(value) { + const date = toDate(value) + return date ? date.getTime() : 0 +} + +export function formatDocumentDurationSince(value, now = Date.now()) { + const startAt = toDate(value) + if (!startAt) { + return '' + } + + const diffMs = Math.max(0, Number(now) - startAt.getTime()) + const totalMinutes = Math.floor(diffMs / (60 * 1000)) + if (totalMinutes < 1) { + return '刚刚' + } + + const days = Math.floor(totalMinutes / (24 * 60)) + const hours = Math.floor((totalMinutes % (24 * 60)) / 60) + const minutes = totalMinutes % 60 + + if (days > 0) { + return hours > 0 ? `${days}天${hours}小时` : `${days}天` + } + + if (hours > 0) { + return minutes > 0 ? `${hours}小时${minutes}分钟` : `${hours}小时` + } + + return `${minutes}分钟` +} + +export function resolveDocumentStayTimeDisplay(row, now = Date.now()) { + const currentStep = Array.isArray(row?.progressSteps) + ? row.progressSteps.find((step) => step?.current) + : null + const stepTime = String(currentStep?.time || '').trim() + if (stepTime.startsWith('停留')) { + return stepTime.replace(/^停留\s*/, '') || '待计算' + } + + const startedAt = row?.updatedAt || row?.submittedAt || row?.createdAt || row?.applyTime + return formatDocumentDurationSince(startedAt, now) || '待计算' +} diff --git a/web/src/utils/expenseApplicationOntology.js b/web/src/utils/expenseApplicationOntology.js new file mode 100644 index 0000000..cfa1400 --- /dev/null +++ b/web/src/utils/expenseApplicationOntology.js @@ -0,0 +1,158 @@ +const EXPENSE_TYPE_LABELS = { + travel: '差旅费', + hotel: '住宿费', + transport: '交通费', + meal: '业务招待费', + entertainment: '业务招待费', + meeting: '会务费', + office: '办公用品费', + training: '培训费', + communication: '通讯费', + welfare: '福利费', + other: '其他费用' +} + +const SLOT_LABELS = { + expense_type: '费用场景', + amount: '申请金额', + time_range: '业务时间', + reason: '申请事由', + attachments: '附件说明', + customer_name: '客户名称', + participants: '参与人员' +} + +const PRE_APPROVAL_TYPES = new Set(['travel', 'meeting', 'office', 'training']) +const ATTACHMENT_REQUIRED_TYPES = new Set(['meeting', 'training']) + +export const APPLICATION_EXAMPLES = [ + '申请下周去北京做客户现场验收,差旅预算18000元', + '申请上海产品发布会会务费32000元,需要场地和物料', + '申请部门集中采购办公用品4800元,用于新员工入职' +] + +export function buildExpenseApplicationOntologyContext(currentUser = {}) { + return { + document_type: 'expense_application', + application_stage: 'pre_approval', + conversation_scenario: 'expense', + entry_source: 'documents_application', + role_codes: Array.isArray(currentUser.roleCodes) ? currentUser.roleCodes : [], + is_admin: Boolean(currentUser.isAdmin), + name: currentUser.name || '', + role: currentUser.role || '', + department: currentUser.department || currentUser.departmentName || '', + department_name: currentUser.department || currentUser.departmentName || '', + position: currentUser.position || '', + grade: currentUser.grade || '', + employee_no: currentUser.employeeNo || currentUser.employee_no || '' + } +} + +export function resolveEntity(ontology, type) { + const entities = Array.isArray(ontology?.entities) ? ontology.entities : [] + return entities.find((item) => item?.type === type) || null +} + +export function resolveConstraint(ontology, field) { + const constraints = Array.isArray(ontology?.constraints) ? ontology.constraints : [] + return constraints.find((item) => item?.field === field) || null +} + +export function resolveExpenseTypeCode(ontology) { + const entity = resolveEntity(ontology, 'expense_type') + return String(entity?.normalized_value || entity?.value || 'other').trim() || 'other' +} + +export function resolveExpenseTypeLabel(code) { + return EXPENSE_TYPE_LABELS[String(code || '').trim()] || EXPENSE_TYPE_LABELS.other +} + +export function resolveApplicationAmount(ontology) { + const amountEntity = resolveEntity(ontology, 'amount') + const amountConstraint = resolveConstraint(ontology, 'amount') + const rawValue = amountEntity?.normalized_value || amountEntity?.value || amountConstraint?.value || '' + const numericValue = Number(String(rawValue).replace(/[^\d.]/g, '')) + return { + raw: String(rawValue || '').trim(), + value: Number.isFinite(numericValue) ? numericValue : 0 + } +} + +export function resolveTimeRangeText(ontology) { + const range = ontology?.time_range || {} + if (range.start_date && range.end_date) { + return range.start_date === range.end_date + ? range.start_date + : `${range.start_date} 至 ${range.end_date}` + } + return String(range.raw || '').trim() +} + +export function resolveAttachmentPolicy(expenseTypeCode, amount = 0) { + const code = String(expenseTypeCode || '').trim() + if (ATTACHMENT_REQUIRED_TYPES.has(code)) { + return { + level: 'required', + label: '必须提交', + description: code === 'meeting' + ? '需补充会议通知、议程、参会范围或预算说明。' + : '需补充培训通知、课程说明、报价或审批依据。' + } + } + if (code === 'office' && amount >= 5000) { + return { + level: 'required', + label: '必须提交', + description: '办公采购金额较高,需补充采购清单、报价或预算说明。' + } + } + if (code === 'travel') { + return { + level: 'optional', + label: '说明可选', + description: '可先提交出差目的、时间和预算;行程或邀请材料可作为补充说明。' + } + } + return { + level: 'none', + label: '无需附件', + description: '当前申请事项可先不提交附件,后续报销阶段再按票据要求补充。' + } +} + +export function buildApplicationFieldsFromOntology(ontology, prompt, currentUser = {}) { + const expenseTypeCode = resolveExpenseTypeCode(ontology) + const amount = resolveApplicationAmount(ontology) + const locationEntity = resolveEntity(ontology, 'location') + const documentTypeEntity = resolveEntity(ontology, 'document_type') + const workflowStageEntity = resolveEntity(ontology, 'workflow_stage') + const attachmentPolicy = resolveAttachmentPolicy(expenseTypeCode, amount.value) + + return { + documentType: documentTypeEntity?.normalized_value || 'expense_application', + documentTypeLabel: documentTypeEntity?.value || '费用申请', + workflowStage: workflowStageEntity?.normalized_value || 'pre_approval', + workflowStageLabel: workflowStageEntity?.value || '前置申请', + expenseTypeCode, + expenseTypeLabel: resolveExpenseTypeLabel(expenseTypeCode), + amount: amount.value, + amountDisplay: amount.value ? `¥${amount.value.toLocaleString('zh-CN')}` : '待补充', + timeRange: resolveTimeRangeText(ontology) || '待补充', + location: locationEntity?.normalized_value || locationEntity?.value || '待补充', + reason: String(prompt || '').trim() || '待补充', + applicant: currentUser.name || currentUser.username || '当前用户', + department: currentUser.department || currentUser.departmentName || '待补充', + preApprovalRequired: PRE_APPROVAL_TYPES.has(expenseTypeCode), + attachmentPolicy, + missingSlots: normalizeMissingSlots(ontology?.missing_slots || []) + } +} + +export function normalizeMissingSlots(slots = []) { + const normalized = Array.isArray(slots) ? slots : [] + return normalized.map((item) => ({ + key: String(item || '').trim(), + label: SLOT_LABELS[String(item || '').trim()] || String(item || '').trim() + })).filter((item) => item.key) +} diff --git a/web/src/utils/hermesEmployeeSettingsModel.js b/web/src/utils/hermesEmployeeSettingsModel.js index 452de81..339e451 100644 --- a/web/src/utils/hermesEmployeeSettingsModel.js +++ b/web/src/utils/hermesEmployeeSettingsModel.js @@ -1,69 +1,26 @@ /** 数字员工设置:面向管理员的简明任务列表(频率固定,仅可调执行时间) */ export const HERMES_SIMPLE_TASKS = [ { - id: 'knowledgeAggregation', - label: '知识库同步', - hint: '同步制度文档与知识索引', - frequency: 'daily', - frequencyLabel: '每天' - }, - { - id: 'ruleReviewDigest', - label: '规则待审提醒', - hint: '汇总待审规则并推送管理员', - frequency: 'daily', - frequencyLabel: '每天' - }, - { - id: 'riskSummary', + id: 'global_risk_scan', label: '风险每日巡检', hint: '扫描报销、付款等风险信号', frequency: 'daily', frequencyLabel: '每天' }, { - id: 'archiveDigest', - label: '归档周报', - hint: '汇总已归档报销单', + id: 'weekly_expense_report', + label: '费控洞察周报', + hint: '聚合生成财务总结简报', frequency: 'weekly', frequencyLabel: '每周一', weekday: 1 - }, - { - id: 'dailyStats', - label: '日报统计', - hint: '生成昨日报销与审批数据', - frequency: 'daily', - frequencyLabel: '每天' - }, - { - id: 'monthlyStats', - label: '月报统计', - hint: '每月 1 号生成上月汇总', - frequency: 'monthly', - frequencyLabel: '每月 1 日', - monthDay: 1 - }, - { - id: 'yearlyStats', - label: '年报统计', - hint: '每年 1 月 1 号生成上年汇总', - frequency: 'yearly', - frequencyLabel: '每年 1 月 1 日', - month: 1, - monthDay: 1 } ] function buildDefaultSchedules() { const defaults = { - knowledgeAggregation: { enabled: true, frequency: 'daily', time: '00:00', weekday: 1, monthDay: 1, month: 1 }, - ruleReviewDigest: { enabled: true, frequency: 'daily', time: '18:00', weekday: 5, monthDay: 1, month: 1 }, - riskSummary: { enabled: true, frequency: 'daily', time: '09:00', weekday: 1, monthDay: 1, month: 1 }, - archiveDigest: { enabled: false, frequency: 'weekly', time: '10:30', weekday: 1, monthDay: 1, month: 1 }, - dailyStats: { enabled: true, frequency: 'daily', time: '08:30', weekday: 1, monthDay: 1, month: 1 }, - monthlyStats: { enabled: true, frequency: 'monthly', time: '09:00', weekday: 1, monthDay: 1, month: 1 }, - yearlyStats: { enabled: false, frequency: 'yearly', time: '10:00', weekday: 1, monthDay: 1, month: 1 } + global_risk_scan: { enabled: true, frequency: 'daily', time: '09:00', weekday: 1, monthDay: 1, month: 1 }, + weekly_expense_report: { enabled: false, frequency: 'weekly', time: '10:30', weekday: 1, monthDay: 1, month: 1 } } for (const task of HERMES_SIMPLE_TASKS) { @@ -91,13 +48,8 @@ export function buildDefaultHermesEmployeeForm() { masterEnabled: true, notifyOnFailure: true, capabilities: { - knowledgeAggregation: true, - ruleReviewDigest: true, - riskSummary: true, - archiveDigest: false, - dailyStats: true, - monthlyStats: true, - yearlyStats: false + global_risk_scan: true, + weekly_expense_report: false }, schedules: buildDefaultSchedules() } diff --git a/web/src/utils/settingsModelHelper.js b/web/src/utils/settingsModelHelper.js index 0ab49cf..42c9f3b 100644 --- a/web/src/utils/settingsModelHelper.js +++ b/web/src/utils/settingsModelHelper.js @@ -39,7 +39,7 @@ export const SECTION_DEFINITIONS = [ id: 'hermes', label: '数字员工设置', title: '数字员工设置', - desc: 'Hermes 自动任务', + desc: '自动任务', longDesc: '选择需要自动执行的任务,并设置每天的执行时间。无需了解 Cron 或复杂调度规则。', actionLabel: '保存数字员工设置' }, diff --git a/web/src/views/AppShellRouteView.vue b/web/src/views/AppShellRouteView.vue index d306ea2..e876590 100644 --- a/web/src/views/AppShellRouteView.vue +++ b/web/src/views/AppShellRouteView.vue @@ -16,6 +16,7 @@ :class="{ 'overview-main': activeView === 'overview', 'workbench-main': activeView === 'workbench', + 'documents-main': activeView === 'documents', 'requests-main': activeView === 'requests', 'approval-main': activeView === 'approval', 'archive-main': activeView === 'archive', @@ -38,6 +39,7 @@ :knowledge-summary="knowledgeSummary" :logs-summary="logsSummary" :request-summary="requestSummary" + :document-summary="documentSummary" :workbench-summary="workbenchSummary" :detail-mode="detailMode" :log-detail-mode="logDetailMode" @@ -47,11 +49,11 @@ @update:active-range="activeRange = $event" @update:custom-range="customRange = $event" @batch-approve="toast('已批量通过 23 条审批任务。')" - @new-application="openTravelCreate" + @new-application="openExpenseApplicationDialog" /> + + + + @@ -139,10 +161,12 @@ import { computed, ref } from 'vue' import SidebarRail from '../components/layout/SidebarRail.vue' import TopBar from '../components/layout/TopBar.vue' import FilterBar from '../components/layout/FilterBar.vue' +import ExpenseApplicationDialog from '../components/shared/ExpenseApplicationDialog.vue' import OverviewView from './OverviewView.vue' import PersonalWorkbenchView from './PersonalWorkbenchView.vue' import TravelReimbursementCreateView from './TravelReimbursementCreateView.vue' import TravelRequestDetailView from './TravelRequestDetailView.vue' +import DocumentsCenterView from './DocumentsCenterView.vue' import RequestsView from './RequestsView.vue' import ApprovalCenterView from './ApprovalCenterView.vue' import ArchiveCenterView from './ArchiveCenterView.vue' @@ -160,7 +184,9 @@ import { filterNavItemsByAccess } from '../utils/accessControl.js' const employeeSummary = ref(null) const knowledgeSummary = ref(null) const logsSummary = ref(null) +const documentSummary = ref(null) const auditDetailOpen = ref(false) +const expenseApplicationDialogOpen = ref(false) const { activeRange, @@ -203,6 +229,19 @@ const { const { companyProfile, currentUser, logout } = useSystemState() const filteredNavItems = computed(() => filterNavItemsByAccess(navItems, currentUser.value)) +function openExpenseApplicationDialog() { + expenseApplicationDialogOpen.value = true +} + +function closeExpenseApplicationDialog() { + expenseApplicationDialogOpen.value = false +} + +function handleExpenseApplicationConfirmed() { + expenseApplicationDialogOpen.value = false + toast('费用申请字段已接入本体识别,后续会按申请审批流落单。') +} + function handleLogout() { logout('manual') } diff --git a/web/src/views/AuditView.vue b/web/src/views/AuditView.vue index 5e17098..cd085e2 100644 --- a/web/src/views/AuditView.vue +++ b/web/src/views/AuditView.vue @@ -215,7 +215,6 @@ >
-
{{ selectedSkill.typeLabel }}

{{ selectedSkill.name }}

@@ -230,11 +229,6 @@
-
- - {{ selectedSkill.riskRuleSeverityLabel }} - -
@@ -243,19 +237,74 @@

基本信息

-

这条规则的业务域、风险等级、创建时间和使用字段。

+

这条规则的业务域、风险等级、创建时间、上线状态和审核历史。

-
- 业务域{{ selectedSkill.category || '-' }} - 风险等级{{ selectedSkill.riskRuleSeverityLabel || '-' }} - 适用场景{{ selectedSkill.riskCategory || selectedSkill.scope || '-' }} - 创建时间{{ selectedSkill.riskRuleCreatedAt || selectedSkill.updatedAt }} - 已创建{{ selectedSkill.riskRuleAgeLabel || '-' }} - - 使用字段 - {{ selectedSkill.riskRuleFieldSummary || '-' }} - +
+
+ 业务域 + {{ selectedSkill.category || '-' }} +
+
+ 适用场景 + {{ selectedSkill.riskCategory || selectedSkill.scope || '-' }} +
+
+ 风险等级 + + + {{ selectedSkill.riskRuleSeverityLabel || '-' }} + + +
+
+ 是否上线 + + + + {{ selectedSkill.isOnlineLabel || '否' }} + + +
+
+ 是否启用 + + + {{ selectedSkill.isEnabledLabel || '-' }} + + +
+
+ 测试状态 + + + {{ riskRuleTestPassed ? '已确认通过' : '待测试确认' }} + + +
+
+ 发布人 + {{ selectedSkill.publisher || '-' }} +
+
+ 审核人 + {{ selectedSkill.reviewer || '-' }} +
+
+ 创建时间 + + {{ selectedSkill.riskRuleCreatedAt || selectedSkill.updatedAt }} + ({{ selectedSkill.riskRuleAgeLabel }}) + +
+
+ 上线时间 + {{ selectedSkill.publishedAt || '-' }} +
+
+ 使用字段 + {{ selectedSkill.riskRuleFieldSummary || '-' }} +
@@ -618,25 +667,88 @@ - -
- + +
+ + - - - -
+ +
+ + +
+ +
+ + +
+ +
@@ -909,10 +1109,12 @@ {{ tableColumns.owner }} {{ tableColumns.scope }} {{ tableColumns.runtime }} - {{ tableColumns.version }} - 状态 - {{ tableColumns.metric }} - 最近更新 + {{ tableColumns.version }} + 状态 + {{ tableColumns.metric }} + 是否上线 + 是否启用 + {{ tableColumns.updatedAt || '最近更新' }} @@ -934,10 +1136,16 @@ {{ skill.owner }} {{ skill.scope }} {{ skill.model }} - {{ skill.versionDisplay || skill.version }} - {{ skill.status }} - {{ skill.hitRate }} - {{ skill.updatedAt }} + {{ skill.versionDisplay || skill.version }} + {{ skill.status }} + {{ skill.hitRate }} + + {{ skill.isOnlineLabel }} + + + {{ skill.isEnabledLabel }} + + {{ skill.updatedAt }} @@ -990,6 +1198,32 @@ + + + + + +
+ 测试状态 + {{ riskRuleTestPassed ? '已确认通过' : '未确认通过' }} +
+
+ -

- 当前没有可选的高级管理员,请先在员工管理中配置具备管理员角色的员工。 -

-
- +

+ 当前没有可选的高级管理员,请先在员工管理中配置具备管理员角色的员工。 +

+
+ 测试确认 + + {{ riskRuleTestPassed ? '当前版本已通过测试确认' : '当前版本尚未确认测试通过' }} + +

只有保存测试报告的风险规则,才能提交给高级管理人员审核。

+
+
+
diff --git a/web/src/views/DocumentsCenterView.vue b/web/src/views/DocumentsCenterView.vue new file mode 100644 index 0000000..55e38d9 --- /dev/null +++ b/web/src/views/DocumentsCenterView.vue @@ -0,0 +1,788 @@ + + + + + diff --git a/web/src/views/LogsView.vue b/web/src/views/LogsView.vue index 55dcdac..18babf0 100644 --- a/web/src/views/LogsView.vue +++ b/web/src/views/LogsView.vue @@ -9,7 +9,7 @@