181 | {/* 状态栏 */}
182 |
190 |
191 |
195 |
196 | 会话ID: {sessionId ? sessionId.slice(-8) : 'loading...'}
197 |
198 |
199 |
207 |
208 |
209 | {/* 消息列表 */}
210 |
211 | {chat.messages.map((message) => (
212 |
217 | ))}
218 | {loading && (
219 |
220 |
221 |
222 | AI正在思考中...
223 |
224 |
225 | )}
226 |
227 |
228 | {/* 输入区域 */}
229 |
230 |
231 |
251 |
252 |
253 | 智能业务助手 - 支持流量查询、宽带报修、套餐变更等业务办理,按Enter发送,Shift+Enter换行
254 |
255 |
256 |
257 |
258 | );
259 | }
--------------------------------------------------------------------------------
/frontend/src/components/ChatBox.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useRef } from 'react';
2 | import { Input, Button, Spin, message as antdMsg, Space, Typography } from 'antd';
3 | import MessageBubble from './MessageBubble';
4 | import SlotFiller from './SlotFiller';
5 | import KnowledgeCitation from './KnowledgeCitation';
6 | import { sendMessage, getMockSlots } from '../api/aiApi';
7 | import { detectIntent } from '../utils/intentMap';
8 |
9 | const { Text } = Typography;
10 |
11 | // 业务场景格式化回复
12 | function formatBusinessReply(intent, data, slotValues = {}) {
13 | if (!data) return '处理完成';
14 | // 流量查询
15 | if (intent.businessKey === 'traffic_query') {
16 | return `本月总流量:${data.total_traffic},已用:${data.used_traffic},剩余:${data.remain_traffic},状态:${data.status}`;
17 | }
18 | // 宽带报修
19 | if (intent.businessKey === 'broadband_repair') {
20 | return `宽带报修工单已创建,联系电话:${data.phone},账号:${data.broadband_account},地址:${data.address},故障类型:${data.fault_type},工单状态:${data.status || '已受理'}。${data.remark || ''}`;
21 | }
22 | // 套餐变更
23 | if (intent.businessKey === 'package_change') {
24 | return `套餐变更成功!原套餐:${data.old_package || ''},新套餐:${data.new_package || data.package_type || ''},生效时间:${data.effective_time || ''},月费:${data.monthly_fee || ''},状态:${data.status || ''}。${data.remark || ''}`;
25 | }
26 | // 副卡办理
27 | if (intent.businessKey === 'sub_card_apply') {
28 | return `副卡办理成功!主卡:${data.main_phone},副卡张数:${data.sub_card_count},套餐:${data.sub_package_type},副卡号码:${Array.isArray(data.sub_cards) ? data.sub_cards.join('、') : ''},月费:${data.monthly_fee},总月费:${data.total_monthly_fee},办理时间:${data.apply_time}。${data.remark || ''}`;
29 | }
30 | // 实名认证
31 | if (intent.businessKey === 'realname_query') {
32 | if (data.status === '已实名' || data.realname_status === '已实名') {
33 | return `实名认证结果:已实名,姓名:${data.name || ''},证件号:${data.id_number || ''}`;
34 | } else if (data.status === '未实名' || data.realname_status === '未实名') {
35 | return '实名认证结果:未实名。';
36 | } else {
37 | return data.remark || data.msg || '实名认证结果:' + (data.status || data.realname_status || '未知');
38 | }
39 | }
40 | // 话费账单
41 | if (intent.businessKey === 'account_bill') {
42 | return `账单周期:${data.bill_period || ''},应缴:${data.amount_due || ''}元,已缴:${data.amount_paid || ''}元,状态:${data.status || ''}`;
43 | }
44 | // 积分查询
45 | if (intent.businessKey === 'points_query') {
46 | return `当前积分:${data.points || ''}分,有效期至:${data.expire_date || ''}`;
47 | }
48 | // 停机保号
49 | if (intent.businessKey === 'suspend_apply') {
50 | return `停机保号办理成功,停机时长:${data.suspend_duration || ''}月,生效时间:${data.effective_time || ''},状态:${data.status || ''}`;
51 | }
52 | // 发票申请
53 | if (intent.businessKey === 'invoice_apply') {
54 | return `发票申请成功,类型:${data.invoice_type || ''},邮寄地址:${data.mailing_address || ''},状态:${data.status || ''}`;
55 | }
56 | // 套餐余量
57 | if (intent.businessKey === 'package_balance') {
58 | return `套餐余量:语音${data.voice_balance || ''},流量${data.data_balance || ''},短信${data.sms_balance || ''},套餐:${data.package_name || ''},到期:${data.expire_date || ''}`;
59 | }
60 | // 充值缴费
61 | if (intent.businessKey === 'recharge') {
62 | const amount = data.amount || slotValues.amount || '';
63 | const payment_method = data.payment_method || slotValues.payment_method || '';
64 | const status = data.status || '充值成功';
65 | return `充值成功,金额:${amount}元,方式:${payment_method},状态:${status}`;
66 | }
67 | // 号码过户
68 | if (intent.businessKey === 'number_transfer') {
69 | return `号码过户成功,原号码:${data.original_phone || ''},新机主证件号:${data.new_owner_id || ''},状态:${data.status || ''}`;
70 | }
71 | // 国际漫游
72 | if (intent.businessKey === 'roaming_enable') {
73 | return `国际漫游已开通,国家:${data.roaming_country || ''},起止:${data.start_date || ''}~${data.end_date || ''},状态:${data.status || ''}`;
74 | }
75 | // 积分兑换
76 | if (intent.businessKey === 'points_exchange') {
77 | const exchange_type = data.exchange_type || slotValues.exchange_type || '';
78 | const exchange_quantity = data.exchange_quantity || slotValues.exchange_quantity || '';
79 | const status = data.status || '兑换成功';
80 | return `积分兑换成功,类型:${exchange_type},数量:${exchange_quantity},状态:${status}`;
81 | }
82 | // 通知订阅
83 | if (intent.businessKey === 'notification_subscribe') {
84 | return `通知订阅成功,类型:${data.notification_type || ''},状态:${data.status || ''}`;
85 | }
86 | // 套餐退订
87 | if (intent.businessKey === 'package_unsubscribe') {
88 | return `套餐退订成功,类型:${data.package_type || ''},状态:${data.status || ''}`;
89 | }
90 | // 宽带升级
91 | if (intent.businessKey === 'broadband_upgrade') {
92 | return `宽带升级成功,账号:${data.broadband_account || ''},类型:${data.upgrade_type || ''},状态:${data.status || ''}`;
93 | }
94 | // 停/复机
95 | if (intent.businessKey === 'stop_resume') {
96 | return `业务办理成功,操作:${data.action || ''},状态:${data.status || ''}`;
97 | }
98 | // 密码重置
99 | if (intent.businessKey === 'password_reset') {
100 | return `密码重置成功,状态:${data.status || ''}`;
101 | }
102 | // 对话日志
103 | if (intent.businessKey === 'chat_log') {
104 | return data.log || data.remark || data.msg || '对话日志操作完成';
105 | }
106 | // 服务评价
107 | if (intent.businessKey === 'feedback') {
108 | return `服务评价提交成功,评分:${data.score || ''},内容:${data.comment || ''}`;
109 | }
110 | // 投诉工单
111 | if (intent.businessKey === 'complaint') {
112 | return `投诉已受理,工单号:${data.complaint_id || ''},类型:${data.complaint_type || ''},优先级:${data.priority || ''},预计处理时长:${data.estimated_time || ''},状态:${data.status || ''}。${data.remark || ''}`;
113 | }
114 | // 增值业务
115 | if (intent.businessKey === 'value_added') {
116 | return `增值业务${data.service_name || ''}${data.action || ''},状态:${data.status || ''}`;
117 | }
118 | // FAQ
119 | if (intent.businessKey === 'faq') {
120 | return data.answer || data.msg || '这是一个模拟FAQ答案。';
121 | }
122 | // 地址变更
123 | if (intent.businessKey === 'address_modify') {
124 | const new_address = data.new_address || slotValues.new_address || '';
125 | const status = data.status || '修改成功';
126 | return `通信地址修改成功,新地址:${new_address},状态:${status}`;
127 | }
128 | // 兜底
129 | return data.remark || data.answer || data.msg || '处理完成';
130 | }
131 |
132 | export default function ChatBox({ chat, updateChat }) {
133 | const [input, setInput] = useState('');
134 | const [loading, setLoading] = useState(false);
135 | const [mockSlots, setMockSlots] = useState(null);
136 | const [pendingSlots, setPendingSlots] = useState([]);
137 | const [slotValues, setSlotValues] = useState({});
138 | const [currentIntent, setCurrentIntent] = useState(null);
139 | const inputRef = useRef();
140 |
141 | React.useEffect(() => {
142 | getMockSlots().then(res => setMockSlots(res.data.data)).catch(() => {});
143 | }, []);
144 |
145 | const handleSend = async (customValues, customIntent) => {
146 | let userInput = input;
147 | if (!userInput && !customValues) return;
148 | if (!customIntent) {
149 | const userMsg = { id: Date.now(), role: 'user', text: userInput || '[补全卡槽]' };
150 | updateChat(chat => ({ ...chat, messages: [...chat.messages, userMsg] }));
151 | }
152 | setInput('');
153 | setLoading(true);
154 |
155 | const intent = customIntent || detectIntent(userInput);
156 | setCurrentIntent(intent);
157 | let values = customValues || slotValues;
158 | let slotDefs = (mockSlots && intent.businessKey && mockSlots[intent.businessKey]?.slots) || {};
159 | // 以mock_slots为准,动态判断所有required字段
160 | let requiredKeys = Object.entries(slotDefs)
161 | .filter(([k, v]) => v.required)
162 | .map(([k]) => k);
163 | let missing = requiredKeys.filter(key => !values[key]);
164 | const askSlots = missing.slice(0, 2);
165 | if (process.env.NODE_ENV !== 'production') {
166 | console.log('【DEBUG】意图:', intent, '已填参数:', values, '缺失卡槽:', missing);
167 | }
168 | if (askSlots.length > 0) {
169 | setPendingSlots(askSlots);
170 | setSlotValues(values);
171 | setLoading(false);
172 | return;
173 | }
174 | try {
175 | const params = {};
176 | requiredKeys.forEach(key => { params[key] = values[key]; });
177 | if (process.env.NODE_ENV !== 'production') {
178 | console.log('【DEBUG】最终请求参数:', params);
179 | }
180 | const res = await sendMessage(intent.api, params);
181 | const aiMsg = {
182 | id: Date.now() + 1,
183 | role: 'ai',
184 | text: formatBusinessReply(intent, res.data.data, values),
185 | status: '处理完成',
186 | citations: res.data.data.citations || [],
187 | };
188 | updateChat(chat => ({ ...chat, messages: [...chat.messages, aiMsg] }));
189 | setSlotValues({});
190 | setPendingSlots([]);
191 | } catch (e) {
192 | antdMsg.error('AI接口调用失败');
193 | }
194 | setLoading(false);
195 | };
196 |
197 | const handleSlotFill = (values) => {
198 | const merged = { ...slotValues, ...values };
199 | setSlotValues(merged);
200 | setPendingSlots([]);
201 | setInput('');
202 | setTimeout(() => handleSend(merged, currentIntent), 0);
203 | };
204 |
205 | return (
206 |
207 |
208 | {chat.title} 参与人:你 / AI助手
209 |
210 |
211 | {chat.messages.map(msg => (
212 |
213 | ))}
214 | {loading && }
215 |
216 | {pendingSlots.length > 0 && mockSlots && currentIntent &&
217 | mockSlots[currentIntent.businessKey] && mockSlots[currentIntent.businessKey].slots && (
218 |
223 | )}
224 |
225 | setInput(e.target.value)}
229 | placeholder="请输入您的问题或业务需求..."
230 | autoSize={{ minRows: 1, maxRows: 4 }}
231 | disabled={loading || pendingSlots.length > 0}
232 | />
233 |
234 |
235 | {chat.messages.length > 0 &&
}
236 |
237 | );
238 | }
--------------------------------------------------------------------------------
/utils/helpers.py:
--------------------------------------------------------------------------------
1 | # encoding=utf-8
2 | import glob
3 | import json
4 | import re
5 | import requests
6 | import urllib3
7 | import config
8 |
9 | # 禁用SSL证书验证警告
10 | urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
11 |
12 |
13 | def filename_to_classname(filename):
14 | """
15 | Convert a snake_case filename to a CamelCase class name.
16 |
17 | Args:
18 | filename (str): The filename in snake_case, without the .py extension.
19 |
20 | Returns:
21 | str: The converted CamelCase class name.
22 | """
23 | parts = filename.split('_')
24 | class_name = ''.join(part.capitalize() for part in parts)
25 | return class_name
26 |
27 |
28 | def load_scene_templates(file_path):
29 | with open(file_path, 'r', encoding='utf-8') as file:
30 | return json.load(file)
31 |
32 |
33 | def load_all_scene_configs():
34 | """
35 | 从本地scene_templates.json文件加载场景配置
36 | 特殊处理common_fields通用字段,将其合并到每个场景的parameters中
37 | """
38 | print("从本地scene_templates.json加载场景配置")
39 | all_scene_configs = {}
40 |
41 | # 搜索目录下的所有json文件
42 | for file_path in glob.glob("scene_config/**/*.json", recursive=True):
43 | current_config = load_scene_templates(file_path)
44 |
45 | # 提取通用字段
46 | common_fields = current_config.get('common_fields', [])
47 |
48 | # 处理场景列表
49 | scene_list = current_config.get('scene_list', [])
50 |
51 | for scene in scene_list:
52 | scene_name = scene.get('scene_name')
53 | if scene_name and scene_name not in all_scene_configs:
54 | # 复制场景的parameters
55 | scene_parameters = scene.get('parameters', []).copy()
56 |
57 | # 将common_fields合并到parameters前面
58 | merged_parameters = common_fields.copy() + scene_parameters
59 |
60 | # 构建场景配置,添加scene_name字段
61 | all_scene_configs[scene_name] = {
62 | "scene_name": scene_name, # 添加英文场景名称
63 | "name": scene.get('name', ''),
64 | "description": scene.get('description', ''),
65 | "parameters": merged_parameters,
66 | "enabled": scene.get('enabled', False),
67 | "example": scene.get('example', '')
68 | }
69 |
70 | # 处理其他非scene_list和common_fields的配置项
71 | for key, value in current_config.items():
72 | if key not in ['common_fields', 'scene_list'] and key not in all_scene_configs:
73 | # 为其他配置项也添加scene_name字段
74 | if isinstance(value, dict):
75 | value['scene_name'] = key
76 | all_scene_configs[key] = value
77 |
78 | return all_scene_configs
79 |
80 |
81 | def call_scene_api(scene_name, slots_data):
82 | """
83 | 调用场景API
84 | :param scene_name: 场景名称(如broadband_repair)
85 | :param slots_data: 槽位数据
86 | :return: API响应结果
87 | """
88 | try:
89 | # 构建API URL
90 | api_url = config.SCENE_API_URL_TEMPLATE.format(scene_name=scene_name)
91 |
92 | # 准备请求头
93 | headers = {
94 | "Content-Type": "application/json"
95 | }
96 |
97 | # 发送POST请求,直接发送扁平化的slots_data
98 | print(f"调用场景API: {api_url}")
99 | print(f"请求体: {json.dumps(slots_data, ensure_ascii=False)}")
100 | response = requests.post(
101 | api_url,
102 | headers=headers,
103 | json=slots_data,
104 | timeout=config.API_TIMEOUT
105 | )
106 |
107 | if response.status_code == 200:
108 | result = response.json()
109 | print(f"API调用成功: {json.dumps(result, ensure_ascii=False)}")
110 | return result
111 | else:
112 | print(f"API调用失败,状态码: {response.status_code}")
113 | return {"error": f"API调用失败,状态码: {response.status_code}"}
114 |
115 | except requests.RequestException as e:
116 | print(f"API请求异常: {e}")
117 | return {"error": f"API请求异常: {e}"}
118 | except Exception as e:
119 | print(f"处理API响应时出错: {e}")
120 | return {"error": f"处理API响应时出错: {e}"}
121 |
122 |
123 | def process_api_result(api_result, chat_history=None):
124 | """
125 | 处理API结果,通过AI生成用户友好的回复
126 | :param api_result: API返回的结果
127 | :param chat_history: 聊天记录
128 | :return: 处理后的用户友好回复
129 | """
130 | try:
131 | # 只取data部分发给AI
132 | data_part = api_result.get("data", api_result)
133 | prompt = config.API_RESULT_PROMPT.format(api_result=json.dumps(data_part, ensure_ascii=False))
134 |
135 | # 调用AI处理结果
136 | result = send_message(prompt, None, chat_history)
137 |
138 | if result:
139 | return result
140 | else:
141 | return "抱歉,处理结果时出现错误,请稍后重试。"
142 |
143 | except Exception as e:
144 | print(f"处理API结果时出错: {e}")
145 | return "抱歉,处理结果时出现错误,请稍后重试。"
146 |
147 |
148 | def send_message(message, user_input, chat_history=None):
149 | """
150 | 请求chatGPT函数,支持聊天记录
151 | """
152 | print('--------------------------------------------------------------------')
153 | if config.DEBUG:
154 | print('prompt输入:', message)
155 | elif user_input:
156 | print('用户输入:', user_input)
157 | print('----------------------------------')
158 |
159 | headers = {
160 | "Authorization": f"Bearer {config.API_KEY}",
161 | "Content-Type": "application/json",
162 | }
163 |
164 | # 构建消息列表
165 | messages = [{"role": "system", "content": config.SYSTEM_PROMPT}]
166 |
167 | # 添加聊天记录(如果提供)
168 | if chat_history:
169 | # 限制聊天记录数量
170 | limited_history = chat_history[-config.CHAT_HISTORY_COUNT:]
171 | for msg in limited_history:
172 | messages.append(msg)
173 |
174 | # 添加当前消息
175 | messages.append({"role": "user", "content": f"{message}"})
176 |
177 | data = {
178 | "model": config.MODEL,
179 | "messages": messages,
180 | "enable_thinking": False
181 | }
182 |
183 | try:
184 | response = requests.post(config.GPT_URL, headers=headers, json=data, verify=False)
185 | if response.status_code == 200:
186 | answer = response.json()["choices"][0]["message"]['content']
187 | print('LLM输出:', answer)
188 | print('--------------------------------------------------------------------')
189 | return answer
190 | else:
191 | print(f"Error: {response.status_code}")
192 | return None
193 | except requests.RequestException as e:
194 | print(f"Request error: {e}")
195 | return None
196 |
197 |
198 | def is_slot_fully_filled(json_data):
199 | """
200 | 检查槽位是否完整填充
201 | """
202 | # 遍历JSON数据中的每个元素
203 | for item in json_data:
204 | # 检查value字段是否为空字符串
205 | if item.get('value') == '':
206 | return False # 如果发现空字符串,返回False
207 | return True # 如果所有value字段都非空,返回True
208 |
209 |
210 | def get_raw_slot(parameters):
211 | # 创建新的JSON对象
212 | output_data = []
213 | for item in parameters:
214 | new_item = {"name": item["name"], "desc": item["desc"], "type": item["type"], "value": ""}
215 | output_data.append(new_item)
216 | return output_data
217 |
218 |
219 | def get_dynamic_example(scene_config):
220 | # 创建新的JSON对象
221 | if 'example' in scene_config and scene_config['example'] != '':
222 | return scene_config['example']
223 | else:
224 | return "JSON:[{'name': 'phone', 'desc': '需要查询的手机号', 'value': ''}, {'name': 'month', 'desc': '查询的月份,格式为yyyy-MM', 'value': ''} ]\n输入:帮我查一下18724011022在2024年7月的流量\n答:{ 'phone': '18724011022', 'month': '2024-07' }"
225 |
226 |
227 | def get_slot_update_json(slot):
228 | # 创建新的JSON对象
229 | output_data = []
230 | for item in slot:
231 | new_item = {"name": item["name"], "desc": item["desc"], "value": item["value"]}
232 | output_data.append(new_item)
233 | return output_data
234 |
235 |
236 | def get_slot_query_user_json(slot):
237 | # 创建新的JSON对象
238 | output_data = []
239 | for item in slot:
240 | if not item["value"]:
241 | new_item = {"name": item["name"], "desc": item["desc"], "value": item["value"]}
242 | output_data.append(new_item)
243 | return output_data
244 |
245 |
246 | def update_slot(json_data, dict_target):
247 | """
248 | 更新槽位slot参数
249 | """
250 | # 遍历JSON数据中的每个元素
251 | for item in json_data:
252 | # 检查item是否包含必要的字段
253 | if not isinstance(item, dict) or 'name' not in item or 'value' not in item:
254 | continue
255 | # 检查value字段是否为空字符串
256 | if item['value'] != '':
257 | for target in dict_target:
258 | if target['name'] == item['name']:
259 | target['value'] = item.get('value')
260 | break
261 |
262 |
263 | def format_name_value_for_logging(json_data):
264 | """
265 | 抽取参数名称和value值
266 | """
267 | log_strings = []
268 | for item in json_data:
269 | name = item.get('name', 'Unknown name') # 获取name,如果不存在则使用'Unknown name'
270 | value = item.get('value', 'N/A') # 获取value,如果不存在则使用'N/A'
271 | log_string = f"name: {name}, Value: {value}"
272 | log_strings.append(log_string)
273 | return '\n'.join(log_strings)
274 |
275 |
276 | def extract_json_from_string(input_string):
277 | """
278 | JSON抽取函数
279 | 返回包含JSON对象的列表
280 | """
281 | try:
282 | # 正则表达式假设JSON对象由花括号括起来
283 | matches = re.findall(r'\{.*?\}', input_string, re.DOTALL)
284 |
285 | # 验证找到的每个匹配项是否为有效的JSON
286 | valid_jsons = []
287 | for match in matches:
288 | try:
289 | json_obj = json.loads(match)
290 | valid_jsons.append(json_obj)
291 | except json.JSONDecodeError:
292 | try:
293 | valid_jsons.append(fix_json(match))
294 | except json.JSONDecodeError:
295 | continue # 如果不是有效的JSON,跳过该匹配项
296 | continue # 如果不是有效的JSON,跳过该匹配项
297 |
298 | return valid_jsons
299 | except Exception as e:
300 | print(f"Error occurred: {e}")
301 | return []
302 |
303 |
304 | def fix_json(bad_json):
305 | # 首先,用双引号替换掉所有的单引号
306 | fixed_json = bad_json.replace("'", '"')
307 | try:
308 | # 然后尝试解析
309 | return json.loads(fixed_json)
310 | except json.JSONDecodeError:
311 | # 如果解析失败,打印错误信息,但不会崩溃
312 | print("给定的字符串不是有效的 JSON 格式。")
313 |
314 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/log.txt:
--------------------------------------------------------------------------------
1 |
2 | ==== 片段 1 原始内容 ====
3 | 你是一个专业的数据分析师,现在需要整理一个Excel表格的分割片段。
4 | **列名:**
5 | 客户需求, 一级模块, 二级模块, 三级模块, 功能用户, 触发事件, 功能过程, 子过程描述, 数据移动类型, 数据组, 数据属性, 复用度, CFP
6 |
7 | **数据内容:**
8 | ```json
9 | [
10 | {
11 | "客户需求": "监控排障需求",
12 | "一级模块": "故障调度",
13 | "二级模块": "含H5链接的事件督办",
14 | "三级模块": "H5页面配置",
15 | "功能用户": "发起者:操作员\n接收者:H5页面告警组件配置管理",
16 | "触发事件": "操作员在界面操作",
17 | "功能过程": "增加H5页面告警组件",
18 | "子过程描述": "输入H5页面告警组件增加信息",
19 | "数据移动类型": "E",
20 | "数据组": "H5页面告警组件增加信息",
21 | "数据属性": "H5页面告警组件标识、组件类型、应用场景、包含告警标签、告警标签显示顺序",
22 | "复用度": "新增",
23 | "CFP": 1
24 | },
25 | {
26 | "客户需求": "监控排障需求",
27 | "一级模块": "故障调度",
28 | "二级模块": "含H5链接的事件督办",
29 | "三级模块": "H5页面配置",
30 | "功能用户": "发起者:操作员\n接收者:H5页面告警组件配置管理",
31 | "触发事件": "操作员在界面操作",
32 | "功能过程": "增加H5页面告警组件",
33 | "子过程描述": "调用增加H5页面告警组件接口",
34 | "数据移动类型": "X",
35 | "数据组": "增加H5页面告警组件接口调用参数",
36 | "数据属性": "增加H5页面告警组件接口路径、H5页面告警组件增加信息明细",
37 | "复用度": "新增",
38 | "CFP": 1
39 | },
40 | {
41 | "客户需求": "监控排障需求",
42 | "一级模块": "故障调度",
43 | "二级模块": "含H5链接的事件督办",
44 | "三级模块": "H5页面配置",
45 | "功能用户": "发起者:操作员\n接收者:H5页面告警组件配置管理",
46 | "触发事件": "操作员在界面操作",
47 | "功能过程": "增加H5页面告警组件",
48 | "子过程描述": "H5页面告警组件增加内容入库操作写入系统日志",
49 | "数据移动类型": "W",
50 | "数据组": "H5页面告警组件增加日志",
51 | "数据属性": "操作人、操作模块、操作时间、H5页面告警组件增加内容入库具体操作、操作结果",
52 | "复用度": "新增",
53 | "CFP": 1
54 | },
55 | {
56 | "客户需求": "监控排障需求",
57 | "一级模块": "故障调度",
58 | "二级模块": "含H5链接的事件督办",
59 | "三级模块": "H5页面配置",
60 | "功能用户": "发起者:操作员\n接收者:H5页面告警组件配置管理",
61 | "触发事件": "操作员在界面操作",
62 | "功能过程": "删除H5页面告警组件",
63 | "子过程描述": "输入H5页面告警组件删除信息",
64 | "数据移动类型": "E",
65 | "数据组": "H5页面告警组件删除信息",
66 | "数据属性": "H5页面告警组件删除指令",
67 | "复用度": "新增",
68 | "CFP": 1
69 | },
70 | {
71 | "客户需求": "监控排障需求",
72 | "一级模块": "故障调度",
73 | "二级模块": "含H5链接的事件督办",
74 | "三级模块": "H5页面配置",
75 | "功能用户": "发起者:操作员\n接收者:H5页面告警组件配置管理",
76 | "触发事件": "操作员在界面操作",
77 | "功能过程": "删除H5页面告警组件",
78 | "子过程描述": "调用删除H5页面告警组件接口",
79 | "数据移动类型": "X",
80 | "数据组": "删除H5页面告警组件接口调用参数",
81 | "数据属性": "删除H5页面告警组件接口路径、H5页面告警组件删除明细",
82 | "复用度": "新增",
83 | "CFP": 1
84 | },
85 | {
86 | "客户需求": "监控排障需求",
87 | "一级模块": "故障调度",
88 | "二级模块": "含H5链接的事件督办",
89 | "三级模块": "H5页面配置",
90 | "功能用户": "发起者:操作员\n接收者:H5页面告警组件配置管理",
91 | "触发事件": "操作员在界面操作",
92 | "功能过程": "删除H5页面告警组件",
93 | "子过程描述": "H5页面告警组件删除内容入库操作写入系统日志",
94 | "数据移动类型": "X",
95 | "数据组": "H5页面告警组件删除加日志",
96 | "数据属性": "删除人、删除模块、删除时间、H5页面告警组件删除内容具体操作、删除结果",
97 | "复用度": "新增",
98 | "CFP": 1
99 | },
100 | {
101 | "客户需求": "监控排障需求",
102 | "一级模块": "故障调度",
103 | "二级模块": "含H5链接的事件督办",
104 | "三级模块": "H5页面配置",
105 | "功能用户": "发起者:操作员\n接收者:H5页面告警组件配置管理",
106 | "触发事件": "操作员在界面操作",
107 | "功能过程": "修改H5页面告警组件",
108 | "子过程描述": "输入H5页面告警组件修改信息",
109 | "数据移动类型": "E",
110 | "数据组": "H5页面告警组件修改信息",
111 | "数据属性": "H5页面告警组件修改指令",
112 | "复用度": "新增",
113 | "CFP": 1
114 | },
115 | {
116 | "客户需求": "监控排障需求",
117 | "一级模块": "故障调度",
118 | "二级模块": "含H5链接的事件督办",
119 | "三级模块": "H5页面配置",
120 | "功能用户": "发起者:操作员\n接收者:H5页面告警组件配置管理",
121 | "触发事件": "操作员在界面操作",
122 | "功能过程": "修改H5页面告警组件",
123 | "子过程描述": "调用修改H5页面告警组件接口",
124 | "数据移动类型": "X",
125 | "数据组": "修改H5页面告警组件接口调用参数",
126 | "数据属性": "修改H5页面告警组件接口路径、H5页面告警组件标识、组件类型、应用场景、包含告警标签、告警标签显示顺序",
127 | "复用度": "新增",
128 | "CFP": 1
129 | },
130 | {
131 | "客户需求": "监控排障需求",
132 | "一级模块": "故障调度",
133 | "二级模块": "含H5链接的事件督办",
134 | "三级模块": "H5页面配置",
135 | "功能用户": "发起者:操作员\n接收者:H5页面告警组件配置管理",
136 | "触发事件": "操作员在界面操作",
137 | "功能过程": "修改H5页面告警组件",
138 | "子过程描述": "H5页面告警组件修改内容入库操作写入系统日志",
139 | "数据移动类型": "X",
140 | "数据组": "H5页面告警组件修改加日志",
141 | "数据属性": "修改人、修改模块、修改时间、H5页面告警组件修改内容入库具体操作、修改结果",
142 | "复用度": "新增",
143 | "CFP": 1
144 | },
145 | {
146 | "客户需求": "监控排障需求",
147 | "一级模块": "故障调度",
148 | "二级模块": "含H5链接的事件督办",
149 | "三级模块": "H5页面配置",
150 | "功能用户": "发起者:操作员\n接收者:H5页面告警组件配置管理",
151 | "触发事件": "操作员在界面操作",
152 | "功能过程": "H5页面告警组件查询",
153 | "子过程描述": "输入H5页面告警组件查询请求",
154 | "数据移动类型": "E",
155 | "数据组": "H5页面告警组件查询请求",
156 | "数据属性": "H5页面告警组件管理查询指令",
157 | "复用度": "新增",
158 | "CFP": 1
159 | },
160 | {
161 | "客户需求": "监控排障需求",
162 | "一级模块": "故障调度",
163 | "二级模块": "含H5链接的事件督办",
164 | "三级模块": "H5页面配置",
165 | "功能用户": "发起者:操作员\n接收者:H5页面告警组件配置管理",
166 | "触发事件": "操作员在界面操作",
167 | "功能过程": "H5页面告警组件查询",
168 | "子过程描述": "调用H5页面告警组件查询接口",
169 | "数据移动类型": "R",
170 | "数据组": "H5页面告警组件查询接口调用参数",
171 | "数据属性": "H5页面告警组件查询接口路径、查询条件",
172 | "复用度": "新增",
173 | "CFP": 1
174 | },
175 | {
176 | "客户需求": "监控排障需求",
177 | "一级模块": "故障调度",
178 | "二级模块": "含H5链接的事件督办",
179 | "三级模块": "H5页面配置",
180 | "功能用户": "发起者:操作员\n接收者:H5页面告警组件配置管理",
181 | "触发事件": "操作员在界面操作",
182 | "功能过程": "H5页面告警组件查询",
183 | "子过程描述": "呈现H5页面告警组件查询出的数据",
184 | "数据移动类型": "X",
185 | "数据组": "H5页面告警组件查询出的数据",
186 | "数据属性": "H5页面告警组件标识、组件类型、应用场景、包含告警标签、告警标签显示顺序",
187 | "复用度": "新增",
188 | "CFP": 1
189 | },
190 | {
191 | "客户需求": "监控排障需求",
192 | "一级模块": "故障调度",
193 | "二级模块": "含H5链接的事件督办",
194 | "三级模块": "H5页面配置",
195 | "功能用户": "发起者:操作员\n接收者:H5页面告警组件配置管理",
196 | "触发事件": "收到接口调用请求",
197 | "功能过程": "增加H5页面告警组件接口",
198 | "子过程描述": "接收增加H5页面告警组件请求",
199 | "数据移动类型": "E",
200 | "数据组": "增加H5页面告警组件接口调用参数",
201 | "数据属性": "增加H5页面告警组件接口路径、H5页面告警组件增加信息明细",
202 | "复用度": "新增",
203 | "CFP": 1
204 | },
205 | {
206 | "客户需求": "监控排障需求",
207 | "一级模块": "故障调度",
208 | "二级模块": "含H5链接的事件督办",
209 | "三级模块": "H5页面配置",
210 | "功能用户": "发起者:操作员\n接收者:H5页面告警组件配置管理",
211 | "触发事件": "收到接口调用请求",
212 | "功能过程": "增加H5页面告警组件接口",
213 | "子过程描述": "保存H5页面告警组件",
214 | "数据移动类型": "W",
215 | "数据组": "H5页面告警组件",
216 | "数据属性": "H5页面告警组件标识、组件类型、应用场景、包含告警标签、告警标签显示顺序",
217 | "复用度": "新增",
218 | "CFP": 1
219 | },
220 | {
221 | "客户需求": "监控排障需求",
222 | "一级模块": "故障调度",
223 | "二级模块": "含H5链接的事件督办",
224 | "三级模块": "H5页面配置",
225 | "功能用户": "发起者:操作员\n接收者:H5页面告警组件配置管理",
226 | "触发事件": "收到接口调用请求",
227 | "功能过程": "增加H5页面告警组件接口",
228 | "子过程描述": "返回H5页面告警组件增加回执信息",
229 | "数据移动类型": "X",
230 | "数据组": "H5页面告警组件增加回执信息",
231 | "数据属性": "H5页面告警组件标识、组件类型、应用场景、包含告警标签、告警标签显示顺序",
232 | "复用度": "新增",
233 | "CFP": 1
234 | },
235 | {
236 | "客户需求": "监控排障需求",
237 | "一级模块": "故障调度",
238 | "二级模块": "含H5链接的事件督办",
239 | "三级模块": "H5页面配置",
240 | "功能用户": "发起者:操作员\n接收者:H5页面告警组件配置管理",
241 | "触发事件": "收到接口调用请求",
242 | "功能过程": "删除H5页面告警组件接口",
243 | "子过程描述": "接收删除H5页面告警组件请求",
244 | "数据移动类型": "E",
245 | "数据组": "删除H5页面告警组件接口调用参数",
246 | "数据属性": "删除H5页面告警组件接口路径、H5页面告警组件删除明细",
247 | "复用度": "新增",
248 | "CFP": 1
249 | },
250 | {
251 | "客户需求": "监控排障需求",
252 | "一级模块": "故障调度",
253 | "二级模块": "含H5链接的事件督办",
254 | "三级模块": "H5页面配置",
255 | "功能用户": "发起者:操作员\n接收者:H5页面告警组件配置管理",
256 | "触发事件": "收到接口调用请求",
257 | "功能过程": "删除H5页面告警组件接口",
258 | "子过程描述": "删除对应的H5页面告警组件数据",
259 | "数据移动类型": "W",
260 | "数据组": "H5页面告警组件",
261 | "数据属性": "H5页面告警组件标识、组件类型、应用场景、包含告警标签、告警标签显示顺序",
262 | "复用度": "新增",
263 | "CFP": 1
264 | },
265 | {
266 | "客户需求": "监控排障需求",
267 | "一级模块": "故障调度",
268 | "二级模块": "含H5链接的事件督办",
269 | "三级模块": "H5页面配置",
270 | "功能用户": "发起者:操作员\n接收者:H5页面告警组件配置管理",
271 | "触发事件": "收到接口调用请求",
272 | "功能过程": "删除H5页面告警组件接口",
273 | "子过程描述": "返回H5页面告警组件数据删除回执信息",
274 | "数据移动类型": "X",
275 | "数据组": "H5页面告警组件数据删除回执信息",
276 | "数据属性": "H5页面告警组件数据删除信息",
277 | "复用度": "新增",
278 | "CFP": 1
279 | },
280 | {
281 | "客户需求": "监控排障需求",
282 | "一级模块": "故障调度",
283 | "二级模块": "含H5链接的事件督办",
284 | "三级模块": "H5页面配置",
285 | "功能用户": "发起者:操作员\n接收者:H5页面告警组件配置管理",
286 | "触发事件": "收到接口调用请求",
287 | "功能过程": "修改H5页面告警组件接口",
288 | "子过程描述": "收到修改H5页面告警组件调用请求",
289 | "数据移动类型": "E",
290 | "数据组": "修改H5页面告警组件接口调用参数",
291 | "数据属性": "修改H5页面告警组件接口路径、H5页面告警组件标识、组件类型、应用场景、包含告警标签、告警标签显示顺序",
292 | "复用度": "新增",
293 | "CFP": 1
294 | },
295 | {
296 | "客户需求": "监控排障需求",
297 | "一级模块": "故障调度",
298 | "二级模块": "含H5链接的事件督办",
299 | "三级模块": "H5页面配置",
300 | "功能用户": "发起者:操作员\n接收者:H5页面告警组件配置管理",
301 | "触发事件": "收到接口调用请求",
302 | "功能过程": "修改H5页面告警组件接口",
303 | "子过程描述": "修改H5页面告警组件入H5页面告警组件表",
304 | "数据移动类型": "W",
305 | "数据组": "H5页面告警组件",
306 | "数据属性": "H5页面告警组件标识、组件类型、应用场景、包含告警标签、告警标签显示顺序",
307 | "复用度": "新增",
308 | "CFP": 1
309 | },
310 | {
311 | "客户需求": "监控排障需求",
312 | "一级模块": "故障调度",
313 | "二级模块": "含H5链接的事件督办",
314 | "三级模块": "H5页面配置",
315 | "功能用户": "发起者:操作员\n接收者:H5页面告警组件配置管理",
316 | "触发事件": "收到接口调用请求",
317 | "功能过程": "修改H5页面告警组件接口",
318 | "子过程描述": "返回H5页面告警组件数据修改回执信息",
319 | "数据移动类型": "X",
320 | "数据组": "H5页面告警组件数据修改回执信息",
321 | "数据属性": "修改的H5页面告警组件数据入库结果",
322 | "复用度": "新增",
323 | "CFP": 1
324 | },
325 | {
326 | "客户需求": "监控排障需求",
327 | "一级模块": "故障调度",
328 | "二级模块": "含H5链接的事件督办",
329 | "三级模块": "H5页面配置",
330 | "功能用户": "发起者:操作员\n接收者:H5页面告警组件配置管理",
331 | "触发事件": "收到接口调用请求",
332 | "功能过程": "H5页面告警组件查询接口",
333 | "子过程描述": "接收H5页面告警组件查询请求",
334 | "数据移动类型": "E",
335 | "数据组": "H5页面告警组件查询接口调用参数",
336 | "数据属性": "H5页面告警组件查询接口路径、查询条件",
337 | "复用度": "新增",
338 | "CFP": 1
339 | },
340 | {
341 | "客户需求": "监控排障需求",
342 | "一级模块": "故障调度",
343 | "二级模块": "含H5链接的事件督办",
344 | "三级模块": "H5页面配置",
345 | "功能用户": "发起者:操作员\n接收者:H5页面告警组件配置管理",
346 | "触发事件": "收到接口调用请求",
347 | "功能过程": "H5页面告警组件查询接口",
348 | "子过程描述": "获取H5页面告警组件数据",
349 | "数据移动类型": "R",
350 | "数据组": "H5页面告警组件",
351 | "数据属性": "H5页面告警组件标识、组件类型、应用场景、包含告警标签、告警标签显示顺序",
352 | "复用度": "新增",
353 | "CFP": 1
354 | },
355 | {
356 | "客户需求": "监控排障需求",
357 | "一级模块": "故障调度",
358 | "二级模块": "含H5链接的事件督办",
359 | "三级模块": "H5页面配置",
360 | "功能用户": "发起者:操作员\n接收者:H5页面告警组件配置管理",
361 | "触发事件": "收到接口调用请求",
362 | "功能过程": "H5页面告警组件查询接口",
363 | "子过程描述": "返回H5页面告警组件数据",
364 | "数据移动类型": "X",
365 | "数据组": "H5页面告警组件",
366 | "数据属性": "H5页面告警组件标识、组件类型、应用场景、包含告警标签、告警标签显示顺序",
367 | "复用度": "新增",
368 | "CFP": 1
369 | },
370 | {
371 | "客户需求": "监控排障需求",
372 | "一级模块": "故障调度",
373 | "二级模块": "含H5链接的事件督办",
374 | "三级模块": "H5页面配置",
375 | "功能用户": "发起者:操作员\n接收者:H5页面事件组件配置管理",
376 | "触发事件": "操作员在界面操作",
377 | "功能过程": "增加H5页面事件组件",
378 | "子过程描述": "输入H5页面事件组件增加信息",
379 | "数据移动类型": "E",
380 | "数据组": "H5页面事件组件增加信息",
381 | "数据属性": "事件组件呈现名称、对应事件ID、事件名称、数据源、组件描述、创建人",
382 | "复用度": "新增",
383 | "CFP": 1
384 | },
385 | {
386 | "客户需求": "监控排障需求",
387 | "一级模块": "故障调度",
388 | "二级模块": "含H5链接的事件督办",
389 | "三级模块": "H5页面配置",
390 | "功能用户": "发起者:操作员\n接收者:H5页面事件组件配置管理",
391 | "触发事件": "操作员在界面操作",
392 | "功能过程": "增加H5页面事件组件",
393 | "子过程描述": "调用增加H5页面事件组件接口",
394 | "数据移动类型": "X",
395 | "数据组": "增加H5页面事件组件接口调用参数",
396 | "数据属性": "增加H5页面事件组件接口路径、H5页面事件组件增加信息明细",
397 | "复用度": "新增",
398 | "CFP": 1
399 | },
400 | {
401 | "客户需求": "监控排障需求",
402 | "一级模块": "故障调度",
403 | "二级模块": "含H5链接的事件督办",
404 | "三级模块": "H5页面配置",
405 | "功能用户": "发起者:操作员\n接收者:H5页面事件组件配置管理",
406 | "触发事件": "操作员在界面操作",
407 | "功能过程": "增加H5页面事件组件",
408 | "子过程描述": "H5页面事件组件增加内容入库操作写入系统日志",
409 | "数据移动类型": "W",
410 | "数据组": "H5页面事件组件增加日志",
411 | "数据属性": "操作人、操作模块、操作时间、H5页面事件组件增加内容入库具体操作、操作结果",
412 | "复用度": "新增",
413 | "CFP": 1
414 | },
415 | {
416 | "客户需求": "监控排障需求",
417 | "一级模块": "故障调度",
418 | "二级模块": "含H5链接的事件督办",
419 | "三级模块": "H5页面配置",
420 | "功能用户": "发起者:操作员\n接收者:H5页面事件组件配置管理",
421 | "触发事件": "操作员在界面操作",
422 | "功能过程": "删除H5页面事件组件",
423 | "子过程描述": "输入H5页面事件组件删除信息",
424 | "数据移动类型": "E",
425 | "数据组": "H5页面事件组件删除信息",
426 | "数据属性": "H5页面事件组件删除指令",
427 | "复用度": "新增",
428 | "CFP": 1
429 | },
430 | {
431 | "客户需求": "监控排障需求",
432 | "一级模块": "故障调度",
433 | "二级模块": "含H5链接的事件督办",
434 | "三级模块": "H5页面配置",
435 | "功能用户": "发起者:操作员\n接收者:H5页面事件组件配置管理",
436 | "触发事件": "操作员在界面操作",
437 | "功能过程": "删除H5页面事件组件",
438 | "子过程描述": "调用删除H5页面事件组件接口",
439 | "数据移动类型": "X",
440 | "数据组": "删除H5页面事件组件接口调用参数",
441 | "数据属性": "删除H5页面事件组件接口路径、H5页面事件组件删除明细",
442 | "复用度": "新增",
443 | "CFP": 1
444 | },
445 | {
446 | "客户需求": "监控排障需求",
447 | "一级模块": "故障调度",
448 | "二级模块": "含H5链接的事件督办",
449 | "三级模块": "H5页面配置",
450 | "功能用户": "发起者:操作员\n接收者:H5页面事件组件配置管理",
451 | "触发事件": "操作员在界面操作",
452 | "功能过程": "删除H5页面事件组件",
453 | "子过程描述": "H5页面事件组件删除内容入库操作写入系统日志",
454 | "数据移动类型": "X",
455 | "数据组": "H5页面事件组件删除加日志",
456 | "数据属性": "删除人、删除模块、删除时间、H5页面事件组件删除内容具体操作、删除结果",
457 | "复用度": "新增",
458 | "CFP": 1
459 | },
460 | {
461 | "客户需求": "监控排障需求",
462 | "一级模块": "故障调度",
463 | "二级模块": "含H5链接的事件督办",
464 | "三级模块": "H5页面配置",
465 | "功能用户": "发起者:操作员\n接收者:H5页面事件组件配置管理",
466 | "触发事件": "操作员在界面操作",
467 | "功能过程": "修改H5页面事件组件",
468 | "子过程描述": "输入H5页面事件组件修改信息",
469 | "数据移动类型": "E",
470 | "数据组": "H5页面事件组件修改信息",
471 | "数据属性": "H5页面事件组件修改指令",
472 | "复用度": "新增",
473 | "CFP": 1
474 | },
475 | {
476 | "客户需求": "监控排障需求",
477 | "一级模块": "故障调度",
478 | "二级模块": "含H5链接的事件督办",
479 | "三级模块": "H5页面配置",
480 | "功能用户": "发起者:操作员\n接收者:H5页面事件组件配置管理",
481 | "触发事件": "操作员在界面操作",
482 | "功能过程": "修改H5页面事件组件",
483 | "子过程描述": "调用修改H5页面事件组件接口",
484 | "数据移动类型": "X",
485 | "数据组": "修改H5页面事件组件接口调用参数",
486 | "数据属性": "修改H5页面事件组件接口路径、事件组件呈现名称、对应事件ID、事件名称、数据源、组件描述、创建人",
487 | "复用度": "新增",
488 | "CFP": 1
489 | },
490 | {
491 | "客户需求": "监控排障需求",
492 | "一级模块": "故障调度",
493 | "二级模块": "含H5链接的事件督办",
494 | "三级模块": "H5页面配置",
495 | "功能用户": "发起者:操作员\n接收者:H5页面事件组件配置管理",
496 | "触发事件": "操作员在界面操作",
497 | "功能过程": "修改H5页面事件组件",
498 | "子过程描述": "H5页面事件组件修改内容入库操作写入系统日志",
499 | "数据移动类型": "X",
500 | "数据组": "H5页面事件组件修改加日志",
501 | "数据属性": "修改人、修改模块、修改时间、H5页面事件组件修改内容入库具体操作、修改结果",
502 | "复用度": "新增",
503 | "CFP": 1
504 | },
505 | {
506 | "客户需求": "监控排障需求",
507 | "一级模块": "故障调度",
508 | "二级模块": "含H5链接的事件督办",
509 | "三级模块": "H5页面配置",
510 | "功能用户": "发起者:操作员\n接收者:H5页面事件组件配置管理",
511 | "触发事件": "操作员在界面操作",
512 | "功能过程": "H5页面事件组件查询",
513 | "子过程描述": "输入H5页面事件组件查询请求",
514 | "数据移动类型": "E",
515 | "数据组": "H5页面事件组件查询请求",
516 | "数据属性": "H5页面事件组件管理查询指令",
517 | "复用度": "新增",
518 | "CFP": 1
519 | },
520 | {
521 | "客户需求": "监控排障需求",
522 | "一级模块": "故障调度",
523 | "二级模块": "含H5链接的事件督办",
524 | "三级模块": "H5页面配置",
525 | "功能用户": "发起者:操作员\n接收者:H5页面事件组件配置管理",
526 | "触发事件": "操作员在界面操作",
527 | "功能过程": "H5页面事件组件查询",
528 | "子过程描述": "调用H5页面事件组件查询接口",
529 | "数据移动类型": "R",
530 | "数据组": "H5页面事件组件查询接口调用参数",
531 | "数据属性": "H5页面事件组件查询接口路径、查询条件",
532 | "复用度": "新增",
533 | "CFP": 1
534 | },
535 | {
536 | "客户需求": "监控排障需求",
537 | "一级模块": "故障调度",
538 | "二级模块": "含H5链接的事件督办",
539 | "三级模块": "H5页面配置",
540 | "功能用户": "发起者:操作员\n接收者:H5页面事件组件配置管理",
541 | "触发事件": "操作员在界面操作",
542 | "功能过程": "H5页面事件组件查询",
543 | "子过程描述": "呈现H5页面事件组件查询出的数据",
544 | "数据移动类型": "X",
545 | "数据组": "H5页面事件组件查询出的数据",
546 | "数据属性": "事件组件呈现名称、对应事件ID、事件名称、数据源、组件描述、创建人",
547 | "复用度": "新增",
548 | "CFP": 1
549 | }
550 | ]
551 | ```
552 |
553 |
--------------------------------------------------------------------------------