chat_service.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. import ollama
  2. import psycopg2
  3. import json
  4. import uuid
  5. import datetime
  6. from llm_model.query import query
  7. from psycopg2.extras import DictCursor
  8. import pandas as pd
  9. import time
  10. from app.utils.pinyin_utils import replace_word
  11. from app.common.word import target_word
  12. from app.common.res import res_success, res_error
  13. from app.utils.log_utils import logger
  14. import re
  15. from markdownify import markdownify
  16. # read_csv = pd.read_csv("E:\\siwei_ai\\poi.csv")
  17. # first_column = read_csv.iloc[:, 0]
  18. # poi_list = first_column.tolist()
  19. # # 将每个 POI 用双引号包裹,并用逗号拼接
  20. # poi_str = ",".join(f'"{poi}"' for poi in poi_list)
  21. # # 保存为 TXT 文件
  22. # with open("E:\\siwei_ai\\poi_list.txt", "w", encoding="utf-8") as file:
  23. # file.write(poi_str)
  24. # print("POI 列表已保存至 poi_list.txt(逗号分隔)")
  25. chat_history = "用户:你好,我是智能助手,请问有什么可以帮助您?\\n智能助手:好的,请问您有什么需求?"
  26. sys_xuanzhi = """请扮演文本提取工具,根据输入和聊天上下文信息,基于以下行政区划、选址点名称、因子选择和用地类型提取这句话中的关键信息,用户没有提及到行政区划和选址点名称则返回空值。提取到的结果请严格以json格式输出并保障寄送格式正确无误,
  27. 行政区划 = ['抱坡区','天涯区','崖州区','海棠区','吉阳区' ]
  28. 选址点名称 = ['南新中学宿舍',"三亚市人民医院-2号综合楼","三亚蜈支洲岛度假中心-医务所","润春堂药店","长春堂药店(荔枝沟路店)" ],
  29. 因子选择 = ["高程","坡度","永久基本农田","城镇开发边界内","生态保护红线","文化保护区","自然保护地","风景名胜区","国有使用权","河道管理线","水库","公益林","火葬场","垃圾处理场","污水处理场","高压线","变电站","古树","城市道路","主要出入口","文化活动设施","体育运动场所","排水","供水","燃气","电力","电信","十五分钟社区生活圈邻里中心","社区服务设施","零售商业场所","医疗卫生设施","幼儿园服务半径","小学服务半径","为老服务设施"],
  30. 用地类型 = ['园地','耕地','林地','草地','湿地','公共卫生用地','老年人社会福利用地','儿童社会福利用地','残疾人社会福利用地','其他社会福利用地','零售商业用地','批发市场用地','餐饮用地','旅馆用地','公用设施营业网点用地','娱乐用地','康体用地','一类工业用地','二类工业用地','广播电视设施用地','环卫用地','消防用地','干渠','水工设施用地','其他公用设施用地','公园绿地','防护绿地','广场用地','军事设施用地','使领馆用地','宗教用地','文物古迹用地','监教场所用地','殡葬用地','其他特殊用地','河流水面','湖泊水面','水库水面','坑塘水面','沟渠','冰川及常年积雪','渔业基础设施用海','增养殖用海','捕捞海域','工业用海','盐田用海','固体矿产用海','油气用海','可再生能源用海','海底电缆管道用海','港口用海','农业设施建设用地','工矿用地','畜禽养殖设施建设用地','水产养殖设施建设用地','城镇住宅用地','特殊用地','居住用地','绿地与开敞空间用地','水田','水浇地','旱地','果园','茶园','橡胶园','其他园地','乔木林地','竹林地','城镇社区服务设施用地','农村宅基地','农村社区服务设施用地','机关团体用地','科研用地','文化用地','教育用地','体育用地','医疗卫生用地','社会福利用地','商业用地','商务金融用地','二类农村宅基地','图书与展览用地','文化活动用地','高等教育用地','中等职业教育用地','体育训练用地','其他交通设施用地','供水用地','排水用地','供电用地','供燃气用地','供热用地','通信用地','邮政用地','医院用地','基层医疗卫生设施用地','田间道','盐碱地','沙地','裸土地','裸岩石砾地','村道用地','村庄内部道路用地','公共管理与公共服务用地','仓储用地','交通运输用地','公用设施用地','交通运输用海','航运用海','路桥隧道用海','风景旅游用海','文体休闲娱乐用海','军事用海','其他特殊用海','空闲地','田坎','港口码头用地','管道运输用地','城市轨道交通用地','城镇道路用地','交通场站用地','一类城镇住宅用地','二类城镇住宅用地','三类城镇住宅用地','一类农村宅基地','商业服务业用地','三类工业用地','一类物流仓储用地','二类物流仓储用地','三类物流仓储用地','盐田','对外交通场站用地','公共交通场站用地','社会停车场用地','中小学用地','幼儿园用地','其他教育用地','体育场馆用地','灌木林地','其他林地','天然牧草地','人工牧草地','其他草地','森林沼泽','灌丛沼泽','沼泽草地','其他沼泽地','沿海滩涂','内陆滩涂','红树林地','乡村道路用地','种植设施建设用地','娱乐康体用地','其他商业服务业用地','工业用地','采矿用地','物流仓储用地','储备库用地','铁路用地','公路用地','机场用地'],
  31. landType是用地类型
  32. districtName是行政区划
  33. poi是选址点名称
  34. area是用地面积,单位为亩,min是最小面积,max是最大面积,
  35. factors是因子选择
  36. buffer是缓冲距离,单位为米
  37. 其他公里、千米的单位转换为米
  38. 输出json格式数据如下:
  39. {
  40.     "districtName": "",
  41.     "poi":"",
  42.     "buffer":30,
  43. "landType": "居住用地",
  44.     "area": {
  45.         "min": 10,
  46.         "max": 100
  47.     },
  48.     "factors": [
  49.         {
  50.             "type": "医疗卫生设施",
  51.             "condition": "lt",
  52.             "value": "500"
  53.         },
  54.         {
  55.             "type": "永久基本农田",
  56.             "condition": "not_intersect"
  57.         },
  58.         {
  59.             "type": "火葬场",
  60.             "condition": "gt",
  61.             "value": "1000"
  62.         },
  63. {
  64.             "type": "幼儿园服务半径",
  65.             "condition": "lt",
  66.             "value": "1000"
  67.         },
  68. {
  69.             "type": "小学服务半径",
  70.             "condition": "lt",
  71.             "value": "1000"
  72.         },
  73.     ]
  74. }
  75. json中"condition"的值为"gt"、"lt"、"get"、"let"、"between","not_intersect"、"intersect"、"not_contain"、"contain"、"between"
  76. """
  77. sys_question = """请扮演问答工具,对用户输入信息进行回答,请严格以markdown格式输出并保障寄送格式正确无误"""
  78. # 连接数据库
  79. conn = psycopg2.connect(
  80. dbname="real3d",
  81. user="postgres",
  82. password="postgis",
  83. # host="192.168.100.30",
  84. host="192.168.60.2",
  85. port="5432"
  86. )
  87. # 清除聊天记录
  88. def clear_chat_history():
  89. global chat_history
  90. chat_history = ""
  91. return chat_history
  92. def extract_json(text):
  93. json_marker = "```json"
  94. start_pos = text.find(json_marker)
  95. if start_pos == -1:
  96. return None
  97. # 从```json后面开始找JSON内容
  98. json_start = text.find('{', start_pos + len(json_marker))
  99. if json_start == -1:
  100. return None
  101. end_marker = "```"
  102. end_pos = text.find(end_marker, json_start)
  103. if end_pos == -1:
  104. json_end = text.rfind('}', json_start)
  105. else:
  106. json_end = text.rfind('}', json_start, end_pos)
  107. if json_end == -1:
  108. return None
  109. # 提取JSON字符串并打印出来看看内容
  110. json_str = text[json_start:json_end + 1]
  111. print("提取的JSON字符串:")
  112. print(json_str)
  113. json_str = json_str.replace("\xa0", " ")
  114. print(json_str)
  115. try:
  116. return json.loads(json_str)
  117. except json.JSONDecodeError as e:
  118. print("JSON解析错误:", e)
  119. # 打印出错误位置附近的内容
  120. error_pos = e.pos
  121. print("错误位置附近的内容:")
  122. print(json_str[max(0, error_pos-20):min(len(json_str), error_pos+20)])
  123. return None
  124. def create_chat(msg, type_ai):
  125. # msg = data['msg']
  126. # type = data['type']
  127. if type_ai == 'selectLand':
  128. # 同音字替换
  129. msg = replace_word(msg, target_word)
  130. words_to_replace1 = ["爆破", "爆坡", "鲍坡"]
  131. for word in words_to_replace1:
  132. msg = msg.replace(word, "抱坡")
  133. print(msg)
  134. # 调用大模型解析
  135. # 这里调用大模型,并返回解析结果
  136. start = time.time()
  137. res = update_chat_history(msg)
  138. print(res) # 打印生成的回复
  139. end = time.time()
  140. print("解析时间:", end - start)
  141. # 解析结果返回给前端
  142. # 未找到相关数据提示
  143. prompt = "根据提供的信息,您的表述不够清晰明确,为更好的达到您的选址需求,请重新描述您的选址条件。"
  144. addtress = ['抱坡区', '天涯区', '崖州区', '海棠区', '吉阳区']
  145. poi_list = ['南新中学宿舍', '三亚市人民医院-2号综合楼', '三亚蜈支洲岛度假中心-医务所', '润春堂药店', '长春堂药店(荔枝沟路店)']
  146. land = ['园地', '耕地', '林地', '草地', '湿地', '公共卫生用地', '老年人社会福利用地', '儿童社会福利用地', '残疾人社会福利用地', '其他社会福利用地', '零售商业用地', '批发市场用地', '餐饮用地', '旅馆用地', '公用设施营业网点用地', '娱乐用地', '康体用地', '一类工业用地', '二类工业用地', '广播电视设施用地', '环卫用地', '消防用地', '干渠', '水工设施用地', '其他公用设施用地', '公园绿地', '防护绿地', '广场用地', '军事设施用地', '使领馆用地', '宗教用地', '文物古迹用地', '监教场所用地', '殡葬用地', '其他特殊用地', '河流水面', '湖泊水面', '水库水面', '坑塘水面', '沟渠', '冰川及常年积雪', '渔业基础设施用海', '增养殖用海', '捕捞海域', '工业用海', '盐田用海', '固体矿产用海', '油气用海', '可再生能源用海', '海底电缆管道用海', '港口用海', '农业设施建设用地', '工矿用地', '畜禽养殖设施建设用地', '水产养殖设施建设用地', '城镇住宅用地', '特殊用地', '居住用地', '绿地与开敞空间用地', '水田', '水浇地', '旱地', '果园', '茶园', '橡胶园', '其他园地', '乔木林地', '竹林地', '城镇社区服务设施用地', '农村宅基地', '农村社区服务设施用地', '机关团体用地', '科研用地', '文化用地', '教育用地', '体育用地', '医疗卫生用地', '社会福利用地', '商业用地', '商务金融用地', '二类农村宅基地', '图书与展览用地',
  147. '文化活动用地', '高等教育用地', '中等职业教育用地', '体育训练用地', '其他交通设施用地', '供水用地', '排水用地', '供电用地', '供燃气用地', '供热用地', '通信用地', '邮政用地', '医院用地', '基层医疗卫生设施用地', '田间道', '盐碱地', '沙地', '裸土地', '裸岩石砾地', '村道用地', '村庄内部道路用地', '公共管理与公共服务用地', '仓储用地', '交通运输用地', '公用设施用地', '交通运输用海', '航运用海', '路桥隧道用海', '风景旅游用海', '文体休闲娱乐用海', '军事用海', '其他特殊用海', '空闲地', '田坎', '港口码头用地', '管道运输用地', '城市轨道交通用地', '城镇道路用地', '交通场站用地', '一类城镇住宅用地', '二类城镇住宅用地', '三类城镇住宅用地', '一类农村宅基地', '商业服务业用地', '三类工业用地', '一类物流仓储用地', '二类物流仓储用地', '三类物流仓储用地', '盐田', '对外交通场站用地', '公共交通场站用地', '社会停车场用地', '中小学用地', '幼儿园用地', '其他教育用地', '体育场馆用地', '灌木林地', '其他林地', '天然牧草地', '人工牧草地', '其他草地', '森林沼泽', '灌丛沼泽', '沼泽草地', '其他沼泽地', '沿海滩涂', '内陆滩涂', '红树林地', '乡村道路用地', '种植设施建设用地', '娱乐康体用地', '其他商业服务业用地', '工业用地', '采矿用地', '物流仓储用地', '储备库用地', '铁路用地', '公路用地', '机场用地']
  148. # json_res = res.replace("json", "")
  149. # json_res = json_res.replace("```", "")
  150. # 使用正则表达式提取<think>标签之间的内容
  151. match = re.search(r'<think>(.*?)</think>', res, re.DOTALL)
  152. if match:
  153. think_content = match.group(1)
  154. think_content = think_content.replace("\n", "")
  155. think_content = markdownify(think_content) # 转换为 Markdown
  156. # print(think_content)
  157. else:
  158. print("没有找到<think>标签内容。")
  159. # 使用这个函数处理你的json_res
  160. json_res = extract_json(res)
  161. print(json_res) # 打印生成的回复
  162. # if json_data:
  163. # districtName = json_data["districtName"]
  164. # else:
  165. # print("无法提取有效的JSON数据")
  166. if json_res != "未找到相关数据":
  167. # try:
  168. print(type(json_res)) # 检查 json_res 的类型
  169. districtName = json_res["districtName"]
  170. landType = json_res["landType"]
  171. poi = json_res["poi"]
  172. # if landType != "未找到相关数据" and landType != "" and districtName != "未找到相关数据"and districtName != "":
  173. if landType in land and( districtName in addtress or poi in poi_list):
  174. json_res = jsonResToDict(json_res, poi, think_content)
  175. # print(json_res)
  176. else:
  177. json_res = prompt
  178. json_res = res_error(json_res, "selectLand", "error1")
  179. # except:
  180. # json_res = prompt
  181. # json_res = res_error(json_res, "selectLand", "error2")
  182. else:
  183. json_res = prompt
  184. json_res = res_error(json_res, "selectLand", "error3")
  185. return json_res
  186. elif type_ai == 'answer':
  187. # json_res = route_query(msg)
  188. # json_res = jsonResToDict_questions(json_res)
  189. # print(json_res) # 打印生成的回复
  190. json_res = update_chat_history_simple(msg)
  191. json_res = res_success(json_res, "answer", "success")
  192. print(json_res) # 打印生成的回复
  193. return json_res
  194. # 智能选址
  195. def update_chat_history(user_message):
  196. global chat_history # 使用全局变量以便更新
  197. prompt = chat_history + "\\n用户:" + user_message
  198. # 生成回复,并加入聊天上下文
  199. res = ollama.generate(
  200. # model="qwen2.5:3b",
  201. model="deepseek-r1:7b",
  202. stream=False,
  203. system=sys_xuanzhi,
  204. prompt=prompt,
  205. options={"temperature": 0, "num_ctx": 32000, },
  206. keep_alive=-1
  207. )
  208. # 获取机器人回复
  209. bot_message = res["response"]
  210. # 更新聊天历史
  211. # chat_history += "\\n智能助手:" + bot_message
  212. # 返回机器人的回复
  213. return bot_message
  214. # 将大模型解析的结果转换为选址需要的数据格式
  215. def jsonResToDict(json_res, poi,think_content):
  216. # 1.查询选址范围信息
  217. # 位置点为空,利用行政区划选址
  218. if poi == "":
  219. print("位置点为空,利用行政区划选址")
  220. ewkt = getAiDistrict(json_res["districtName"])
  221. # 位置点不为空,利用位置点选址
  222. else:
  223. ewkt = getPoiArea(json_res["poi"],json_res["buffer"])
  224. print("位置点不为空,利用位置点选址")
  225. # 2.保存选址范围信息
  226. geomId = saveGeom(ewkt)
  227. # 3.获取用地类型信息
  228. landType = json_res["landType"]
  229. landType = getLandType(landType, "YDYHFLDM")
  230. # 4.获取模板信息
  231. factorTemplates = getTemplateByCode(landType)
  232. # TODO 以哪个因子列表为准,模版和因子个数怎么匹配
  233. now = datetime.datetime.now()
  234. formatted_time = now.strftime("%Y%m%d%H%M%S")
  235. res = {
  236. "xzmj": 1500,
  237. "xmmc": "规划选址项目_"+formatted_time,
  238. "jsdw": "建设单位",
  239. "ydxz_bsm": landType,
  240. "ydmjbegin": json_res["area"]["min"],
  241. "ydmjend": json_res["area"]["max"],
  242. "geomId": geomId,
  243. "yxyz": [],
  244. # TODO: 循环遍历
  245. # "yxyz": [
  246. # {
  247. # "id": "259e5bbaab434dbfb9c679bd44d4bfa4",
  248. # "name": "幼儿园服务半径",
  249. # "bsm": "TB_YEY",
  250. # "conditionInfo": {
  251. # "spatial_type": "distance",
  252. # "default": "lt",
  253. # "hasValue": true,
  254. # "defaultValue": "300",
  255. # "unit": "米",
  256. # "clip": false
  257. # }
  258. # }
  259. # ],
  260. # "useMultiple": json_res["useMultiple"],
  261. "useLandType": True,
  262. # "multipleDistance": json_res["multipleDistance"]
  263. }
  264. # 循环遍历输入因子
  265. factors = json_res["factors"]
  266. input_factors = {}
  267. for factor in factors:
  268. factorInfo = getFactorByName(factor["type"])
  269. if factorInfo == None:
  270. continue
  271. factorId = factorInfo["id"]
  272. factorBsm = factorInfo["bsm"]
  273. conditionInfo = factorInfo["condition_info"]
  274. conditionObj = json.loads(conditionInfo)
  275. defaultValue = '0'
  276. default = 'lt'
  277. if "value" in factor:
  278. defaultValue = str(factor["value"])
  279. if "condition" in factor:
  280. default = factor["condition"]
  281. # if defaultValue == '':
  282. # defaultValue = '0'
  283. factor_info = {
  284. "id": factorId,
  285. "name": factor["type"],
  286. "bsm": factorBsm,
  287. "conditionInfo": {
  288. "spatial_type": conditionObj["spatial_type"],
  289. "default": default,
  290. "hasValue": conditionObj["hasValue"],
  291. "defaultValue": defaultValue,
  292. "unit": conditionObj["unit"],
  293. "clip": conditionObj["clip"]
  294. }
  295. }
  296. input_factors[factor_info["id"]] = factor_info
  297. # 循环遍历模板
  298. # 记录已经添加的因子 ID
  299. added_factor_ids = set()
  300. # 首先处理模板
  301. for factorTemplate in factorTemplates:
  302. factorId = factorTemplate["id"]
  303. factorTemplate["conditionInfo"] = json.loads(
  304. factorTemplate["conditionInfo"])
  305. res["yxyz"].append(factorTemplate)
  306. added_factor_ids.add(factorId) # 记录已添加的因子 ID
  307. # 然后检查 input_factors 并添加未在模板中的因子
  308. for factor_id, factor_info in input_factors.items():
  309. if factor_id not in added_factor_ids:
  310. res["yxyz"].append(factor_info)
  311. resObj = {}
  312. resObj["data"] = res
  313. resObj["code"] = 200
  314. resObj["think"] = think_content
  315. resObj["type"] = "selectLand"
  316. return resObj
  317. # 获取因子信息
  318. def getFactorByName(name):
  319. with conn.cursor(cursor_factory=DictCursor) as cur:
  320. sql = "SELECT * FROM base.t_fzss_fzxz_factor WHERE name = %s"
  321. complete_sql = cur.mogrify(sql, (name,)).decode('utf-8')
  322. logger.info(f"Executing SQL: {complete_sql}")
  323. cur.execute(sql, (name,))
  324. res = cur.fetchone()
  325. return res
  326. # 获取选址范围信息
  327. def getAiDistrict(name):
  328. with conn.cursor(cursor_factory=DictCursor) as cur:
  329. sql = "SELECT public.st_asewkt(geom) as geom FROM base.t_fzss_fzxz_ai_district WHERE name = %s"
  330. complete_sql = cur.mogrify(sql, (name,)).decode('utf-8')
  331. logger.info(f"Executing SQL: {complete_sql}")
  332. cur.execute(sql, (name,))
  333. res = cur.fetchone()
  334. return res["geom"]
  335. # 获取位置点信息区域
  336. def getPoiArea(name, buffer):
  337. with conn.cursor(cursor_factory=DictCursor) as cur:
  338. # SQL query with LIKE and buffer
  339. sql = """
  340. SELECT public.st_asewkt(public.st_buffer(geom::public.geography, %s)) as geom
  341. FROM vector.poi
  342. WHERE name LIKE %s
  343. """
  344. # Use % for LIKE query, adding % around the name parameter
  345. like_name = f"%{name}%"
  346. # Format the query
  347. complete_sql = cur.mogrify(sql, (buffer, like_name)).decode('utf-8')
  348. logger.info(f"Executing SQL: {complete_sql}")
  349. # Execute the query
  350. cur.execute(sql, (buffer, like_name))
  351. res = cur.fetchone()
  352. return res["geom"]
  353. # 保存选址范围信息
  354. def saveGeom(ewkt):
  355. new_uuid = str(uuid.uuid4()) # 生成一个新的 UUID
  356. from_type = 3
  357. with conn.cursor() as cur:
  358. sql = "INSERT INTO base.t_fzss_zhxz_file(id,geom,from_type,create_time,area) VALUES (%s,public.st_geomfromewkt(%s),%s,now(),public.st_area(public.st_geomfromewkt(%s)::public.geography))"
  359. complete_sql = cur.mogrify(
  360. sql, (new_uuid, ewkt, from_type, ewkt)).decode('utf-8')
  361. logger.info(f"Executing SQL: {complete_sql}")
  362. cur.execute(sql, (new_uuid, ewkt, from_type, ewkt))
  363. conn.commit()
  364. return new_uuid
  365. # 获取用地类型信息
  366. def getLandType(landName, fzbs):
  367. with conn.cursor(cursor_factory=DictCursor) as cur:
  368. sql = "SELECT dm,mc,fzbs FROM base.t_fzss_fzxz_dict WHERE mc = %s and fzbs=%s"
  369. complete_sql = cur.mogrify(sql, (landName, fzbs)).decode('utf-8')
  370. logger.info(f"Executing SQL: {complete_sql}")
  371. cur.execute(sql, (landName, fzbs))
  372. res = cur.fetchone()
  373. return res["dm"]
  374. # 获取内置模板信息
  375. def getTemplateByCode(code):
  376. with conn.cursor(cursor_factory=DictCursor) as cur:
  377. sql = 'SELECT factor_id as id,factor_name as name,factor_bsm as bsm,condition_info as "conditionInfo" FROM base.t_fzss_fzxz_factor_temp WHERE land_type_code = %s'
  378. complete_sql = cur.mogrify(sql, (code,)).decode('utf-8')
  379. logger.info(f"Executing SQL: {complete_sql}")
  380. cur.execute(sql, (code,))
  381. res = cur.fetchall()
  382. # 将查询结果转换为字典列表
  383. result_list = [dict(row) for row in res]
  384. return result_list
  385. # 简单知识问答,未关联本地知识库
  386. def update_chat_history_simple(user_message):
  387. global chat_history # 使用全局变量以便更新
  388. prompt = chat_history + "\\n用户:" + user_message
  389. # 生成回复,并加入聊天上下文
  390. res = ollama.generate(
  391. model="deepseek-r1:1.5b",
  392. stream=False,
  393. system=sys_question,
  394. prompt=prompt,
  395. options={"temperature": 0, "num_ctx": 32000, },
  396. keep_alive=-1
  397. )
  398. # 获取机器人回复
  399. bot_message = res["response"] + "感谢您的提问,四维智能助手将竭诚为您解答。"
  400. # 更新聊天历史
  401. chat_history += "\\n智能助手:" + bot_message
  402. # 返回机器人的回复
  403. return bot_message
  404. def route_query(msg):
  405. response = query(msg)
  406. # print(response)
  407. # if response:
  408. # resObj = {}
  409. # resObj["data"] = response
  410. # resObj["code"] = 200
  411. # resObj["type"] = "answer"
  412. # return resObj
  413. # return {"error": "Something went wrong"}, 400
  414. return response