Commit 2ac68b34 by chenjinjing

no message

parent 49b94055
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -6,17 +6,21 @@
"dependencies": {
"@alicloud/sms-sdk": "^1.1.6",
"@types/node": "^10.12.18",
"archiver": "^7.0.1",
"compression": "^1.7.4",
"exceljs": "^4.4.0",
"express": "^4.17.1",
"express-async-handler": "^1.1.4",
"express-history-api-fallback": "^2.2.1",
"formidable": "^1.2.1",
"fs-extra": "^11.3.2",
"log4js": "^6.6.1",
"lru-cache": "^4.1.5",
"md5": "^2.2.1",
"moment": "^2.24.0",
"mongoose": "^5.4.0",
"mysql": "^2.18.1",
"node-fetch": "^2.7.0",
"node-xlsx": "^0.16.1",
"nodemailer": "^6.1.1",
"officegen": "^0.6.5",
......
<config>
<port>9098</port>
<sign>xxx90909082fsdahfjosadjfpoiwausjorip2hjklrhn1ioud0u124rx0qwejfokasjfolksaujfoas</sign>
<dbServer>http://192.168.0.71:9096</dbServer>
<dbServer>http://192.168.0.71:40012</dbServer>
<imgUrl>http://192.168.0.71:9098</imgUrl>
<imgFileUrl>http://192.168.0.71:9097</imgFileUrl>
<fileUrl>/yuyi/files/1/</fileUrl>
......
//数据同步
import moment = require("moment");
import { OPERATIONALDATATYPE, TABLENAME } from "../config/enum/dbEnum";
import { selectData, selectManyTableData } from "../data/operationalData";
export async function integration() {
let selectParam:any = {startTime:{"%between%":["2025-07-01", "2025-09-30"]}};
let enterpriseFilesList = ["eId", "enterpriseName", "uscc", "industry", "logonTime", "logonAddress","operatingAddress", "mainBusiness"];
let leaseFileList = ["area", "rent", "building", "roomNumber", "startTime", "endTime" ];
let fuhuaFileList = [ "startTime", "endTime"];
let manyTableInfo:any = {};
manyTableInfo[TABLENAME.企业孵化信息] = {column:fuhuaFileList, where:selectParam };
manyTableInfo[TABLENAME.租赁信息] = {column:leaseFileList, where:{} };
let dbList = await selectManyTableData(OPERATIONALDATATYPE.多表联查, TABLENAME.企业基础信息表, {}, enterpriseFilesList, manyTableInfo);
let dataList = [];
let distinctMap = {};
dbList.forEach(info => {
let { enterprise_fuhuas, enterprise_leases } = info;
let enterprise_fuhua = enterprise_fuhuas[0];
let enterprise_lease = enterprise_leases[0];
let leaseAddress = "";
if (enterprise_lease.building ) leaseAddress += `${enterprise_lease.building}号楼`;
if (enterprise_lease.roomNumber) leaseAddress += `${enterprise_lease.roomNumber}室`;
if (!leaseAddress) leaseAddress = JSON.parse(info.logonAddress)[JSON.parse(info.logonAddress).length - 1]
let newindustry = [];
JSON.parse(info.industry).forEach(key => {
switch(key) {
case 1: newindustry.push(6);break;
case 2: newindustry.push(3);break;
case 3: newindustry.push(8);break;
case 4: newindustry.push(8);break;
case 5: newindustry.push(8);break;
case 6: newindustry.push(8);break;
}
})
let addInfo = {
name:info.enterpriseName,
uscc:info.uscc,
industry:newindustry,
logonTime:new Date(info.logonTime).valueOf(),
// logonTime:info.logonTime,
firstIncubationTime:new Date(enterprise_fuhua.startTime).valueOf(),
isNaturalPersonHolding:true,
logonAddress:JSON.parse(info.logonAddress),
operatingAddress:info.operatingAddress ? JSON.parse(info.operatingAddress) : JSON.parse(info.logonAddress),
leasedArea:enterprise_lease.area ? parseFloat(enterprise_lease.area) : 0,
mainBusiness:info.mainBusiness || "",
jiaSu:2,
leaseAddress,
price:parseFloat(enterprise_lease.rent),
contractStartTime:new Date(enterprise_fuhua.startTime).valueOf(),
contractEndTime:new Date(enterprise_fuhua.endTime).valueOf(),
payStartTime:new Date(enterprise_fuhua.startTime).valueOf(),
payLong:moment(enterprise_fuhua.endTime).diff(moment(enterprise_fuhua.startTime), 'months'),
areaUnit:1
};
dataList.push(addInfo);
if (!distinctMap[info.uscc]) distinctMap[info.uscc] = addInfo;
});
let outList = Object.values(distinctMap);
console.log();
}
......@@ -7,14 +7,117 @@ import moment = require("moment");
import { getQcc } from "../util/request";
import { OPERATIONALDATATYPE, TABLEID, TABLENAME } from "../config/enum/dbEnum";
import { operationalData, selectData } from "../data/operationalData";
import { getMySqlMs, getPinyinInitials, randomId } from "../tools/system";
import { FINANCINGROUNDS, IPRALLTYPE } from "../config/enum/enum";
import { table } from "console";
import { changeEnumValue } from "../util/verificationEnum";
import { getMySqlMs, getPinyinInitials, getPwdMd5, randomId } from "../tools/system";
import { FINANCINGROUNDS } from "../config/enum/enum";
const xlsx = require('node-xlsx');
const path = require('path');
const fs = require('fs');
/**
* 迁移所有企业用户的密码为加密格式
*/
export async function migrateEnterpriseUserPasswords() {
try {
// 获取所有企业用户
const enterpriseUsers = await selectData(
OPERATIONALDATATYPE.查询多个,
TABLENAME.企业用户表,
{},
["uId", "uscc", "pwd", "userName"]
);
if (!enterpriseUsers || enterpriseUsers.length === 0) {
console.log("没有找到需要迁移的企业用户");
return { success: true, migrated: 0 };
}
let migratedCount = 0;
// 遍历所有用户并更新密码
for (const user of enterpriseUsers) {
// 跳过已经加密的密码(假设加密后的密码长度为32位)
if (user.pwd && user.pwd.length === 32) {
console.log(`用户 ${user.uscc} 的密码已经加密,跳过`);
continue;
}
// 使用uId作为盐值进行加密
const encryptedPwd = getPwdMd5(user.uId, user.pwd);
// 更新数据库中的密码
await operationalData(
OPERATIONALDATATYPE.修改,
TABLENAME.企业用户表,
{ pwd: encryptedPwd },
{ uId: user.uId }
);
migratedCount++;
console.log(`已迁移用户 ${user.userName} 的密码`);
}
console.log(`企业用户密码迁移完成,共迁移了 ${migratedCount} 个用户`);
return { success: true, migrated: migratedCount };
} catch (error) {
console.error("企业用户密码迁移过程中发生错误:", error);
return { success: false, error: error.message };
}
}
/**
* 迁移所有企业用户的密码为加密格式
*/
export async function migrateAdminPasswords() {
try {
// 获取所有企业用户
const enterpriseUsers = await selectData(
OPERATIONALDATATYPE.查询多个,
TABLENAME.管理后台用户,
{},
["aId", "loginId", "pwd", "name"]
);
if (!enterpriseUsers || enterpriseUsers.length === 0) {
console.log("没有找到需要迁移的企业用户");
return { success: true, migrated: 0 };
}
let migratedCount = 0;
// 遍历所有用户并更新密码
for (const user of enterpriseUsers) {
// 跳过已经加密的密码(假设加密后的密码长度为32位)
if (user.pwd && user.pwd.length === 32) {
console.log(`用户 ${user.loginId} 的密码已经加密,跳过`);
continue;
}
// 使用aId作为盐值进行加密
const encryptedPwd = getPwdMd5(user.aId, user.pwd);
// 更新数据库中的密码
await operationalData(
OPERATIONALDATATYPE.修改,
TABLENAME.管理后台用户,
{ pwd: encryptedPwd },
{ aId: user.aId }
);
migratedCount++;
console.log(`已迁移用户 ${user.name} 的密码`);
}
console.log(`企业用户密码迁移完成,共迁移了 ${migratedCount} 个用户`);
return { success: true, migrated: migratedCount };
} catch (error) {
console.error("企业用户密码迁移过程中发生错误:", error);
return { success: false, error: error.message };
}
}
/**
* 获取当个excel文件数据
* @param filePath
......
......@@ -46,7 +46,8 @@ import { systemSendMail } from "./mail";
logonAddress:JSON.stringify(["", "", "", param.logonAddress]),
mail:param.mail,//邮箱地址
state:enumConfig.CHANGESTATE.未审核,
register:enumConfig.CHANGESTATE.未审核
register:enumConfig.CHANGESTATE.未审核,
// createTime:getMySqlMs(),
};
await operationalData(OPERATIONALDATATYPE.增加, TABLENAME.企业基础信息表, addEInfo, {});
......@@ -346,6 +347,29 @@ export async function settleInEnterpriseOut(eId:string, descType, desc:string) {
mailStr += `<p>我们期待未来与贵公司的合作机会,衷心祝愿贵公司业务发展顺利!</p>`;
await systemSendMail(resInfo.eId, enumConfig.MAILTYPE.驳回入孵申请, mailStr );
/**设置7天后再次提醒 */
setTimeout( async() => {
try {
//检查企业状态是否仍然是已驳回(未重新提交)
let currentInfo = await selectData(OPERATIONALDATATYPE.查询单个, TABLENAME.企业基础信息表, {eId}, ["register"]);
if (currentInfo && currentInfo.register === enumConfig.CHANGESTATE.已驳回) {
let reminderMailStr = "";
reminderMailStr += "<p>【雨艺孵化器】入孵申请提醒</p>";
reminderMailStr += "<p>尊敬的客户:</p>";
reminderMailStr += "<p>我们注意到您在7天前提交的入孵申请未通过初审,目前尚未收到您的重新提交。</p>";
reminderMailStr += `<p>驳回原因:${descStr}</p>`;
reminderMailStr += "<p>如果您仍有入驻意向,请根据审核意见完善资料后重新提交申请。</p>";
reminderMailStr += "<p>如有任何疑问,欢迎随时联系我们。</p>";
reminderMailStr += "<p>期待您的回复!</p>";
await systemSendMail(resInfo.eId, enumConfig.MAILTYPE.驳回入孵申请, reminderMailStr);
console.log(`7天后入孵申请驳回提醒邮件已发送给企业 ${resInfo.eId}`);
}
} catch (error) {
console.error(`发送7天后入孵申请驳回提醒邮件失败:`, error);
}
}, 7 * 24 * 60 * 60 * 1000); // 7天后的毫秒数
return {isSuccess:true};
}
......@@ -626,7 +650,7 @@ export async function enterpriseRegisterExamineOut(eId:string, descType, desc:st
}
await operationalData( OPERATIONALDATATYPE.增加, TABLENAME.入孵申请审批表, addInfo, {} );
/**发送邮件 */
/**发送邮件 - 首次驳回通知 */
let mailStr = "";
mailStr += "<p>感谢贵公司积极配合入孵流程。经审核,贵公司提交的入孵材料<span style='font-weight: 700;'>暂未通过审核</span>,主要原因如下:</p>";
mailStr += `<ul>`;
......@@ -637,6 +661,29 @@ export async function enterpriseRegisterExamineOut(eId:string, descType, desc:st
mailStr += `<p>感谢理解与配合!</p>`;
await systemSendMail(resInfo.eId, enumConfig.MAILTYPE.驳回入孵材料申请, mailStr );
/**设置7天后再次提醒 */
setTimeout(async () => {
try {
// 检查企业状态是否仍然是已驳回(未重新提交材料)
let currentInfo = await selectData(OPERATIONALDATATYPE.查询单个, TABLENAME.企业基础信息表, {eId}, ["state"]);
if (currentInfo && currentInfo.state === enumConfig.CHANGESTATE.已驳回) {
let reminderMailStr = "";
reminderMailStr += "<p>【雨艺孵化器】入孵材料审核提醒</p>";
reminderMailStr += "<p>尊敬的客户:</p>";
reminderMailStr += "<p>我们注意到您在7天前提交的入孵材料未通过审核,目前尚未收到您重新提交的完善材料。</p>";
reminderMailStr += `<p>驳回原因:${descStr}</p>`;
reminderMailStr += "<p>请您根据审核意见尽快完善相关材料并重新提交,以便我们继续为您处理入孵申请。</p>";
reminderMailStr += "<p>如有任何疑问,欢迎随时联系我们。</p>";
reminderMailStr += "<p>期待您的完善材料!</p>";
await systemSendMail(resInfo.eId, enumConfig.MAILTYPE.驳回入孵材料申请, reminderMailStr);
console.log(`7天后入孵材料驳回提醒邮件已发送给企业 ${resInfo.eId}`);
}
} catch (error) {
console.error(`发送7天后入孵材料驳回提醒邮件失败:`, error);
}
}, 7 * 24 * 60 * 60 * 1000); // 7天后的毫秒数
return {isSuccess:true};
}
......
......@@ -5,7 +5,7 @@
import { OPERATIONALDATATYPE, TABLENAME } from "../config/enum/dbEnum";
import { ERRORENUM } from "../config/enum/errorEnum";
import { operationalData, selectData } from "../data/operationalData";
import { getMySqlMs, getToken, md5PwdStr } from "../tools/system";
import { getMySqlMs, getPwdMd5, getToken, md5PwdStr } from "../tools/system";
import { BizError } from "../util/bizError";
......@@ -16,10 +16,12 @@ export async function adminLogin(loginId:string, pwd:string) {
let filesList = ["name", "aId", "pwd"];
let adminUserInfo = await selectData(OPERATIONALDATATYPE.查询单个, TABLENAME.管理后台用户, {loginId}, filesList);
console.log(adminUserInfo.pwd);
if (!adminUserInfo || !adminUserInfo.aId) {
throw new BizError(ERRORENUM.账号或密码错误);
}
if (adminUserInfo.pwd != pwd) {
const encryptedPwd = getPwdMd5(adminUserInfo.aId, pwd);
if (adminUserInfo.pwd != encryptedPwd) {
throw new BizError(ERRORENUM.账号或密码错误);
}
......@@ -78,3 +80,29 @@ export async function enterpriseLogout(eId:string) {
return {isSuccess:true};
}
/**
* 修改密码
* @param uId
* @param pwd 原密码
* @param newPwd 新密码
* @param confirmPwd 再次确认密码
* @returns
*/
export async function changePassword(uId:string, pwd:string, newPwd:string, confirmPwd:string) {
let adminUserInfo = await selectData(OPERATIONALDATATYPE.查询单个, TABLENAME.管理后台用户, { aId:uId }, ["loginId", "aId", "pwd"]);
if (!adminUserInfo.aId) throw new BizError(ERRORENUM.数据不存在);
/**验证当前密码 */
if (pwd != adminUserInfo.pwd) throw new BizError(ERRORENUM.原密码错误);
if (newPwd != confirmPwd) throw new BizError(ERRORENUM.密码不一致);
if (newPwd.search(/^[A-Za-z0-9]{6,18}$/) < 0) throw new BizError(ERRORENUM.密码只能由618位字符和数字组成);
await operationalData(OPERATIONALDATATYPE.修改, TABLENAME.管理后台用户, {pwd:newPwd}, { aId:uId });
return {isSuccess:true};
}
......@@ -880,18 +880,18 @@ export async function dwFinancingSituatione(eId: string) {
resInfo.forEach(info => {
let {enterpriseName, uscc, enterprise_financings} = info;
let subList = [];
valueList.forEach(subInfo => {
if (subInfo == "enterpriseName") subList.push(enterpriseName);//企业名称
if (subInfo == "uscc") subList.push(uscc); //统一信用代码
if (subInfo == "financingAmount") subList.push(enterprise_financings[0].financingAmount);//融资金额
if (subInfo == "financingRounds") subList.push(changeEnumValue(enumConfig.FINANCINGROUNDS, enterprise_financings[0].financingRounds));//融资轮次
if (subInfo == "investmentDate") subList.push(moment(enterprise_financings[0].investmentDate).format("YYYY-MM-DD"));//获得投资时间
if (subInfo == "investmentInstitutionsName") subList.push(enterprise_financings[0].investmentInstitutionsName);//投资机构名称
});
dataList.push(subList);
enterprise_financings.forEach(finnancing => {
let subList = [];
valueList.forEach(subInfo => {
if (subInfo == "enterpriseName") subList.push(enterpriseName);//企业名称
if (subInfo == "uscc") subList.push(uscc); //统一信用代码
if (subInfo == "financingAmount") subList.push(finnancing.financingAmount);//融资金额
if (subInfo == "financingRounds") subList.push(changeEnumValue(enumConfig.FINANCINGROUNDS, finnancing.financingRounds));//融资轮次
if (subInfo == "investmentDate") subList.push(moment(finnancing.investmentDate).format("YYYY-MM-DD"));//获得投资时间
if (subInfo == "investmentInstitutionsName") subList.push(finnancing.investmentInstitutionsName);//投资机构名称
});
dataList.push(subList);
})
})
return {dataList};
......
......@@ -37,7 +37,7 @@ export enum TABLENAME {
企业服务表 ='enterprise_service',
企业基础信息表 ='enterprise',
政策表 = 'policy',
管理后台用户 = 'adminUser',//以下为新表
管理后台用户 = 'adminuser',//以下为新表
变更信息表 = "info_update",
企业标签表 = "enterprise_label",
股权结构 = "ownership",
......
......@@ -81,7 +81,8 @@ export enum EMIGRATIONTYPE {
毕业迁出 = 1,
毕业未迁出, //新加状态
到期退租,
违约退租
违约退租,
到期未迁出
}
......@@ -176,7 +177,8 @@ export enum FINANCINGROUNDS {
export enum POLICYTYPE {
财政补贴 = 1,
资质申报 = 2,
政策扶持 = 3
政策扶持 = 3,
// 政策宣讲 = 3
}
......@@ -187,7 +189,8 @@ export enum CLIENTPOLICYTYPE {
全部 = 0,
财政补贴 = 1,
资质申报 = 2,
政策扶持 = 3
政策扶持 = 3,
// 政策宣讲 = 3
}
......
......@@ -41,7 +41,10 @@ export enum ERRORENUM {
该用户邮箱为空,
邮件发送失败,
该企业暂未提交入孵材料,
请选择驳回原因
请选择驳回原因,
原密码错误,
密码不一致,
系统错误
}
export enum ERRORCODEENUM {
......
// 使用示例:下载多个图片并打包成ZIP
const { downloadImagesByUrls, downloadImagesWithNames, downloadImagesAndZip } = require('./imgZip');
// 示例1:根据URL数组下载图片并打包
async function example1() {
const imageUrls = [
'https://example.com/image1.jpg',
'https://example.com/image2.png',
'https://example.com/image3.gif'
];
const result = await downloadImagesByUrls(imageUrls, 'my_images');
if (result.isSuccess) {
console.log('ZIP创建成功:', result.zipPath);
} else {
console.error('错误:', result.error);
}
}
// 示例2:指定自定义文件名
async function example2() {
const imageUrls = [
'https://example.com/image1.jpg',
'https://example.com/image2.png'
];
const filenames = [
'封面图.jpg',
'详情图.png'
];
const result = await downloadImagesWithNames(imageUrls, filenames, 'custom_names');
if (result.isSuccess) {
console.log('ZIP创建成功:', result.zipPath);
} else {
console.error('错误:', result.error);
}
}
// 示例3:使用完整的图片信息对象
async function example3() {
const images = [
{ url: 'https://example.com/image1.jpg', filename: '图片1.jpg' },
{ url: 'https://example.com/image2.png' }, // 不指定文件名,会自动生成
{ url: 'https://example.com/image3.gif', filename: '特殊图片.gif' }
];
const result = await downloadImagesAndZip(images, 'mixed_images');
if (result.isSuccess) {
console.log('ZIP创建成功:', result.zipPath);
} else {
console.error('错误:', result.error);
}
}
module.exports = {
example1,
example2,
example3
};
import { integration } from "./biz/dataAsync";
import { migrateAdminPasswords, migrateEnterpriseUserPasswords } from "./biz/dataInit";
import { updateItemQCCData } from "./biz/qccInit";
import { initConfig, systemConfig } from "./config/serverConfig";
import { initApiDataStorage } from "./data/dataInterfaceWithCache";
......@@ -9,10 +11,14 @@ async function lanuch() {
httpServer.createServer(systemConfig.port);
console.log('This indicates that the server is started successfully.');
await initApiDataStorage();
// await initApiDataStorage();
// await migrateEnterpriseUserPasswords();
// await migrateAdminPasswords();
// await integration();
}
lanuch();
\ No newline at end of file
lanuch();
......@@ -14,7 +14,7 @@ export class httpServer {
httpServer.all('*', (req, res, next) => {
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('Access-Control-Allow-Headers', 'Content-Type,request-origin,userid,token');
res.header('Access-Control-Allow-Headers', 'Content-Type,request-origin,userid,token,Authorization');
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
res.header('Access-Control-Allow-Credentials', true);
res.header("X-Powered-By", ' 3.2.1');
......
......@@ -18,6 +18,7 @@ export function setRouter(httpServer) {
//管理员登录登出
httpServer.post('/admin/user/login', asyncHandler(login));
httpServer.post('/admin/user/logout', checkUser, asyncHandler(logout));
httpServer.post('/admin/user/changepwd', checkUser, asyncHandler(changePassword));
// //新入孵企业
httpServer.post('/admin/enterprise/settlein/list', checkUser, asyncHandler(settleIn));
......@@ -737,6 +738,20 @@ async function logout(req, res) {
/**
* 修改密码
* @param req
* @param res
*/
async function changePassword(req, res) {
const UserInfo = req.userInfo;
let {pwd, newPwd, confirmPwd } = req.body
let result = await userBiz.changePassword(UserInfo.uId, pwd, newPwd, confirmPwd );
res.success(result);
}
/**
*
* @param req
* @param res
......
......@@ -6,7 +6,7 @@ import * as asyncHandler from 'express-async-handler';
import { checkInterior } from '../middleware/user';
import { getMySqlMs, getPinyinInitials, randomId } from '../tools/system';
import { OPERATIONALDATATYPE, TABLEID, TABLENAME } from '../config/enum/dbEnum';
import { ANSWERTYPE, CHANGESTATE, DEGREE, FUHUASTATE, IPRALLTYPE, STATE, ZZMM } from '../config/enum/enum';
import { ANSWERTYPE, CHANGESTATE, DEGREE, FOLLOWUPSTATUS, FUHUASTATE, IPRALLTYPE, NEEDCATEGORY, OUTCOME, STATE, ZZMM } from '../config/enum/enum';
import { operationalData, selectData } from '../data/operationalData';
import { initApiDataStorage } from '../data/dataInterfaceWithCache';
import { updateQCCDataTask } from '../biz/qccInit';
......@@ -30,8 +30,108 @@ export function setRouter(httpServer) {
httpServer.post('/admin/data/maintenance/datainit/loginTime', checkInterior, asyncHandler(dataUpdateLoginTime));
httpServer.post('/admin/data/maintenance/datainit/updatetime', checkInterior, asyncHandler(updateTime));
httpServer.post('/admin/data/maintenance/datainit/addenterprise', checkInterior, asyncHandler(addEnterprise));
httpServer.post('/admin/data/maintenance/datainit/addservice', checkInterior, asyncHandler(addService));
}
/**
* 导入企业服务
*/
export async function addService(req, res) {
const FIELD_MAPPING = {
/**企业服务表 */
'需求类别': 'needCategory',
'需求内容': 'needContent',
'申请时间': 'applyTime',
'跟进状态': 'followUpStatus',
'解决时间': 'resolveTime',
'反馈': 'fangKui',
'反馈时间': 'shouLiTime',
'结果': 'outcome',
'备注': 'desc'
};
//2.读取文件
let {sheetMap} = getExcel(path.join(__dirname.substring(0,__dirname.indexOf("out")), "res", '企业服务导入数据.xlsx' ));
let dataList1 = sheetMap['未受理'];
let dataList2 = sheetMap['已受理'];
let dataList3 = sheetMap['已结束'];
for (let i = 1; i < dataList1.length; i++) {
let info = dataList1[i];
let enterpriseName =info[0];
let uscc = info[1];
let enterpriseDbInfo = await selectData(OPERATIONALDATATYPE.查询单个, TABLENAME.企业基础信息表, {enterpriseName, uscc}, ["eId", "uscc", "enterpriseName"]);
if (!enterpriseDbInfo.eId) throw new BizError("未匹配到对应企业");
let excelInfo = {
esId: randomId(TABLEID.企业服务表),
eId:enterpriseDbInfo.eId,
needCategory:NEEDCATEGORY[info[2]],
needContent:info[3],
applyTime:info[4],
followUpStatus:FOLLOWUPSTATUS.未受理,
}
// 新增企业服务
await operationalData(OPERATIONALDATATYPE.增加, TABLENAME.企业服务表, excelInfo, {});
console.log(`新增未受理企业服务信息完成:${enterpriseName}`);
}
for (let i = 1; i < dataList2.length; i++) {
let info = dataList2[i];
let enterpriseName =info[0];
let uscc = info[1];
let enterpriseDbInfo = await selectData(OPERATIONALDATATYPE.查询单个, TABLENAME.企业基础信息表, {enterpriseName, uscc}, ["eId", "uscc", "enterpriseName"]);
if (!enterpriseDbInfo.eId) throw new BizError("未匹配到对应企业");
//{fangKui, followUpStatus:enumConfig.FOLLOWUPSTATUS.受理中, shouLiTime:getMySqlMs()}
let excelInfo = {
esId: randomId(TABLEID.企业服务表),
eId:enterpriseDbInfo.eId,
needCategory:NEEDCATEGORY[info[2]],
needContent:info[3],
applyTime:info[4],
fangKui:info[5],
shouLiTime:getMySqlMs(info[6]),
followUpStatus:FOLLOWUPSTATUS.受理中,
}
// 新增企业服务
await operationalData(OPERATIONALDATATYPE.增加, TABLENAME.企业服务表, excelInfo, {});
console.log(`新增受理中企业服务信息完成:${enterpriseName}`);
}
for (let i = 1; i < dataList3.length; i++) {
let info = dataList3[i];
let enterpriseName =info[0];
let uscc = info[1];
let enterpriseDbInfo = await selectData(OPERATIONALDATATYPE.查询单个, TABLENAME.企业基础信息表, {enterpriseName, uscc}, ["eId", "uscc", "enterpriseName"]);
if (!Object.keys(enterpriseDbInfo).length) throw new BizError(ERRORENUM.企业不存在);
if (!enterpriseDbInfo.eId) throw new BizError(ERRORENUM.企业不存在);
//{outcome, followUpStatus:enumConfig.FOLLOWUPSTATUS.已完成, desc, resolveTime}
let excelInfo = {
esId: randomId(TABLEID.企业服务表),
eId:enterpriseDbInfo.eId,
needCategory:NEEDCATEGORY[info[2]],
needContent:info[3],
applyTime:info[4],
fangKui:info[5],
shouLiTime:getMySqlMs(info[6]),
outcome: OUTCOME[info[7]],
desc:info[8],
followUpStatus:FOLLOWUPSTATUS.已完成,
}
// 新增企业服务
await operationalData(OPERATIONALDATATYPE.增加, TABLENAME.企业服务表, excelInfo, {});
console.log(`新增已完成企业服务信息完成:${enterpriseName}`);
}
res.success({isSuccess:true});
}
......
......@@ -8,6 +8,7 @@ import * as fuhuaRouters from './fuhua';
import * as dbInitRouters from './dbinit';
import * as userRuFuRouters from './userRuFu';
import * as answerRouters from './answer';
import * as zipRouters from './zip';
export function setRouter(httpServer){
/**下拉框等公用 路由 */
publicRouters.setRouter(httpServer);
......@@ -20,4 +21,6 @@ export function setRouter(httpServer){
userRuFuRouters.setRouter(httpServer);
answerRouters.setRouter(httpServer);
zipRouters.setRouter(httpServer);
}
\ No newline at end of file
/**
* zip文件下载
*/
import * as asyncHandler from 'express-async-handler';
import * as zipBiz from '../biz/createZip';
import { checkUser } from '../middleware/user';
import * as fs from 'fs-extra';
export function setRouter(httpServer) {
httpServer.post('/admin/zip/download', checkUser, asyncHandler(downloadZipfiles));
}
/**
* 下载企业文件ZIP包
* @param req
* @param res
*/
async function downloadZipfiles(req, res) {
try {
console.log('收到ZIP下载请求,参数:', req.body);
let { eId } = req.body;
if (!eId) {
return res.status(400).json({ error: '缺少必要参数eId' });
}
let result = await zipBiz.downloadEnterpriseFilesZip(eId);
console.log('ZIP文件创建成功:', result.fileName);
// 设置响应头
res.setHeader('Content-Type', 'application/zip');
res.setHeader('Content-Disposition', `attachment; filename=${encodeURIComponent(result.fileName)}`);
res.setHeader('Access-Control-Expose-Headers', 'Content-Disposition');
// 检查文件是否存在
if (!await fs.pathExists(result.filePath)) {
throw new Error('ZIP文件未找到: ' + result.filePath);
}
// 获取文件状态
const stats = await fs.stat(result.filePath);
res.setHeader('Content-Length', stats.size);
console.log(`准备发送文件: ${result.fileName}, 大小: ${stats.size} bytes`);
// 发送文件
res.sendFile(result.filePath, (err) => {
if (err) {
console.error('发送文件失败:', err);
if (!res.headersSent) {
res.status(500).json({ error: '文件发送失败', message: err.message });
}
} else {
console.log('文件发送成功');
}
// 可选:发送完成后删除临时文件
setTimeout(async () => {
try {
if (await fs.pathExists(result.filePath)) {
await fs.remove(result.filePath);
console.log('临时文件已清理:', result.filePath);
}
} catch (cleanupError) {
console.error('清理临时文件失败:', cleanupError);
}
}, 1000);
});
} catch (error) {
console.error('下载文件失败:', error);
if (!res.headersSent) {
res.status(500).json({
error: '下载失败',
message: error.message,
stack: process.env.NODE_ENV === 'development' ? error.stack : undefined
});
}
}
}
{
"compilerOptions": {
"module": "commonjs",
"target": "es2017",
"target": "ES2020",
"sourceMap": true,
"rootDir":"./src",
"outDir":"./out"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment