完成了LLM的适配,DIfy暂时不用

This commit is contained in:
pengGgxp 2025-05-01 18:14:28 +08:00
parent ec4cb87ed7
commit 365b8a488c
21 changed files with 4757 additions and 260 deletions

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-#
# -------------------------------------------------------------------------------
# Name: utils.py
# Name: api_utils.py
# Description:
# Author: xaoyaoo
# Date: 2023/12/03

View File

View File

@ -0,0 +1,14 @@
# 接入dify工作流,用来制作微信聊天记录可视化
class Dify(object):
def __init__(self):
api_key = ""
api_base_url = ""
#TODO: 文件上传
def file_upload(self):
pass
#TODO: 运行工作流
def run_workflows(self):
pass

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -161,12 +161,12 @@ def export_json_mini_time_limit(wxid, outpath, db_config, my_wxid="我",
start_part = start_createtime.replace(" ", "_").replace(":", "-") if start_createtime else "all"
end_part = end_createtime.replace(" ", "_").replace(":", "-") if end_createtime else "now"
time_suffix = f"_{start_part}_to_{end_part}"
save_path = os.path.join(outpath, f"{wxid}_mini{time_suffix}.json")
filename = f"{wxid}_mini{time_suffix}.json"
save_path = os.path.join(outpath, filename)
with open(save_path, "w", encoding="utf-8") as f:
json.dump(mini_data, f, ensure_ascii=False, indent=indent)
return True, f"导出成功: {save_path}"
return True, f"导出成功: {save_path}", filename

View File

@ -13,6 +13,7 @@ from collections import Counter
from urllib.parse import quote, unquote
from typing import List, Optional
import fastapi.requests
from pydantic import BaseModel
from fastapi import APIRouter, Response, Body, Query, Request
from starlette.responses import StreamingResponse, FileResponse
@ -21,12 +22,15 @@ import pywxdump
from pywxdump import decrypt_merge, get_core_db
from pywxdump.db import DBHandler
from pywxdump.db.utils import download_file, dat2img
from .api_utils.html import HtmlController
from .export import export_csv, export_json, export_html
from .export.exportJSON import export_json_mini, export_json_mini_time_limit
from .rjson import ReJson, RqJson
from .utils import error9999, gc, asyncError9999, rs_loger
rs_api = APIRouter()
@ -466,13 +470,49 @@ def get_export_json(wxid: str = Body(..., embed=True)):
if not os.path.exists(outpath):
os.makedirs(outpath)
code, ret = export_json_mini_time_limit(wxid, outpath, db_config, my_wxid=my_wxid,start_createtime="2025-4-29 00:00:00", end_createtime="2025-4-30 00:00:00")
code, ret = export_json(wxid, outpath, db_config, my_wxid=my_wxid)
if code:
return ReJson(0, ret)
else:
return ReJson(2001, body=ret)
class ExportJsonMiniRequest(BaseModel):
start_createtime: str
end_createtime: str
@rs_api.api_route('/export_json_mini_select_time', methods=["GET", 'POST'])
def get_export_json(wxid: str = Body(..., embed=True),time: ExportJsonMiniRequest = Body(..., embed=True)):
"""
导出json,选择时间迷你版本
:return:
"""
my_wxid = gc.get_conf(gc.at, "last")
if not my_wxid: return ReJson(1001, body="my_wxid is required")
db_config = gc.get_conf(my_wxid, "db_config")
if not wxid:
return ReJson(1002, body=f"username is required: {wxid}")
outpath = os.path.join(gc.work_path, "export", my_wxid, "json", wxid)
if not os.path.exists(outpath):
os.makedirs(outpath)
start_createtime = time.start_createtime # 格式为 "2025-05-01 18:06:00"
end_createtime = time.end_createtime
code, ret,filename = export_json_mini_time_limit(wxid, outpath, db_config, my_wxid=my_wxid,start_createtime=start_createtime, end_createtime=end_createtime)
if code:
# 成功创建,执行生成可视化页面的逻辑
# with open(os.path.join(gc.work_path, "export", my_wxid, "html", wxid, filename), "w", encoding="utf-8") as f:
# f.write(
# #现在是fake
# HtmlController().create_html(json_data=None)
# )
return ReJson(0, ret)
else:
return ReJson(2001, body=ret)
@ -671,4 +711,61 @@ def get_readme():
else:
return ReJson(2001, body="status_code is not 200")
class DifyApiModel(BaseModel):
api_key:str
base_url:str
@rs_api.api_route('/dify_setting', methods=["GET", 'POST'])
@error9999
def dify_setting(request: Request = None, dify: DifyApiModel = Body(None, embed=True)):
"""
dify设置
"""
if request.method == "GET":
my_wxid = gc.get_conf(gc.at, "last")
if not my_wxid: return ReJson(1001, body="my_wxid is required")
gc.get_conf(my_wxid, "dify_setting")
return ReJson(0, body=gc.get_conf(my_wxid, "dify_setting"))
elif request.method == "POST":
my_wxid = gc.get_conf(gc.at, "last")
if not my_wxid: return ReJson(1001, body="my_wxid is required")
if not dify.api_key and not dify.base_url:
return ReJson(1002, body="dify_setting is required")
gc.set_conf(my_wxid, "dify_setting", {"API_KEY": dify.api_key, "BASE_URL": dify.base_url})
return ReJson(0, body=gc.get_conf(my_wxid, "dify_setting"))
return ReJson(2001, body="status_code is not 200")
class DeepSeekApiModel(BaseModel):
api_key:str
@rs_api.api_route('/deepseek_setting', methods=["GET", 'POST'])
@error9999
def deepseek_setting(request: Request = None, deepseek: DeepSeekApiModel = Body(None, embed=True)):
"""
deepseek设置
"""
if request.method == "GET":
my_wxid = gc.get_conf(gc.at, "last")
if not my_wxid: return ReJson(1001, body="my_wxid is required")
gc.get_conf(my_wxid, "deepseek_setting")
return ReJson(0, body=gc.get_conf(my_wxid, "deepseek_setting"))
elif request.method == "POST":
my_wxid = gc.get_conf(gc.at, "last")
if not my_wxid: return ReJson(1001, body="my_wxid is required")
if not deepseek or not deepseek.api_key:
return ReJson(1002, body="deepseek_setting is required")
gc.set_conf(my_wxid, "deepseek_setting", {"API_KEY": deepseek.api_key})
return ReJson(0, body=gc.get_conf(my_wxid, "deepseek_setting"))
return ReJson(2001, body="status_code is not 200")
# END 关于、帮助、设置 ***************************************************************************************************

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-#
# -------------------------------------------------------------------------------
# Name: utils.py
# Name: api_utils.py
# Description:
# Author: xaoyaoo
# Date: 2024/01/16

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-#
# -------------------------------------------------------------------------------
# Name: __init__.py.py
# Description: db.utils
# Description: db.api_utils
# Author: xaoyaoo
# Date: 2024/07/23
# -------------------------------------------------------------------------------

View File

@ -35,6 +35,20 @@
--section-gap: 160px;
}
/* 可视化页面的css*/
:root {
--bg-ui-s-primary: #0f0e17;
--bg-ui-s-secondary: #1a1925;
--bg-ui-s-tertiary: #252336;
--text-ui-s-primary: #fffffe;
--text-ui-s-secondary: #a7a9be;
--accent-ui-s-primary: #ff8906;
--accent-ui-s-secondary: #f25f4c;
--accent-ui-s-tertiary: #e53170;
--accent-ui-s-blue: #3da9fc;
--accent-ui-s-purple: #7209b7;
--accent-ui-s-cyan: #00b4d8;
}
/* @media (prefers-color-scheme: dark) {
:root {

View File

@ -11,6 +11,7 @@ import ExportJSON from "@/components/chatBackup/ExportJSON.vue";
import ExportHTML from "@/components/chatBackup/ExportHTML.vue";
import ExportPDF from "@/components/chatBackup/ExportPDF.vue";
import ExportDOCX from "@/components/chatBackup/ExportDOCX.vue";
import ExportJSONMini from './ExportJSONMini.vue';
const props = defineProps({
wxid: {
@ -44,6 +45,10 @@ const setting = {
brief: 'json',
detail: "只包含文本,可用于数据分析,情感分析等方面。",
},
'json-mini': {
brief: 'json-mini',
detail: "只包含文本只有最小化的json格式。支持选择时间注意不要选择太多时间会导致导出数据过大影响AI分析。",
},
'html': {
brief: 'html-测试中',
detail: "主要用于浏览器可视化查看。",
@ -91,6 +96,7 @@ const setting = {
<ExportDEDB v-if="exportType=='dedb'" :wxid="props.wxid"/>
<ExportCSV v-if="exportType=='csv'" :wxid="props.wxid"/>
<ExportJSON v-if="exportType=='json'" :wxid="props.wxid"/>
<ExportJSONMini v-if="exportType=='json-mini'" :wxid="props.wxid"/>
<ExportHTML v-if="exportType=='html'" :wxid="props.wxid"/>
<ExportPDF v-if="exportType=='pdf'" :wxid="props.wxid"/>
<ExportDOCX v-if="exportType=='docx'" :wxid="props.wxid"/>

View File

@ -0,0 +1,65 @@
<script setup lang="ts">
import {defineProps, ref, watch} from "vue";
import http from "@/utils/axios.js";
import DateTimeSelect from "@/components/utils/DateTimeSelect.vue";
const props = defineProps({
wxid: {
type: String,
required: true,
}
});
watch(() => props.wxid, (newVal: string, oldVal: String) => {
console.log(newVal);
});
// props.wxidprops.wxid
const datetime = ref([]);
const Result = ref("");
const requestExport = async () => {
Result.value = "正在处理中...";
try {
Result.value = await http.post('/api/rs/export_json_mini_select_time', {
'wxid': props.wxid,
// 'datetime': datetime.value,
"time":{
"start_time":datetime.value[0],
"end_time":datetime.value[1]
}
});
} catch (error) {
console.error('Error fetching data msg_count:', error);
Result.value = "请求失败\n" + error;
return [];
}
}
//
const handDatetimeChildData = (val: any) => {
datetime.value = val;
}
</script>
<template>
<div>
<!-- <div>-->
<!-- <strong>时间(默认全部)</strong>-->
<!-- <DateTimeSelect @datetime="handDatetimeChildData"/>-->
<!-- </div>-->
<div style="position: relative;">
<el-button type="primary" @click="requestExport()">导出</el-button>
</div>
<el-divider/>
<!-- 结果显示 -->
<el-input type="textarea" :rows="6" readonly placeholder="" v-model="Result"
style="width: 100%;"></el-input>
</div>
</template>
<style scoped>
</style>

View File

@ -23,6 +23,11 @@ const router = createRouter({
name: 'chat',
component: () => import((`@/views/ChatView.vue`))
},
{
path: '/chat2ui',
name: 'chat2ui',
component: () => import((`@/views/Chat2UiView.vue`))
},
{
path: '/contacts',
name: 'contacts',

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-#
# -------------------------------------------------------------------------------
# Name: utils.py
# Name: api_utils.py
# Description:
# Author: xaoyaoo
# Date: 2023/12/25

View File

@ -45,17 +45,17 @@ setup(
license='MIT',
# packages=find_packages(exclude=[]),
packages=['pywxdump', 'pywxdump.ui', 'pywxdump.wx_core', 'pywxdump.wx_core.utils', 'pywxdump.analyzer',
'pywxdump.api', 'pywxdump.api.export', 'pywxdump.db', 'pywxdump.db.utils'],
packages=['pywxdump', 'pywxdump.ui', 'pywxdump.wx_core', 'pywxdump.wx_core.api_utils', 'pywxdump.analyzer',
'pywxdump.api', 'pywxdump.api.export', 'pywxdump.db', 'pywxdump.db.api_utils'],
package_dir={'pywxdump': 'pywxdump',
'pywxdump.wx_core': 'pywxdump/wx_core',
'pywxdump.wx_core.utils': 'pywxdump/wx_core/utils',
'pywxdump.wx_core.api_utils': 'pywxdump/wx_core/api_utils',
'pywxdump.analyzer': 'pywxdump/analyzer',
'pywxdump.ui': 'pywxdump/ui',
'pywxdump.api': 'pywxdump/api',
'pywxdump.api.export': 'pywxdump/api/export',
'pywxdump.db': 'pywxdump/db',
'pywxdump.db.utils': 'pywxdump/db/utils'
'pywxdump.db.api_utils': 'pywxdump/db/api_utils'
},
# include_package_data=True,
package_data={

5
temp.md Normal file
View File

@ -0,0 +1,5 @@
- 导出json可选时间
- 单独导航栏 Ai可视化
- 可以进行可视化的文件列表
- 已经可视化的列表
- 查看

634
test.html

File diff suppressed because it is too large Load Diff

40
test.py

File diff suppressed because one or more lines are too long

View File

@ -153,7 +153,7 @@ if package_path:
hidden_imports = f.read().splitlines()
hidden_imports = [i.replace('-', '_').split("=")[0].split("~")[0] for i in hidden_imports if
i and i not in ["setuptools", "wheel"]] # 去掉setuptools、wheel
hidden_imports += ["pywxdump", "pywxdump.db", "pywxdump.db.__init__.utils"]
hidden_imports += ["pywxdump", "pywxdump.db", "pywxdump.db.__init__.api_utils"]
# 获取 ui 文件夹下的所有文件 用于打包
root_path = os.path.join(package_path, 'pywxdump')

1078
text.html Normal file

File diff suppressed because it is too large Load Diff