2025-05-27 15:46:31 +08:00

409 lines
12 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 固定中文帐号
const FIXED_ACCOUNT = "广东具身风暴";
// 生成固定密钥(基于中文账户名)
function generateFixedKey() {
// 对中文账号生成 MD5 值
const fullMD5 = CryptoJS.MD5(FIXED_ACCOUNT).toString(CryptoJS.enc.Hex); // 计算 MD5 值
return fullMD5.substring(8, 24).toUpperCase(); // 提取中间16位并转换为大写
}
// AES 加密
function encryptAES(plainText) {
const key = generateFixedKey(); // 获取固定密钥
const keyWordArray = CryptoJS.enc.Utf8.parse(key); // 转换为 WordArray 类型
// 使用 AES 加密ECB 模式PKCS7 填充
const encrypted = CryptoJS.AES.encrypt(plainText, keyWordArray, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7,
});
// 返回 Base64 格式加密结果
return encrypted.toString();
}
// AES 解密
function decryptAES(cipherText) {
const key = generateFixedKey(); // 获取固定密钥
const keyWordArray = CryptoJS.enc.Utf8.parse(key);
// 使用 AES 解密
const decrypted = CryptoJS.AES.decrypt(cipherText, keyWordArray, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7,
});
// 将解密后的数据转换为字符串
return decrypted.toString(CryptoJS.enc.Utf8);
}
// 加密
// const encryptedText = encryptAES(plaintext);
// // console.log("加密后的文本:", encryptedText);
// 登录请求
async function loginRequest() {
const loginData = {
username: "广东具身风暴",
password: "123456",
};
try {
const response = await fetch("http://qa.gddayo.com:5011/user/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
Username: loginData.username,
Password: loginData.password,
}),
});
const data = await response.json();
if (data.Code == 1) {
const decryptedText = decryptAES(data.Data);
const loginData = JSON.parse(decryptedText);
// 存储 token
localStorage.setItem("token", loginData.ApiToken);
return loginData.ApiToken; // 返回新的 token
} else {
throw new Error("登录失败:" + data.Message);
}
} catch (error) {
console.error("登录请求失败:", error);
throw error;
}
}
// 获取 token自动处理过期逻辑
async function getToken() {
let token = localStorage.getItem("token");
if (!token) {
console.log("Token不存在正在登录...");
token = await loginRequest(); // 登录并获取新的 token
}
return token;
}
// 通用请求方法
async function makeRequest(url, options, retryCount = 3) {
try {
const token = await getToken(); // 确保有可用 token
options.headers = options.headers || {};
options.headers["ApiToken"] = token; // 添加 token 到请求头
const response = await fetch(url, options);
const data = await response.json();
if (data.Message === "抱歉,没有登录或登录已超时" && retryCount > 0) {
console.warn("Token过期正在重新登录...");
await loginRequest(); // 重新登录
return makeRequest(url, options, retryCount - 1); // 重新发起请求
}
return data; // 返回成功数据
} catch (error) {
console.error("请求失败:", error);
throw error;
}
}
// 获取用户列表
async function fetchUserList() {
const url = "http://qa.gddayo.com:5011/customer/SearchbyuserPage";
const requestData = encryptAES(
JSON.stringify({
PageSize: 100,
PageIndex: 1,
})
);
const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ Data: requestData }),
};
try {
const data = await makeRequest(url, options);
const returnData = JSON.parse(decryptAES(data.Data));
return returnData.Customers;
} catch (error) {
console.error("获取用户分页失败:", error);
showPhoneNumberError("获取用户列表失败,请稍后再试");
return [];
}
}
// 显示用户信息
function displayUserInfo(user) {
const userListDiv = document.getElementById("user-list");
const userDiv = document.createElement("div");
let genderImg =
user.Gender === 1 ? "static/images/ir_report/man.png" : "static/images/ir_report/female.png";
userDiv.innerHTML = `
<div class="user-item" id="user-${user.CustomerId}">
<div class="user-info">
<div class="user-name">${user.RealName}</div>
<img class="user-gender" src="${genderImg}" />
</div>
<div class="report-list" id="report-list-${user.CustomerId}" style="display:none;"></div>
</div>
`;
// 为用户信息添加点击事件
userDiv.querySelector(".user-info").addEventListener("click", () => {
const customerId = user.CustomerId;
const reportListDiv = document.getElementById(`report-list-${customerId}`);
if (reportListDiv.style.display === "none") {
getReportData(customerId);
reportListDiv.style.display = "block";
} else {
reportListDiv.style.display = "none";
}
});
userListDiv.appendChild(userDiv);
}
// 搜索并显示匹配的用户
async function searchAndDisplayUser(inputValue) {
const users = await fetchUserList();
// 清空现有的用户列表
const userListDiv = document.getElementById("user-list");
userListDiv.innerHTML = "";
// 遍历所有用户,查找与输入手机号匹配的用户
const matchedUsers = users.filter((user) => user.Mobile === inputValue);
inputModal.style.display = "none";
if (matchedUsers.length > 0) {
matchedUsers.forEach((user) => displayUserInfo(user));
} else {
showPhoneNumberError("未找到匹配的用户");
}
}
// // 页面初始化时调用
// async function initializePage() {
// await getUserPage();
// }
// initializePage();
// 获取报告数据
async function getReportData(ClientId) {
const url = "http://qa.gddayo.com:5011/customer/SearchreportPageV2";
const requestData = encryptAES(
JSON.stringify({
ClientId,
})
);
const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ Data: requestData }),
};
try {
const data = await makeRequest(url, options); // 调用通用请求方法
const returnData = JSON.parse(decryptAES(data.Data));
const reportListDiv = document.getElementById(`report-list-${ClientId}`);
reportListDiv.innerHTML = ""; // 清空报告列表
if (returnData.Reports.length === 0) {
reportListDiv.innerHTML = "<div class='no-report'>暂无报告</div>";
} else {
returnData.Reports.forEach((ele) => {
const reportDiv = document.createElement("div");
const fileUrl = JSON.parse(ele.Url)[0];
reportDiv.innerHTML = `
<div class="report-item">
<div class="report-name">${setFileName(fileUrl)}</div>
</div>
`;
// 添加点击事件,在 report-window 中显示 PDF
reportDiv
.querySelector(".report-item")
.addEventListener("click", () => {
// displayPDF(fileUrl); // 显示 PDF
extractPdfContent(fileUrl); // 解析 PDF
});
reportListDiv.appendChild(reportDiv);
});
}
} catch (error) {
console.error("获取报告失败:", error);
}
}
// 前端发送在线PDF链接并获取解析结果
async function extractPdfContent(pdfUrl) {
const response = await fetch("/extract_pdf", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ pdf_url: pdfUrl }),
});
const data = await response.json();
if (data.error) {
console.error("Error:", data.error);
return;
}
// 获取解析的文本内容
console.log("Text:", data.text);
// 创建请求体
const textData = {
input: data.text,
};
const reportWindow = document.getElementById("report-window");
reportWindow.style.display = "block";
const reportBox = document.getElementById("report-box");
reportBox.innerHTML = "ai辨识中...";
const closeBtn = document.getElementById("close-report-btn");
closeBtn.style.display = "none";
fetch("/generate_health_report", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(textData),
})
.then(async (response) => {
const mdName = `generated_content`;
await loadMarkdown(mdName, "report-box");
closeBtn.style.display = "block";
const imgBox = document.getElementById("img-box");
// 获取解析的图片并显示;
const len = data.images.length;
pushImg(data.images[len - 2], imgBox);
pushImg(data.images[len - 1], imgBox);
})
.catch((error) => {
console.error("Error:", error);
alert(
`Error: ${error.response ? error.response.data.error : error.message}`
);
});
}
function pushImg(imgUrl, imgBox) {
const img = document.createElement("img");
img.src = imgUrl; // 图片URL
imgBox.appendChild(img);
}
// 提取文件名
function setFileName(url) {
// 使用正则表达式匹配文件名部分
const pattern = /([^/]+)\.pdf$/; // 匹配最后一个 "/" 后的内容,直到 ".pdf"
const match = url.match(pattern);
return match ? match[1] : "未知文件"; // 如果匹配成功返回文件名,否则返回默认值
}
// 显示 PDF 文件
function displayPDF(pdfUrl) {
const reportWindow = document.getElementById("report-window");
reportWindow.style.display = "block";
const reportWindowContainer = document.getElementById(
"report-window-container"
);
const loadingTask = pdfjsLib.getDocument(pdfUrl);
loadingTask.promise.then((pdf) => {
for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {
pdf.getPage(pageNum).then((page) => {
const containerWidth = reportWindowContainer.clientWidth;
const scale = containerWidth / page.getViewport({ scale: 1 }).width;
const viewport = page.getViewport({ scale });
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
canvas.width = viewport.width;
canvas.height = viewport.height;
reportWindowContainer.appendChild(canvas);
const renderContext = {
canvasContext: context,
viewport: viewport,
};
page.render(renderContext);
});
}
});
}
function closeReport() {
try {
const reportWindow = document.getElementById("report-window");
reportWindow.style.display = "none";
// const reportWindowContainer = document.getElementById(
// "report-window-container"
// );
// reportWindowContainer.innerHTML = "";
const reportBox = document.getElementById("report-box");
reportBox.innerHTML = "";
const imgBox = document.getElementById("img-box");
imgBox.innerHTML = "";
} catch (error) {
console.error("关闭报告失败:", error);
}
}
// 校验手机号码格式
function validatePhoneNumber(inputValue) {
const phoneRegex = /^1[3-9]\d{9}$/;
return phoneRegex.test(inputValue);
}
// 显示错误提示
function showPhoneNumberError(message) {
showPopup(message, { confirm: true, cancel: false });
}
const inputModal = document.getElementById("input-modal");
const inputConfirmBtn = document.getElementById("input-confirm-btn");
const inputCancelBtn = document.getElementById("input-cancel-btn");
inputConfirmBtn.addEventListener("click", () => {
const inputValue = document.getElementById("phone-input").value;
if (!validatePhoneNumber(inputValue)) {
showPhoneNumberError("请输入正确的手机号码");
return;
} else {
searchAndDisplayUser(inputValue);
}
});
inputCancelBtn.addEventListener("click", () => {
inputModal.style.display = "none";
});
function showInputModal() {
inputModal.style.display = "flex";
}