Merge branch 'main' of http://10.10.14.176:3000/huanghai/dsProject
commit
e7ac177ad1
@ -1,13 +1,132 @@
|
||||
# routes/LoginController.py
|
||||
# routes/DocumentController.py
|
||||
import os
|
||||
|
||||
from fastapi import APIRouter, Request, Response, Depends
|
||||
from fastapi import APIRouter, Request, Response, Depends, UploadFile, File
|
||||
|
||||
from auth.dependencies import get_current_user
|
||||
from utils.PageUtil import *
|
||||
from utils.ParseRequest import *
|
||||
|
||||
# 创建一个路由实例,需要依赖get_current_user,登录后才能访问
|
||||
router = APIRouter(dependencies=[Depends(get_current_user)])
|
||||
|
||||
# 创建上传文件的目录
|
||||
UPLOAD_DIR = "upload_file"
|
||||
if not os.path.exists(UPLOAD_DIR):
|
||||
os.makedirs(UPLOAD_DIR)
|
||||
|
||||
@router.get("/")
|
||||
async def test(request: Request, response: Response):
|
||||
return {"success": True, "message": "成功!"}
|
||||
# 合法文件扩展名
|
||||
supported_suffix_types = ['doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx']
|
||||
|
||||
# 【Document-1】文档管理列表
|
||||
@router.get("/list")
|
||||
async def list(request: Request):
|
||||
# 获取参数
|
||||
person_id = await get_request_str_param(request, "person_id", True, True)
|
||||
stage_id = await get_request_num_param(request, "stage_id", False, True, -1)
|
||||
subject_id = await get_request_num_param(request, "subject_id", False, True, -1)
|
||||
document_suffix = await get_request_str_param(request, "document_suffix", False, True)
|
||||
document_name = await get_request_str_param(request, "document_name", False, True)
|
||||
page_number = await get_request_num_param(request, "page_number", False, True, 1)
|
||||
page_size = await get_request_num_param(request, "page_size", False, True, 10)
|
||||
|
||||
print(person_id, stage_id, subject_id, document_suffix, document_name, page_number, page_size)
|
||||
|
||||
# 拼接查询SQL语句
|
||||
|
||||
select_document_sql: str = " SELECT * FROM t_ai_teaching_model_document WHERE is_deleted = 0 and person_id = '" + person_id + "'"
|
||||
if stage_id != -1:
|
||||
select_document_sql += " AND stage_id = " + str(stage_id)
|
||||
if subject_id != -1:
|
||||
select_document_sql += " AND subject_id = " + str(subject_id)
|
||||
if document_suffix != "":
|
||||
select_document_sql += " AND document_suffix = '" + document_suffix + "'"
|
||||
if document_name != "":
|
||||
select_document_sql += " AND document_name = '" + document_name + "'"
|
||||
select_document_sql += " ORDER BY create_time DESC "
|
||||
|
||||
# 查询文档列表
|
||||
page = await get_page_data_by_sql(select_document_sql, page_number, page_size)
|
||||
for item in page["list"]:
|
||||
theme_info = await find_by_id("t_ai_teaching_model_theme", "id", item["theme_id"])
|
||||
item["theme_info"] = theme_info
|
||||
|
||||
return {"success": True, "message": "查询成功!", "data": page}
|
||||
|
||||
|
||||
# 【Document-2】保存文档管理
|
||||
@router.post("/save")
|
||||
async def save(request: Request, file: UploadFile = File(...)):
|
||||
# 获取参数
|
||||
id = await get_request_num_param(request, "id", False, True, 0)
|
||||
stage_id = await get_request_num_param(request, "stage_id", False, True, -1)
|
||||
subject_id = await get_request_num_param(request, "subject_id", False, True, -1)
|
||||
theme_id = await get_request_num_param(request, "theme_id", True, True, None)
|
||||
person_id = await get_request_str_param(request, "person_id", True, True)
|
||||
bureau_id = await get_request_str_param(request, "bureau_id", True, True)
|
||||
# 先获取theme主题信息
|
||||
theme_object = await find_by_id("t_ai_teaching_model_theme", "id", theme_id)
|
||||
if theme_object is None:
|
||||
return {"success": False, "message": "主题不存在!"}
|
||||
# 获取文件名
|
||||
document_name = file.filename
|
||||
# 检查文件名在该主题下是否重复
|
||||
select_theme_document_sql: str = "SELECT * FROM t_ai_teaching_model_document WHERE is_deleted = 0 and document_name = '" + document_name + "'"
|
||||
if id != 0:
|
||||
select_theme_document_sql += " AND id <> " + id
|
||||
theme_document = await find_by_sql(select_theme_document_sql, ())
|
||||
if theme_document is not None:
|
||||
return {"success": False, "message": "该主题下文档名称重复!"}
|
||||
# 获取文件扩展名
|
||||
document_suffix = file.filename.split(".")[-1]
|
||||
# 检查文件扩展名
|
||||
if document_suffix not in supported_suffix_types:
|
||||
return {"success": False, "message": "不支持的文件类型!"}
|
||||
# 构造文件保存路径
|
||||
document_dir = UPLOAD_DIR + os.sep + str(theme_object["short_name"]) + "_" + str(theme_object["id"]) + os.sep
|
||||
if not os.path.exists(document_dir):
|
||||
os.makedirs(document_dir)
|
||||
document_path = os.path.join(document_dir, file.filename)
|
||||
# 保存文件
|
||||
try:
|
||||
with open(document_path, "wb") as buffer:
|
||||
buffer.write(await file.read())
|
||||
except Exception as e:
|
||||
return {"success": False, "message": f"文件保存失败!{e}"}
|
||||
|
||||
# 构造保存文档SQL语句
|
||||
param = {"stage_id": stage_id, "subject_id": subject_id, "document_name": document_name, "theme_id": theme_id, "document_path": document_path, "document_suffix": document_suffix, "person_id": person_id, "bureau_id": bureau_id}
|
||||
|
||||
# 保存数据
|
||||
if id == 0:
|
||||
param["train_flag"] = 0
|
||||
# 插入数据
|
||||
id = await insert("t_ai_teaching_model_document", param, False)
|
||||
return {"success": True, "message": "保存成功!", "data": {"insert_id" : id}}
|
||||
else:
|
||||
# 更新数据
|
||||
await update("t_ai_teaching_model_document", param, "id", id)
|
||||
return {"success": True, "message": "更新成功!", "data": {"update_id" : id}}
|
||||
|
||||
# 【Document-3】获取文档信息
|
||||
@router.get("/get")
|
||||
async def get(request: Request):
|
||||
# 获取参数
|
||||
id = await get_request_num_param(request, "id", True, True, None)
|
||||
# 查询数据
|
||||
document_object = await find_by_id("t_ai_teaching_model_document", "id", id)
|
||||
if document_object is None:
|
||||
return {"success": False, "message": "未查询到该文档信息!"}
|
||||
theme_info = await find_by_id("t_ai_teaching_model_theme", "id", document_object["theme_id"])
|
||||
document_object["theme_info"] = theme_info
|
||||
return {"success": True, "message": "查询成功!", "data": {"document": document_object}}
|
||||
|
||||
|
||||
@router.post("/delete")
|
||||
async def delete(request: Request):
|
||||
# 获取参数
|
||||
id = await get_request_num_param(request, "id", True, True, None)
|
||||
result = await delete_by_id("t_ai_teaching_model_document", "id", id)
|
||||
if not result:
|
||||
return {"success": False, "message": "删除失败!"}
|
||||
return {"success": True, "message": "删除成功!"}
|
@ -0,0 +1,50 @@
|
||||
# routes/UserController.py
|
||||
import re
|
||||
|
||||
from fastapi import APIRouter, Request, Response, Depends
|
||||
from auth.dependencies import *
|
||||
from utils.CommonUtil import md5_encrypt
|
||||
from utils.Database import *
|
||||
from utils.ParseRequest import *
|
||||
|
||||
# 创建一个路由实例,需要依赖get_current_user,登录后才能访问
|
||||
router = APIRouter(dependencies=[Depends(get_current_user)])
|
||||
|
||||
# 【Base-User-1】维护用户手机号
|
||||
@router.post("/modifyTelephone")
|
||||
async def modify_telephone(request: Request):
|
||||
person_id = await get_request_str_param(request, "person_id", True, True)
|
||||
telephone = await get_request_str_param(request, "telephone", True, True)
|
||||
# 校验手机号码格式
|
||||
if not re.match(r"^1[3-9]\d{9}$", telephone):
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="手机号码格式错误")
|
||||
# 校验手机号码是否已被注册
|
||||
select_telephone_sql: str = "select * from t_sys_loginperson where b_use = 1 and telephone = '" + telephone + "' and person_id <> '" + person_id + "'"
|
||||
userlist = await find_by_sql(select_telephone_sql, ())
|
||||
if userlist is not None:
|
||||
return {"success": False, "message": "手机号码已被注册"}
|
||||
else:
|
||||
update_telephone_sql: str = "update t_sys_loginperson set telephone = '" + telephone + "' where person_id = '" + person_id + "'"
|
||||
await execute_sql(update_telephone_sql)
|
||||
return {"success": True, "message": "修改成功"}
|
||||
|
||||
|
||||
# 【Base-User-2】维护用户密码
|
||||
@router.post("/modifyPassword")
|
||||
async def modify_password(request: Request):
|
||||
person_id = await get_request_str_param(request, "person_id", True, True)
|
||||
old_password = await get_request_str_param(request, "old_password", True, True)
|
||||
password = await get_request_str_param(request, "password", True, True)
|
||||
# 校验旧密码是否正确
|
||||
select_password_sql: str = "select pwdmd5 from t_sys_loginperson where person_id = '" + person_id + "' and b_use = 1"
|
||||
userlist = await find_by_sql(select_password_sql, ())
|
||||
if len(userlist) == 0:
|
||||
return {"success": False, "message": "用户不存在"}
|
||||
else:
|
||||
if userlist[0]["pwdmd5"] != md5_encrypt(old_password):
|
||||
return {"success": False, "message": "旧密码错误"}
|
||||
else:
|
||||
update_password_sql: str = "update t_sys_loginperson set original_pwd = '" + password + "',pwdmd5 = '" + md5_encrypt(password) + "' where person_id = '" + person_id + "'"
|
||||
await execute_sql(update_password_sql)
|
||||
return {"success": True, "message": "修改成功"}
|
||||
|
@ -0,0 +1,48 @@
|
||||
import math
|
||||
from utils.Database import *
|
||||
|
||||
|
||||
# 查询数据条数
|
||||
async def get_total_data_count(total_data_sql):
|
||||
total_data_count = 0
|
||||
total_data_count_sql = "select count(*) as num from (" + total_data_sql + ") as temp_table"
|
||||
result = await find_by_sql(total_data_count_sql,())
|
||||
row = result[0] if result else None
|
||||
if row:
|
||||
total_data_count = row.get("num")
|
||||
return total_data_count
|
||||
|
||||
|
||||
def get_page_by_total_row(total_data_count, page_number, page_size):
|
||||
total_page = (page_size != 0) and math.floor((total_data_count + page_size - 1) / page_size) or 0
|
||||
if page_number <= 0:
|
||||
page_number = 1
|
||||
if 0 < total_page < page_number:
|
||||
page_number = total_page
|
||||
offset = page_size * page_number - page_size
|
||||
limit = page_size
|
||||
return total_data_count, total_page, offset, limit
|
||||
|
||||
|
||||
async def get_page_data_by_sql(total_data_sql: str, page_number: int, page_size: int):
|
||||
total_row: int = 0
|
||||
total_page: int = 0
|
||||
total_data_sql = total_data_sql.replace(";", "")
|
||||
total_data_sql = total_data_sql.replace(" FROM ", " from ")
|
||||
|
||||
# 查询总数
|
||||
total_data_count = await get_total_data_count(total_data_sql)
|
||||
if total_data_count == 0:
|
||||
return {"page_number": page_number, "page_size": page_size, "total_row": 0, "total_page": 0, "list": []}
|
||||
else:
|
||||
total_row, total_page, offset, limit = get_page_by_total_row(total_data_count, page_number, page_size)
|
||||
|
||||
# 构造执行分页查询的sql语句
|
||||
page_data_sql = total_data_sql + " LIMIT %d offset %d " % (limit, offset)
|
||||
print(page_data_sql)
|
||||
# 执行分页查询
|
||||
page_data = await find_by_sql(page_data_sql, ())
|
||||
if page_data:
|
||||
return {"page_number": page_number, "page_size": page_size, "total_row": total_row, "total_page": total_page, "list": page_data}
|
||||
else:
|
||||
return {"page_number": page_number, "page_size": page_size, "total_row": 0, "total_page": 0, "list": []}
|
Binary file not shown.
File diff suppressed because one or more lines are too long
@ -0,0 +1,47 @@
|
||||
from selenium import webdriver
|
||||
from selenium.webdriver.chrome.options import Options
|
||||
from selenium.webdriver.chrome.service import Service as ChromeService
|
||||
from selenium.webdriver.common.by import By
|
||||
|
||||
def init_wechat_browser():
|
||||
"""初始化微信爬虫浏览器实例"""
|
||||
options = Options()
|
||||
options.add_argument('-headless')
|
||||
service = ChromeService(executable_path=r"C:\Windows\System32\chromedriver.exe")
|
||||
return webdriver.Chrome(service=service, options=options)
|
||||
|
||||
|
||||
def get_article_content(url):
|
||||
"""
|
||||
获取微信公众号文章内容
|
||||
:param url: 文章URL
|
||||
:return: 文章内容文本
|
||||
"""
|
||||
options = Options()
|
||||
options.add_argument('-headless')
|
||||
service = ChromeService(executable_path=r"C:\Windows\System32\chromedriver.exe")
|
||||
driver = webdriver.Chrome(service=service, options=options)
|
||||
|
||||
try:
|
||||
driver.get(url)
|
||||
html_content = driver.find_element(By.CLASS_NAME, "rich_media").text
|
||||
|
||||
# 处理内容,提取空行后的文本
|
||||
lines = html_content.split('\n')
|
||||
content_after_empty_line = ""
|
||||
found_empty_line = False
|
||||
|
||||
for line in lines:
|
||||
if not found_empty_line and line.strip() == "":
|
||||
found_empty_line = True
|
||||
continue
|
||||
|
||||
if found_empty_line:
|
||||
content_after_empty_line += line + "\n"
|
||||
|
||||
if not found_empty_line:
|
||||
content_after_empty_line = html_content
|
||||
|
||||
return content_after_empty_line.replace("\n\n", "\n")
|
||||
finally:
|
||||
driver.quit()
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,17 @@
|
||||
{
|
||||
"_clsk": "2gtve8|1752546228205|1|1|mp.weixin.qq.com/weheat-agent/payload/record",
|
||||
"xid": "16332bed01be1055e236ad45b33af8df",
|
||||
"data_bizuin": "3514353238",
|
||||
"slave_user": "gh_4f88a4e194da",
|
||||
"slave_sid": "QzBRX1FWTXNMaEdJYnc4ODBaM3FJU3RRbjVJNFE2N2IzMXFyVGlRQ0V5YklvNGFOc3NBWHdjV2J5OVg5U0JBVXdfdGhSU3lObXRheG1TdFUyXzVFcTFYS3E1NTh2aTlnSlBOOUluMUljUnBkYktjeUJDM216WVJNYzJKQkx2eW9Ib1duUk1yWXI3RndTa2dK",
|
||||
"rand_info": "CAESIFwUSYus3XR5tFa1+b5ytJeuGAQS02d07zNBJNfi+Ftk",
|
||||
"data_ticket": "9gQ088/vC7+jqxfFxBKS2aRx/JjmzJt+8HyuDLJtQBgpVej1hfSG1A0FQKWBbHQh",
|
||||
"bizuin": "3514353238",
|
||||
"mm_lang": "zh_CN",
|
||||
"slave_bizuin": "3514353238",
|
||||
"uuid": "8c5dc8e06af66d00a4b8e8596c8662eb",
|
||||
"ua_id": "y1HZNMSzYCWuaUJDAAAAAApPVJ0a_arX_A5zqoUh6P8=",
|
||||
"wxuin": "52546211515015",
|
||||
"_clck": "msq32d|1|fxm|0",
|
||||
"expiry": 1787106233
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>长春市教育信息资讯库维护</title>
|
||||
<link rel="stylesheet" href="layui/css/layui.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="layui-container">
|
||||
<div class="layui-row">
|
||||
<div class="layui-col-md12">
|
||||
<h2 class="layui-header">长春市教育信息资讯库维护</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-tab layui-tab-brief">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this">文章列表</li>
|
||||
<li>信息来源</li>
|
||||
</ul>
|
||||
<div class="layui-tab-content">
|
||||
<div class="layui-tab-item layui-show">
|
||||
<table id="articleTable" lay-filter="articleTable"></table>
|
||||
</div>
|
||||
<div class="layui-tab-item">
|
||||
<table id="sourceTable" lay-filter="sourceTable"></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="layui/layui.js"></script>
|
||||
<script>
|
||||
layui.use(['table', 'element'], function () {
|
||||
var table = layui.table;
|
||||
var element = layui.element;
|
||||
|
||||
// 信息来源表格
|
||||
table.render({
|
||||
elem: '#sourceTable',
|
||||
url: '/api/sources',
|
||||
page: true,
|
||||
parseData: function (res) { // 新增parseData函数处理返回数据
|
||||
return {
|
||||
"code": res.code,
|
||||
"msg": res.msg,
|
||||
"count": res.data.total,
|
||||
"data": res.data.list
|
||||
};
|
||||
},
|
||||
cols: [[
|
||||
{field: 'id', title: '序号', width: 80},
|
||||
{field: 'name', title: '账号名称'},
|
||||
{field: 'type', title: '来源类型'},
|
||||
{field: 'update_time', title: '更新时间'}
|
||||
]]
|
||||
});
|
||||
|
||||
// 文章列表表格
|
||||
table.render({
|
||||
elem: '#articleTable',
|
||||
url: '/api/articles',
|
||||
page: true,
|
||||
parseData: function (res) {
|
||||
return {
|
||||
"code": res.code,
|
||||
"msg": res.msg,
|
||||
"count": res.data.total,
|
||||
"data": res.data.list
|
||||
};
|
||||
},
|
||||
cols: [[
|
||||
{field: 'id', title: '序号', width: 80},
|
||||
{field: 'title', title: '标题', templet: function(d){
|
||||
return '<a href="' + d.url + '" target="_blank" style="color: #1E88E5; text-decoration: underline; cursor: pointer;">' + d.title + '</a>';
|
||||
}},
|
||||
{field: 'source', title: '来源', width: 150},
|
||||
{field: 'publish_date', title: '发布日期', width: 120},
|
||||
{field: 'collect_time', title: '采集时间', width: 150}
|
||||
]]
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in new issue