409 lines
12 KiB
JavaScript
409 lines
12 KiB
JavaScript
// 固定中文帐号
|
||
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";
|
||
}
|