Commit c8ff749a by chenjinjing

bug修复

parent b8e90c2a
No preview for this file type
No preview for this file type
No preview for this file type
<config>
<port>7071</port>
<excelModelUrl>http://192.168.0.71:7071/template/</excelModelUrl>
<excelModelUrl>http://127.0.0.1:7071/template/</excelModelUrl>
<!-- <excelModelUrl>http://101.89.111.202:7071/template/</excelModelUrl> -->
<mongodb>
<path>192.168.0.105</path>
<path>192.168.0.71</path>
<!-- <path>127.0.0.1</path> -->
<port>27017</port>
<w>1</w>
<!-- <dataBase>baseDB</dataBase> -->
......
......@@ -31,24 +31,44 @@ export async function activityList(title:string, startTime:number, endTime:numbe
selectParam.title = {"$regex":`${title}`};
}
if (startTime && endTime) {
selectParam.startTime = { "$gte": startTime };
selectParam.endTime = { "$lte": endTime };
selectParam.startTime = { "$lte": endTime };
selectParam.endTime = { "$gte": startTime };
}
if (target) {
verificationEnumTools.eccEnumValue('管理后台获取园区活动列表', 'target', configEnum.ACTIVITYTARGET, target);
selectParam.target = {"$in":target};
}
// if (state) {
// verificationEnumTools.eccEnumValue('管理后台获取园区活动列表', 'state', configEnum.ACTIVITYSTATE, state);
// selectParam.state = state;
// }
/**需要用到的查询数据 */
let activityDbList = await activityData.findActivityListToPage(selectParam, (page - 1) * 10);
let allActivityDbList = await activityData.findActivityListByParam(selectParam);
// 如果有状态筛选,过滤数据
let filteredActivityDbList = activityDbList;
if (state) {
verificationEnumTools.eccEnumValue('管理后台获取园区活动列表', 'state', configEnum.ACTIVITYSTATE, state);
selectParam.state = state;
filteredActivityDbList = activityDbList.filter(info => {
const activityState = calculateActivityState(info.startTime, info.endTime);
return activityState === state;
});
}
// 重新计算总数
let count = allActivityDbList.length;
if (state) {
count = allActivityDbList.filter(info => {
const activityState = calculateActivityState(info.startTime, info.endTime);
return activityState === state;
}).length;
}
/**需要用到的查询数据 */
let activityDbList = await activityData.findActivityListToPage(selectParam, (page - 1) * 10);
let count = await activityData.findActivityCount(selectParam);//符合查询条件的数据总数
/**组合返回结果 */
let dataList = [];
activityDbList.forEach( info => {
filteredActivityDbList.forEach( info => {
/**截取返回数据 */
let changeData:any = extractData(splitResultConfig.activityListConfig, info, true);
......@@ -58,7 +78,10 @@ export async function activityList(title:string, startTime:number, endTime:numbe
target.push(verificationEnumTools.changeEnumValue(configEnum.ACTIVITYTARGET, info))
})
changeData.target = target;
changeData.state = verificationEnumTools.changeEnumValue(configEnum.ACTIVITYSTATE, changeData.state);
// 计算活动状态
let stateType = calculateActivityState(info.startTime, info.endTime)
changeData.state = verificationEnumTools.changeEnumValue(configEnum.ACTIVITYSTATE, stateType);
dataList.push(changeData);
})
......@@ -79,15 +102,18 @@ export async function activityCreate(param) {
if (param.target && param.target.length > 0) {
verificationEnumTools.eccEnumValue('管理后台新增园区活动', 'target', configEnum.ACTIVITYTARGET, param.target);
}
verificationEnumTools.eccEnumValue('管理后台新增园区活动', 'state', configEnum.ACTIVITYSTATE, param.state);
let enterpriseInfo = await activityData.findActivityByParam({title:param.title});
// 校验时间
if (param.startTime >= param.endTime) {
throw new BizError(ERRORENUM.参数错误, '活动开始时间不能晚于或等于结束时间');
}
let enterpriseInfo = await activityData.findActivityByParam({title:param.title, startTime:param.startTime});
if (enterpriseInfo && enterpriseInfo.title) throw new BizError(ERRORENUM.该活动已存在, `${param.title}已经在库中存在`);
let activityInfo = {
id: randomId(TABLEID.活动),
title: param.title,
state: param.state,
startTime: param.startTime,
endTime: param.endTime,
target: param.target,
......@@ -106,13 +132,12 @@ export async function activityCreate(param) {
* @param uscc
*/
export async function activityInfo(id:string) {
/**校验企业 */
/**校验活动 */
let activityDbInfo = await activityData.findActivityByParam({id});
if (!activityDbInfo || !activityDbInfo.id) throw new BizError(ERRORENUM.未找到数据, `库中不存在id=${id}这个活动`);
let dataInfo = {
title: activityDbInfo.title,
state: activityDbInfo.state,
startTime: activityDbInfo.startTime,
endTime: activityDbInfo.endTime,
target: activityDbInfo.target,
......@@ -126,7 +151,7 @@ export async function activityInfo(id:string) {
/**
* 园区活动-修改
* @param uscc
* @param id
* @param param
*/
export async function activityUpdate(id:string, param) {
......@@ -137,15 +162,19 @@ export async function activityUpdate(id:string, param) {
if (param.target && param.target.length > 0) {
verificationEnumTools.eccEnumValue('管理后台新增园区活动', 'target', configEnum.ACTIVITYTARGET, param.target);
}
verificationEnumTools.eccEnumValue('管理后台新增园区活动', 'state', configEnum.ACTIVITYSTATE, param.state);
/**校验企业 */
// 校验时间
if (param.startTime >= param.endTime) {
throw new BizError(ERRORENUM.参数错误, '活动开始时间不能晚于或等于结束时间');
}
/**校验活动 */
let activityDbInfo = await activityData.findActivityByParam({id});
if (!activityDbInfo || !activityDbInfo.id) throw new BizError(ERRORENUM.未找到数据, `库中不存在id=${id}这个活动`);
/**修改字段 */
let changeList = checkChange(param, activityDbInfo);
if (!changeList.length) throw new BizError(ERRORENUM.数据无更新, `${param.name}数据无更新`);
if (!changeList.length) throw new BizError(ERRORENUM.数据无更新, `${param.title}数据无更新`);
changeList.forEach(key => {
activityDbInfo[key] = param[key];
});
......@@ -179,30 +208,40 @@ export async function activityDelete(id:string) {
* @param state 活动状态
* @returns 二维数组,第一行为表头,后续行为数据
*/
export async function outPutActivityData(title: string, startTime: number, endTime: number, target: number[], state: number) {
export async function outPutActivityData(title: string, startTime: number, endTime: number, target: number[], state: number, id:string[]) {
/** 拼接查询条件 */
let selectParam: any = {};
if (title) {
selectParam.title = { "$regex": `${title}` };
}
if (startTime && endTime) {
selectParam.startTime = { "$gte": startTime };
selectParam.endTime = { "$lte": endTime };
selectParam.startTime = { "$lte": endTime };
selectParam.endTime = { "$gte": startTime };
} else if (startTime) {
selectParam.startTime = { "$gte": startTime };
selectParam.startTime = { "$lte": endTime };
} else if (endTime) {
selectParam.endTime = { "$lte": endTime };
selectParam.endTime = { "$gte": startTime };
}
if (target && target.length > 0) {
selectParam.target = { "$in": target };
}
if (state) {
selectParam.state = state;
}
/** 查询园区活动数据 */
let activityDbList = await activityData.findActivityListByParam(selectParam);
// 如果有状态筛选,在内存中过滤
if (state) {
activityDbList = activityDbList.filter(info => {
const activityState = calculateActivityState(info.startTime, info.endTime);
return activityState === state;
});
}
// 如果有ID筛选
if (id) {
activityDbList = activityDbList.filter(info => id.includes(info.id));
}
/** 表头定义 */
const titleList = [
"活动标题",
......@@ -211,7 +250,7 @@ export async function outPutActivityData(title: string, startTime: number, endTi
"结束时间",
"活动类型",
"活动地点",
"活动描述"
// "活动描述"
];
let dataList = [titleList]; // 第一行为表头
......@@ -233,8 +272,9 @@ export async function outPutActivityData(title: string, startTime: number, endTi
}
changeData.target = targetTexts.join("、") || "未选择";
// 活动状态
changeData.state = verificationEnumTools.changeEnumValue(configEnum.ACTIVITYSTATE, changeData.state) || "未选择";
// 计算活动状态并转为文本
const activityState = calculateActivityState(info.startTime, info.endTime);
changeData.state = verificationEnumTools.changeEnumValue(configEnum.ACTIVITYSTATE, activityState) || "未选择";
/** 时间格式化 */
changeData.startTime = changeData.startTime ? formatDateTime(changeData.startTime) : "-";
......@@ -253,7 +293,7 @@ export async function outPutActivityData(title: string, startTime: number, endTi
changeData.endTime,
changeData.target,
changeData.location || "-",
changeData.desc || "-"
// changeData.desc || "-"
];
dataList.push(row);
......@@ -280,4 +320,25 @@ function formatDateTime(timestamp: number): string {
}
/**
* 根据活动时间计算活动状态
* @param startTime 开始时间戳
* @param endTime 结束时间戳
* @returns 活动状态枚举值
*/
function calculateActivityState(startTime:number, endTime:number) {
const now = Date.now();
if (now < startTime) {
return configEnum.ACTIVITYSTATE.未开始;
} else if (now >= startTime && now <= endTime) {
return configEnum.ACTIVITYSTATE.活动中;
} else {
return configEnum.ACTIVITYSTATE.已结束;
}
}
......@@ -77,69 +77,185 @@ export async function adminUserCreate(param) {
* 数据看板
*/
// export async function homePage() {
// let baseData = {
// "企业总数":0,
// "100平方公里范围企业":0,
// "3.73平方公里实体租赁":0,
// "关联入驻企业":0,
// "小台账企业":0,
// "重点稳商":0,
// /**上月 */
// "上月100平方公里范围企业":0,
// "上月3.73平方公里实体租赁":0,
// "上月关联入驻企业":0,
// "上月小台账企业":0,
// "上月重点稳商":0,
// /**汇总数据 */
// let 汇总数据 = {
// "企业总数": 0,
// "100平方公里范围企业": 0,
// "3.73平方公里实体租赁": 0,
// "关联入驻企业": 0,
// "小台账企业": 0,
// "重点稳商": 0,
// /**较上月变化量 */
// "较上月100平方公里范围企业变化": 0,
// "较上月3.73平方公里实体租赁变化": 0,
// "较上月关联入驻企业变化": 0,
// "较上月小台账企业变化": 0,
// "较上月重点稳商变化": 0,
// "较上月总入驻企业变化": 0
// };
// /** 查询企业数据 */
// let enterpriseDbList = await enterpriseData.findEnterpriseListByParam({});
// baseData.企业总数 = enterpriseDbList.length;
// enterpriseDbList.forEach( info => {
// let labels = info.labels;
// labels.forEach( info => {
// let {labelId, labelType, state} = info;
// if (state) {
// if (labelId == ENTERPRISESYSTEMLABEL["100平方公里"]) baseData["100平方公里范围企业"] += 1;
// if (labelId == ENTERPRISESYSTEMLABEL["3.73平方公里"]) baseData["3.73平方公里实体租赁"] += 1;
// if (labelId == ENTERPRISESYSTEMLABEL.软件关联入驻企业) baseData["关联入驻企业"] += 1;
// if (labelId == ENTERPRISESYSTEMLABEL.小台账企业) baseData["小台账企业"] += 1;
// if (labelId == ENTERPRISESYSTEMLABEL.重点稳商企业) baseData["重点稳商"] += 1;
// }
// })
// })
// /**上月 */
// /** 获取上月时间范围 */
// let now = moment();
// /** 获取时间范围 */
// let lastMonthStart = moment().subtract(1, 'month').startOf('month').valueOf();
// let lastMonthEnd = moment().subtract(1, 'month').endOf('month').valueOf();
// /** 查询上月入驻的企业数据 */
// let enterpriseLastMonthDbList = await enterpriseData.findEnterpriseListByParam({
// parkEntryTime: {
// $gte: lastMonthStart,
// $lte: lastMonthEnd
// /** 初始企业数据没有入驻时间处理:设置默认入驻时间:2025年12月 */
// let defaultParkEntryTime = moment('2025-12-01').startOf('month').valueOf();
// /** 查询所有企业数据 */
// let enterpriseDbList = await enterpriseData.findEnterpriseListByParam({});
// /** 统计当前所有企业数据 */
// 汇总数据.企业总数 = enterpriseDbList.length;
// // 分别统计当前所有企业和上月企业
// let currentMonthStats = {
// "企业总数": 0,
// "100平方公里范围企业": 0,
// "3.73平方公里实体租赁": 0,
// "关联入驻企业": 0,
// "小台账企业": 0,
// "重点稳商": 0,
// "总入驻企业": 0
// };
// let lastMonthStats = {
// "企业总数": 0,
// "100平方公里范围企业": 0,
// "3.73平方公里实体租赁": 0,
// "关联入驻企业": 0,
// "小台账企业": 0,
// "重点稳商": 0,
// "总入驻企业": 0
// };
// // 遍历所有企业进行统计
// enterpriseDbList.forEach(info => {
// // 处理入驻时间:如果为空则使用默认时间
// let parkEntryTime = info.parkEntryTime || defaultParkEntryTime;
// // 统计当前所有企业的标签
// info.labels.forEach(label => {
// let {labelId, state} = label;
// if (state === false) return; //跳过失效标签
// switch(parseInt(labelId)) {
// case ENTERPRISESYSTEMLABEL["100平方公里"]:
// currentMonthStats["100平方公里范围企业"] += 1;
// break;
// case ENTERPRISESYSTEMLABEL["3.73平方公里"]:
// currentMonthStats["3.73平方公里实体租赁"] += 1;
// break;
// case ENTERPRISESYSTEMLABEL.软件关联入驻企业:
// currentMonthStats["关联入驻企业"] += 1;
// break;
// case ENTERPRISESYSTEMLABEL.小台账企业:
// currentMonthStats["小台账企业"] += 1;
// break;
// case ENTERPRISESYSTEMLABEL.重点稳商企业:
// currentMonthStats["重点稳商"] += 1;
// break;
// }
// });
// // 统计上月数据
// enterpriseLastMonthDbList.forEach(info => {
// let labels = info.labels;
// labels.forEach(label => {
// let {labelId, labelType, state} = label;
// if (state) {
// if (labelId == ENTERPRISESYSTEMLABEL["100平方公里"]) baseData["上月100平方公里范围企业"] += 1;
// if (labelId == ENTERPRISESYSTEMLABEL["3.73平方公里"]) baseData["上月3.73平方公里实体租赁"] += 1;
// if (labelId == ENTERPRISESYSTEMLABEL.软件关联入驻企业) baseData["上月关联入驻企业"] += 1;
// if (labelId == ENTERPRISESYSTEMLABEL.小台账企业) baseData["上月小台账企业"] += 1;
// if (labelId == ENTERPRISESYSTEMLABEL.重点稳商企业) baseData["上月重点稳商"] += 1;
// // 判断是否是上月入驻的企业
// if (parkEntryTime >= lastMonthStart && parkEntryTime <= lastMonthEnd) {
// lastMonthStats["总入驻企业"] += 1;
// // 统计上月企业的标签
// info.labels.forEach(label => {
// let {labelId, state} = label;
// if (!state) return;
// switch(parseInt(labelId)) {
// case ENTERPRISESYSTEMLABEL["100平方公里"]:
// lastMonthStats["100平方公里范围企业"] += 1;
// break;
// case ENTERPRISESYSTEMLABEL["3.73平方公里"]:
// lastMonthStats["3.73平方公里实体租赁"] += 1;
// break;
// case ENTERPRISESYSTEMLABEL.软件关联入驻企业:
// lastMonthStats["关联入驻企业"] += 1;
// break;
// case ENTERPRISESYSTEMLABEL.小台账企业:
// lastMonthStats["小台账企业"] += 1;
// break;
// case ENTERPRISESYSTEMLABEL.重点稳商企业:
// lastMonthStats["重点稳商"] += 1;
// break;
// }
// });
// }
// });
// // 设置当前所有企业数量到汇总数据
// 汇总数据["100平方公里范围企业"] = currentMonthStats["100平方公里范围企业"];
// 汇总数据["3.73平方公里实体租赁"] = currentMonthStats["3.73平方公里实体租赁"];
// 汇总数据["关联入驻企业"] = currentMonthStats["关联入驻企业"];
// 汇总数据["小台账企业"] = currentMonthStats["小台账企业"];
// 汇总数据["重点稳商"] = currentMonthStats["重点稳商"];
// // 计算变化量(本月数据 - 上月数据)
// 汇总数据.较上月100平方公里范围企业变化 = currentMonthStats["100平方公里范围企业"] - lastMonthStats["100平方公里范围企业"];
// 汇总数据["较上月3.73平方公里实体租赁变化"] = currentMonthStats["3.73平方公里实体租赁"] - lastMonthStats["3.73平方公里实体租赁"];
// 汇总数据.较上月关联入驻企业变化 = currentMonthStats["关联入驻企业"] - lastMonthStats["关联入驻企业"];
// 汇总数据.较上月小台账企业变化 = currentMonthStats["小台账企业"] - lastMonthStats["小台账企业"];
// 汇总数据.较上月重点稳商变化 = currentMonthStats["重点稳商"] - lastMonthStats["重点稳商"];
// 汇总数据.较上月总入驻企业变化 = currentMonthStats["总入驻企业"] - lastMonthStats["总入驻企业"];
// /**企业服务追踪 */
// let 企业服务追踪 = {
// 企业需求总数:0,
// 已解决企业需求:0,
// 待解决需求数:0
// };
// /** 查询服务追踪数据 */
// let trackDbList = await findTrackListByParam({});
// 企业服务追踪.企业需求总数 = trackDbList.length;
// trackDbList.forEach( info => {
// if (info.trackType == TRACKTYPE.已解决) 企业服务追踪.已解决企业需求 += 1;
// if (info.trackType == TRACKTYPE.未解决) 企业服务追踪.待解决需求数 += 1;
// })
// /**实体租赁企业场地分布 */
// let 实体租赁企业场地分布 = [];
// // 定义物业列表(按你的需求顺序)
// let propertyList = [
// { id: PROPERTY.于田大厦, name: "于田大厦" },
// { id: PROPERTY.汽车创新港, name: "汽车创新港" },
// { id: PROPERTY.汽车城大厦, name: "汽车城大厦" },
// { id: PROPERTY.嘉亭荟, name: "嘉亭荟" },
// { id: PROPERTY.智驾园, name: "智驾园" },
// { id: PROPERTY.同济科技园, name: "同济科技园" }
// ];
// // 初始化统计数组
// propertyList.forEach(property => {
// 实体租赁企业场地分布.push({
// key: property.name,
// value: 0
// });
// });
// return baseData;
// // 遍历所有企业,筛选实体型企业并按物业统计
// enterpriseDbList.forEach(info => {
// // 判断是否为实体型企业(ENTERPRISENATURE.实体型 = 6)
// if (info.enterpriseNature === 6) {
// let propertyValue = info.property;
// // 转换为数字类型以确保类型匹配
// let propertyValueNum = Number(propertyValue);
// // 找到对应的物业并计数
// let propertyIndex = propertyList.findIndex(p => p.id === propertyValueNum);
// if (propertyIndex !== -1) {
// 实体租赁企业场地分布[propertyIndex].value += 1;
// }
// }
// });
// return {汇总数据, 企业服务追踪, 实体租赁企业场地分布};
// }
export async function homePage() {
/**汇总数据 */
......@@ -160,9 +276,13 @@ export async function homePage() {
};
/** 获取时间范围 */
let currentMonthStart = moment().startOf('month').valueOf();
let lastMonthStart = moment().subtract(1, 'month').startOf('month').valueOf();
let lastMonthEnd = moment().subtract(1, 'month').endOf('month').valueOf();
// 用于统计当前月(截至当前时刻)的企业数据
let currentMonthEnterpriseCount = 0;
/** 初始企业数据没有入驻时间处理:设置默认入驻时间:2025年12月 */
let defaultParkEntryTime = moment('2025-12-01').startOf('month').valueOf();
......@@ -172,9 +292,8 @@ export async function homePage() {
/** 统计当前所有企业数据 */
汇总数据.企业总数 = enterpriseDbList.length;
// 分别统计当前所有企业和上月企业
// 分别统计当前所有企业和上月底的企业
let currentMonthStats = {
"企业总数": 0,
"100平方公里范围企业": 0,
"3.73平方公里实体租赁": 0,
"关联入驻企业": 0,
......@@ -184,7 +303,6 @@ export async function homePage() {
};
let lastMonthStats = {
"企业总数": 0,
"100平方公里范围企业": 0,
"3.73平方公里实体租赁": 0,
"关联入驻企业": 0,
......@@ -198,7 +316,7 @@ export async function homePage() {
// 处理入驻时间:如果为空则使用默认时间
let parkEntryTime = info.parkEntryTime || defaultParkEntryTime;
// 统计当前所有企业的标签
// 统计当前月的企业标签(所有企业)
info.labels.forEach(label => {
let {labelId, state} = label;
if (state === false) return; //跳过失效标签
......@@ -222,14 +340,25 @@ export async function homePage() {
}
});
// 判断是否是上月入驻的企业
if (parkEntryTime >= lastMonthStart && parkEntryTime <= lastMonthEnd) {
// 统计当前月截至现在的入驻企业数
if (parkEntryTime <= moment().valueOf()) {
currentMonthStats["总入驻企业"] += 1;
}
// 判断是否在上月底之前就已存在的企业(用于统计上月底的数据)
if (parkEntryTime <= lastMonthEnd) {
// 统计上月底的企业总数
lastMonthStats["总入驻企业"] += 1;
// 统计上月企业的标签
// 统计上月底的标签数据
info.labels.forEach(label => {
let {labelId, state} = label;
if (!state) return;
if (state === false) return; //跳过失效标签
// 注意:这里需要判断标签在上月底之前是否已经存在
// 假设标签创建时间或生效时间也需要考虑
// 如果标签系统没有时间记录,我们可以假设所有现有标签在上月已存在
// 或者根据标签的createTime判断
switch(parseInt(labelId)) {
case ENTERPRISESYSTEMLABEL["100平方公里"]:
......@@ -305,8 +434,8 @@ export async function homePage() {
// 遍历所有企业,筛选实体型企业并按物业统计
enterpriseDbList.forEach(info => {
// 判断是否为实体型企业(ENTERPRISENATURE.实体型 = 6)
if (info.enterpriseNature === 6) {
let propertyValue = info.property;
if (info.enterpriseNature == labelEnum.ENTERPRISENATURE.实体型) {
let propertyValue = info.property; //PROPERTY
// 转换为数字类型以确保类型匹配
let propertyValueNum = Number(propertyValue);
......
......@@ -17,7 +17,7 @@ import { BizError } from "../util/bizError";
import { ERRORENUM } from "../config/errorEnum";
import * as sysTools from "../tools/system";
import * as labelData from "../data/label";
import { generateEnterpriseLabels, uniqueLabelList } from '../util/labelUtils';
import { convertLabelsToDbFormat, generateEnterpriseLabels, uniqueLabelList } from '../util/labelUtils';
import moment from "moment";
let md5 = require("md5");
......@@ -72,10 +72,12 @@ export async function enterpriseCreate(param) {
if (enterpriseDbInfo && enterpriseDbInfo.uscc) throw new BizError(ERRORENUM.该企业已存在, `${param.uscc}已经在库中存在`);
// 1. 获取所有可用的标签
const activeLabels = await labelData.selectLabelList({ state: false });
let activeLabels = await labelData.selectLabelList({ state: false });
// 2. 生成企业标签数组
const labels = await generateEnterpriseLabels(param, activeLabels);
let labels = await generateEnterpriseLabels(param, activeLabels);
let zhuceziben = sysTools.formatRegisteredCapital(param.zhuceziben)
// 3. 准备企业数据
let enterpriseInfo = {
......@@ -93,12 +95,13 @@ export async function enterpriseCreate(param) {
RAS: param.RAS,
jingYingFanWei: param.jingYingFanWei,
legalPerson: param.legalPerson,
zhuceziben: param.zhuceziben,
zhuceziben,
dianHua: param.dianHua,
createTime: new Date().valueOf(),
labels: labels,
pwd: sysTools.getPwdMd5(param.uscc, md5(param.uscc.slice(param.uscc.length-6))),
firstLoginIsChangePwd:false,
isSettled: configEnum.STATE.
};
// 4. 保存企业数据
......@@ -128,43 +131,80 @@ export async function enterpriseList(dataType:number, name:string, industry, par
selectParam.industry = {"$in":industry};
}
if (parkEntryTime) {
let parkEntryStartTime = moment(`${parkEntryTime}-01-01`);
let parkEntryEndTime = moment(`${parkEntryTime}-12-31`);
selectParam.parkEntryTime = {"$gt":parkEntryStartTime, "$lt":parkEntryEndTime};
let parkEntryStartTime = moment(`${parkEntryTime}-01-01`).valueOf();
let parkEntryEndTime = moment(`${parkEntryTime}-12-31`).valueOf();
selectParam.parkEntryTime = {"$gte":parkEntryStartTime, "$lte":parkEntryEndTime};
}
if (logonTime) {
let logonStartTime = moment(`${logonTime}-01-01`);
let logonEndTime = moment(`${logonTime}-12-31`);
selectParam.logonTime = {"$gt":logonStartTime, "$lt":logonEndTime};
let logonStartTime = moment(`${logonTime}-01-01`).valueOf();
let logonEndTime = moment(`${logonTime}-12-31`).valueOf();
selectParam.logonTime = {"$gte":logonStartTime, "$lte":logonEndTime};
}
//企业库列表分类
let allLabelList = [];
let dataTypeLabelList = [];
if (dataType) {
if (dataType == labelEnum.BASELABEL["100平方公里"]) allLabelList.push(labelEnum.BASELABEL["100平方公里"].toString());
else if (dataType == labelEnum.BASELABEL["3.73平方公里"]) allLabelList.push(labelEnum.BASELABEL["3.73平方公里"].toString());
else if (dataType == labelEnum.BASELABEL.小台账企业) allLabelList.push(labelEnum.BASELABEL.小台账企业.toString());
else if (dataType == labelEnum.BASELABEL.软件关联入驻企业) allLabelList.push(labelEnum.BASELABEL.软件关联入驻企业.toString());
else if (dataType == labelEnum.BASELABEL.重点稳商企业) allLabelList.push(labelEnum.BASELABEL.重点稳商企业.toString());
if (dataType == labelEnum.BASELABEL["100平方公里"]) dataTypeLabelList.push(labelEnum.BASELABEL["100平方公里"].toString());
else if (dataType == labelEnum.BASELABEL["3.73平方公里"]) dataTypeLabelList.push(labelEnum.BASELABEL["3.73平方公里"].toString());
else if (dataType == labelEnum.BASELABEL.小台账企业) dataTypeLabelList.push(labelEnum.BASELABEL.小台账企业.toString());
else if (dataType == labelEnum.BASELABEL.软件关联入驻企业) dataTypeLabelList.push(labelEnum.BASELABEL.软件关联入驻企业.toString());
else if (dataType == labelEnum.BASELABEL.重点稳商企业) dataTypeLabelList.push(labelEnum.BASELABEL.重点稳商企业.toString());
}
// 处理标签筛选逻辑
if (dataTypeLabelList.length > 0 || (labelIdList && labelIdList.length > 0)) {
let labelConditions = [];
// 如果传了dataType,必须包含该标签
if (dataTypeLabelList.length > 0) {
labelConditions.push({
"labels": {
"$elemMatch": {
"labelId": { "$in": dataTypeLabelList }
}
}
});
}
//标签筛选
// 如果传了labelIdList,必须包含其中任意一个标签
if (labelIdList && labelIdList.length > 0) {
labelIdList.forEach( info => {
allLabelList.push(info.toString());
})
let uniqueLabels = uniqueLabelList(labelIdList.map(id => id.toString()));
if (uniqueLabels.length > 0) {
labelConditions.push({
"labels": {
"$elemMatch": {
"labelId": { "$in": uniqueLabels }
}
}
});
}
}
if (dataType || labelIdList && labelIdList.length > 0) {
let uniqueLabels = uniqueLabelList(allLabelList);
selectParam.labels = {"$elemMatch":{labelId:{"$in":uniqueLabels} } }
// 构建查询条件
if (labelConditions.length === 1) {
Object.assign(selectParam, labelConditions[0]);
} else if (labelConditions.length > 1) {
// 使用 $and 连接多个条件,表示必须同时满足
selectParam["$and"] = labelConditions;
}
}
/**标签名称转换 */
let labelDbList = await labelData.selectLabelList({});
let labelDbMap = {};
labelDbList.forEach( info => {
labelDbMap[info.id] = info.labelName;
})
/**需要用到的查询数据 */
let enterpriseDbList = await enterpriseData.findEnterpriseListToPage(selectParam, (page - 1) * 10);
// 使用更稳定的排序:首先按createTime,然后按id或uscc确保顺序稳定
let enterpriseDbList = await enterpriseData.findEnterpriseListToPageSort(selectParam, (page - 1) * 10, {createTime: -1, _id: -1});
let count = await enterpriseData.findEnterpriseCount(selectParam);//符合查询条件的数据总数
/**组合返回结果 */
let dataList = [];
enterpriseDbList.forEach( info => {
/**截取返回数据 */
let changeData:any = extractData(splitResultConfig.enterpriseListConfig, info, true);
......@@ -172,7 +212,12 @@ export async function enterpriseList(dataType:number, name:string, industry, par
/**将枚举值转为字符 */
let industry = [];
if (changeData.industry && changeData.industry.length > 0) {
industry.push(verificationEnumTools.changeEnumValue(industryEnum.ALLINDUSTRY, changeData.industry))
// 注意:这里应该是数组处理,但原代码用单个值处理
// 根据实际情况调整
let industryValue = verificationEnumTools.changeEnumValue(industryEnum.ALLINDUSTRY, changeData.industry);
if (industryValue) {
industry.push(industryValue);
}
}
changeData.industry = industry;
......@@ -180,7 +225,10 @@ export async function enterpriseList(dataType:number, name:string, industry, par
if (changeData.labels && changeData.labels.length > 0) {
changeData.labels.forEach( info => {
let {labelId, state} = info;
labels.push(verificationEnumTools.changeEnumValue(labelEnum.ENTERPRISESYSTEMLABEL, parseInt(labelId)))
// 只添加状态为true的标签
if (state === true || state === undefined) {
labels.push(labelDbMap[labelId]);
}
})
}
changeData.labels = labels;
......@@ -189,7 +237,7 @@ export async function enterpriseList(dataType:number, name:string, industry, par
changeData.RAS = verificationEnumTools.changeEnumValue(configEnum.RAS, changeData.RAS);
dataList.push(changeData);
})
});
return {count, dataList};
}
......@@ -221,8 +269,10 @@ export async function enterpriseInfo(uscc:string) {
parkEntryTime: enterpriseDbInfo.parkEntryTime, //moment(enterpriseDbInfo.parkEntryTime).format("YYYY-MM-DD"), //入驻园区时间
labels: labels, //企业标签
industry: enterpriseDbInfo.industry, //行业领域
property: enterpriseDbInfo.property, //所属物业
enterpriseNature: enterpriseDbInfo.enterpriseNature, //企业性质
// property: enterpriseDbInfo.property.toString(), //所属物业
// enterpriseNature: enterpriseDbInfo.enterpriseNature.toString(), //企业性质
property: enterpriseDbInfo.property ? enterpriseDbInfo.property.toString() : "", //所属物业
enterpriseNature: enterpriseDbInfo.enterpriseNature ? enterpriseDbInfo.enterpriseNature.toString() : "", //企业性质
leasedArea: enterpriseDbInfo.leasedArea, //租赁面积(㎡)
RAS: enterpriseDbInfo.RAS, //登记状态
jingYingFanWei: enterpriseDbInfo.jingYingFanWei, //经营范围
......@@ -252,10 +302,45 @@ export async function enterpriseUpdate(uscc:string, param) {
/**校验标签 */
if (param.labels && param.labels.length > 0) {
// 检查标签中是否包含多个企业性质或所属物业
let enterpriseNatureLabels = [];
let propertyLabels = [];
let yearLabels = [];
for (let i = 0; i < param.labels.length; i++) {
let labelDbInfo = await labelData.findOnceLabel(param.labels[i]);
if (!labelDbInfo && !labelDbInfo.id) throw new BizError(ERRORENUM.该标签不存在, `${param.labels[i]}在库中不存在`);
let labelId = param.labels[i];
let labelDbInfo = await labelData.findOnceLabel(labelId);
if (!labelDbInfo || !labelDbInfo.id) {
throw new BizError(ERRORENUM.该标签不存在, `${labelId}在库中不存在`);
}
// 根据标签类型分类
if (labelDbInfo.labelType === labelEnum.LABELTYPE.企业性质) {
enterpriseNatureLabels.push(labelId);
} else if (labelDbInfo.labelType === labelEnum.LABELTYPE.所属物业) {
propertyLabels.push(labelId);
} else if (labelDbInfo.labelType === labelEnum.LABELTYPE.入驻年份) {
yearLabels.push(labelId);
}
}
// 检查企业性质标签是否多选
if (enterpriseNatureLabels.length > 1) {
throw new BizError(ERRORENUM.企业性质不可多选, '企业性质不可多选');
}
// 检查所属物业标签是否多选
if (propertyLabels.length > 1) {
throw new BizError(ERRORENUM.所属物业不可多选, '所属物业不可多选');
}
// 检查入驻年份标签是否多选
if (yearLabels.length > 1) {
throw new BizError(ERRORENUM.入驻年份不可多选, '入驻年份不可多选');
}
param.labels = await convertLabelsToDbFormat(param.labels);
}
if (!sysTools.eccUscc(param.uscc)) throw new BizError(ERRORENUM.统一社会信用代码不合法);
......@@ -274,6 +359,84 @@ export async function enterpriseUpdate(uscc:string, param) {
enterpriseDbInfo[key] = param[key];
});
/**处理入驻年份标签更新(新增的逻辑)*/
if (param.parkEntryTime) {
try {
let year = moment(param.parkEntryTime).format("YYYY");
if (year && year != "-") {
let yearValue;
switch (year.toString()) {
case '2023':
yearValue = labelEnum.ENTERPRISESYSTEMLABEL["2023年"];
break;
case '2024':
yearValue = labelEnum.ENTERPRISESYSTEMLABEL["2024年"];
break;
case '2025':
yearValue = labelEnum.ENTERPRISESYSTEMLABEL["2025年"];
break;
case '2026':
yearValue = labelEnum.ENTERPRISESYSTEMLABEL["2026年"];
break;
case '2027':
yearValue = labelEnum.ENTERPRISESYSTEMLABEL["2027年"];
break;
case '2028':
yearValue = labelEnum.ENTERPRISESYSTEMLABEL["2028年"];
break;
default:
// 处理其他年份
yearValue = year.toString();
break;
}
if (yearValue) {
// 查找现有的入驻年份标签
let existingYearLabelIndex = -1;
let existingYearLabel = null;
for (let j = 0; j < enterpriseDbInfo.labels.length; j++) {
let label = enterpriseDbInfo.labels[j];
// 检查标签类型是否为入驻年份
if (label.labelType === labelEnum.LABELTYPE.入驻年份) {
existingYearLabelIndex = j;
existingYearLabel = label;
break;
}
}
if (existingYearLabelIndex !== -1 && existingYearLabel) {
// 如果已存在入驻年份标签
if (existingYearLabel.labelId && existingYearLabel.labelId.toString() !== yearValue.toString()) {
// 标签年份与当前年份不一致,需要更新
enterpriseDbInfo.labels[existingYearLabelIndex] = {
labelId: yearValue.toString(),
labelType: labelEnum.LABELTYPE.入驻年份,
state: true
};
console.log(`已为企业 ${enterpriseDbInfo.name} (${enterpriseDbInfo.uscc}) 更新入驻年份标签:从 ${existingYearLabel.labelId} 更新为 ${yearValue}`);
} else {
// 标签年份一致,无需修改
console.log(`企业 ${enterpriseDbInfo.name} (${enterpriseDbInfo.uscc}) 入驻年份标签已是最新(${yearValue}),无需更新`);
}
} else {
// 不存在入驻年份标签,需要添加
enterpriseDbInfo.labels.push({
labelId: yearValue.toString(),
labelType: labelEnum.LABELTYPE.入驻年份,
state: true
});
console.log(`已为企业 ${enterpriseDbInfo.name} (${enterpriseDbInfo.uscc}) 添加 ${year}年 入驻年份标签`);
}
}
}
} catch (error) {
console.error(`为企业 ${enterpriseDbInfo.name} (${enterpriseDbInfo.uscc}) 处理入驻年份标签时出错:`, error);
// 继续执行修改操作,标签更新失败不影响整体业务
}
}
await enterpriseDbInfo.save();
return {isSuccess:true};
......@@ -304,7 +467,7 @@ export async function enterpriseDelete(uscc:string) {
* @param dataType 企业分类(1=100平方公里、2=3.73平方公里、3=软件关联入驻企业、4=小台账企业、5=重点稳商企业)
* @returns 二维数组,第一行为表头,后续行为数据
*/
export async function outPutEnterpriseData(name:string, industry:string[], parkEntryTime:number, logonTime:number, labelIdList:string[], dataType:number) {
export async function outPutEnterpriseData(name:string, industry:string[], parkEntryTime:number, logonTime:number, labelIdList:string[], dataType:number, uscc:string[]) {
/** 拼接查询条件 */
let selectParam: any = {};
if (name) {
......@@ -323,6 +486,9 @@ export async function outPutEnterpriseData(name:string, industry:string[], parkE
let logonEndTime = moment(`${logonTime}-12-31`).valueOf();
selectParam.logonTime = { "$gte": logonStartTime, "$lte": logonEndTime };
}
if (uscc) {
selectParam.uscc = {"$in": uscc};
}
// 标签筛选
let allLabelList = [];
......@@ -345,13 +511,17 @@ export async function outPutEnterpriseData(name:string, industry:string[], parkE
}
/** 查询企业数据 */
let enterpriseDbList = await enterpriseData.findEnterpriseListByParam(selectParam);
let enterpriseDbList = await enterpriseData.findEnterpriseListByParamSort(selectParam, {createTime: -1});
/** 表头定义 */
const titleList = [
let titleList = [
"企业名称",
"统一社会信用代码",
"注册地址",
"所属省份",
"所属城市",
"所属区县",
"详细地址",
// "注册地址",
"注册时间",
"入驻时间",
"行业领域",
......@@ -367,10 +537,14 @@ export async function outPutEnterpriseData(name:string, industry:string[], parkE
];
/** 字段映射 */
const keyList = [
let keyList = [
"name",
"uscc",
"logonAddress",
"province", // 所属省份
"city", // 所属城市
"district", // 所属区县
"logonAdd", // 详细地址
// "logonAddress",
"logonTime",
"parkEntryTime",
"industry",
......@@ -397,6 +571,14 @@ export async function outPutEnterpriseData(name:string, industry:string[], parkE
changeData.enterpriseNature = verificationEnumTools.changeEnumValue(labelEnum.ENTERPRISENATURE, changeData.enterpriseNature) || "未选择";
changeData.RAS = verificationEnumTools.changeEnumValue(configEnum.RAS, changeData.RAS) || "未选择";
/**注册地址转文本 */
if (changeData.logonAddress) {
changeData.province = changeData.logonAddress[0];
changeData.city = changeData.logonAddress[1];
changeData.district = changeData.logonAddress[2];
changeData.logonAdd = changeData.logonAddress[3];
}
/** 标签转文本 */
let labelNames = [];
if (changeData.labels && changeData.labels.length > 0) {
......@@ -407,8 +589,16 @@ export async function outPutEnterpriseData(name:string, industry:string[], parkE
changeData.labels = labelNames.join("、") || "无标签";
/** 时间格式化 */
changeData.logonTime = changeData.logonTime ? moment(changeData.logonTime).format("YYYY-MM-DD") : "-";
changeData.parkEntryTime = changeData.parkEntryTime ? moment(changeData.parkEntryTime).format("YYYY-MM-DD") : "-";
if (changeData.logonTime && changeData.logonTime != "-") {
changeData.logonTime = moment(changeData.logonTime).format("YYYY-MM-DD");
} else {
changeData.logonTime = "-";
}
if (changeData.parkEntryTime && changeData.parkEntryTime != "-") {
changeData.parkEntryTime = moment(changeData.parkEntryTime).format("YYYY-MM-DD");
} else {
changeData.parkEntryTime = "-";
}
/** 生成一行数据 */
let row = [];
......
......@@ -16,6 +16,10 @@ import * as sysTools from "../tools/system";
import * as negotiationData from "../data/negotiation";
import * as enterpriseData from "../data/enterprise";
import * as manageData from "../data/manage";
import moment from "moment";
import { BizError } from "../util/bizError";
import { ERRORENUM } from "../config/errorEnum";
import { getEnterpriseMap, getManageData } from "../util/piecemeal";
const xlsx = require('node-xlsx');
const path = require('path');
......@@ -55,6 +59,10 @@ export async function upShowExcel(list, excelType) {
if (excelType == UpExcelNameType.在谈在跟) {
await 在谈在跟(buff);
} else if (excelType == UpExcelNameType.全部企业) {
await 全部企业(buff);
} else if (excelType == UpExcelNameType.经营数据) {
await 经营数据(buff);
}
return {isSuccess:true}
......@@ -66,38 +74,6 @@ export async function 在谈在跟(buff) {
let excelData = onceSheetBecomeOfblockData("在谈在跟.xlsx", "Sheet1");
// let excelData = [
// {
// blockData: [
// [
// "在跟在谈导入新增记录",
// "__EMPTY",
// "__EMPTY_1",
// "__EMPTY_2",
// "__EMPTY_3",
// "__EMPTY_4",
// ],
// [
// "企业名称",
// "行业领域",
// "推进、注册情况",
// "进展情况",
// "负责人、首谈人",
// "对接部门",
// ],
// [
// "上海测试在谈在跟企业2",
// "渔业",
// "洽谈中",
// "初次接触",
// "测试陈",
// "测试部",
// ],
// ],
// blockTitle: "0_0",
// },
// ]
let negotiationList = [];
excelData.forEach( info => {
let {blockData} = info;
......@@ -106,7 +82,7 @@ export async function 在谈在跟(buff) {
/**枚举转换 */
let industry = [industryEnum.ALLINDUSTRY[rowData[1]]];
let registrationStatus = configEnum.REGISTRATIONSTATUS[rowData[2]];
let progressStatus = configEnum.REGISTRATIONSTATUS[rowData[3]];
let progressStatus = configEnum.PROGRESSSTATUS[rowData[3]];
//准备在谈在跟数据
let negotiationInfo = {
id: randomId(TABLEID.在跟在谈),
......@@ -133,40 +109,54 @@ export async function 全部企业(buff) {
let excelData = onceSheetBecomeOfblockData("全部企业.xlsx", "Sheet1");
/**获取所有企业 */
let enterpriseMap = await getEnterpriseMap();
let enterpriseList = [];
excelData.forEach( info => {
let {blockData} = info;
for (let i = 2; i < blockData.length; i++) {
let rowData = blockData[i];
if (!sysTools.eccUscc(rowData[1])) throw new BizError(ERRORENUM.统一社会信用代码不合法);
let now = new Date().valueOf();
if (new Date(rowData[6]).valueOf() > now) throw new BizError(ERRORENUM.不可选择未来时间);
if (new Date(rowData[7]).valueOf() > now) throw new BizError(ERRORENUM.不可选择未来时间);
/**不能出现重复的统一社会信用代码 */
let thisEnterprise = enterpriseMap[rowData[1]];
if (thisEnterprise) throw new BizError(ERRORENUM.该企业已存在, `${rowData[1]}已经在库中存在`);
/**枚举转换 */
let industry = [industryEnum.ALLINDUSTRY[rowData[12]]]; //行业领域
let labelList = parseLabels(rowData); //解析标签
let enterpriseNature = labelEnum.ENTERPRISENATURE[rowData[13]]; //企业性质
let property = labelEnum.PROPERTY[rowData[14]]; //所属物业
let RAS = configEnum.RAS[rowData[18]];
let enterpriseNature = labelEnum.ENTERPRISENATURE[rowData[9]]; //企业性质
let property = labelEnum.PROPERTY[rowData[10]]; //所属物业
let RAS = configEnum.RAS[rowData[14]];
let logonAddress = [rowData[2], rowData[3], rowData[4], rowData[5]];
//准备企业数据
let enterpriseInfo = {
id: randomId(TABLEID.企业基础信息表),
// id: randomId(TABLEID.企业基础信息表),
name: rowData[0],
uscc: rowData[1],
logonAddress: logonAddress,
logonTime: rowData[6],
parkEntryTime: rowData[7],
logonTime: new Date(rowData[6]).valueOf(),
parkEntryTime: new Date(rowData[7]).valueOf(),
industry,
property,
enterpriseNature,
leasedArea: rowData[17],
leasedArea: rowData[13],
RAS,
jingYingFanWei: rowData[19],
legalPerson: rowData[20],
zhuceziben: rowData[21],
dianHua: rowData[22],
jingYingFanWei: rowData[15],
legalPerson: rowData[16],
zhuceziben: rowData[17],
dianHua: rowData[18],
createTime: new Date().valueOf(),
labels: labelList,
pwd: sysTools.getPwdMd5(rowData[1], md5(rowData[1].slice(rowData[1].length-6))),
firstLoginIsChangePwd:false,
isSettled: configEnum.STATE.
};
enterpriseList.push(enterpriseInfo);
......@@ -182,13 +172,30 @@ export async function 经营数据(buff) {
let excelData = onceSheetBecomeOfblockData("经营数据.xlsx", "Sheet1");
/**获取所有企业 */
let enterpriseMap = await getEnterpriseMap();
let manageList = [];
excelData.forEach( info => {
for (let thisexcel = 0; thisexcel < excelData.length; thisexcel++) {
let info = excelData[thisexcel];
let {blockData} = info;
for (let i = 2; i < blockData.length; i++) {
let rowData = blockData[i];
/**不能出现重复的统一社会信用代码 */
let thisEnterprise = enterpriseMap[rowData[1]];
if (!thisEnterprise) throw new BizError(ERRORENUM.该企业不存在, `${rowData[1]}在库中不存在`);
if (!sysTools.eccUscc(rowData[1])) throw new BizError(ERRORENUM.统一社会信用代码不合法);
/**枚举转换 */
let period = configEnum.REGISTRATIONSTATUS[rowData[2]];
let period = configEnum.PERIOD[rowData[3]];
/**校验经营数据是否重复 */
let isAdd = await getManageData(rowData[1], rowData[2], period);
if (!isAdd) throw new BizError(ERRORENUM.请勿重复提交填报数据, `${rowData[1]}已有${rowData[2]}${period}时间经营数据`);
//准备经营数据
let manageInfo = {
id: randomId(TABLEID.企业经营数据),
......@@ -208,7 +215,7 @@ export async function 经营数据(buff) {
manageList.push(manageInfo);
}
});
}
await manageData.createDataByParam(manageList);
console.log("经营数据数据导入成功");
......@@ -225,142 +232,129 @@ function parseLabels(rowData) {
let currentTime = new Date().valueOf();
// 1. 基础标签 (BASELABEL)
if (rowData[9] === '是') {
labels.push({
labelId: labelEnum.BASELABEL["3.73平方公里"],
labelType: labelEnum.LABELTYPE.基础标签,
state: true
});
}
if (rowData[8] === '是') {
labels.push({
labelId: labelEnum.BASELABEL["100平方公里"],
labelType: labelEnum.LABELTYPE.基础标签,
state: true
});
}
if (rowData[10] === '是') {
if (rowData[8]) {
labels.push({
labelId: labelEnum.BASELABEL["软件关联入驻企业"],
labelId: labelEnum.ENTERPRISESYSTEMLABEL[rowData[8]],
labelType: labelEnum.LABELTYPE.基础标签,
state: true
});
}
if (rowData[11] === '是') {
if (rowData[9]) {
labels.push({
labelId: labelEnum.BASELABEL["小台账企业"],
labelType: labelEnum.LABELTYPE.基础标签,
labelId: labelEnum.ENTERPRISESYSTEMLABEL[rowData[9]],
labelType: labelEnum.LABELTYPE.企业性质,
state: true
});
}
if (rowData[12] === '是') {
if (rowData[10]) {
labels.push({
labelId: labelEnum.BASELABEL["重点稳商企业"],
labelType: labelEnum.LABELTYPE.基础标签,
labelId: labelEnum.ENTERPRISESYSTEMLABEL[rowData[10]],
labelType: labelEnum.LABELTYPE.所属物业,
state: true
});
}
// 2. 入驻年份标签 (ENTERPRISESYSTEMLABEL)
let entryYear = rowData['parkEntryTime'];
if (entryYear && entryYear != "-") {
let yearValue;
switch (entryYear.toString()) {
case '2023年':
yearValue = labelEnum.ENTERPRISESYSTEMLABEL["2023年"];
break;
case '2024年':
yearValue = labelEnum.ENTERPRISESYSTEMLABEL["2024年"];
break;
case '2025年':
yearValue = labelEnum.ENTERPRISESYSTEMLABEL["2025年"];
break;
case '2026年':
yearValue = labelEnum.ENTERPRISESYSTEMLABEL["2026年"];
break;
case '2027年':
yearValue = labelEnum.ENTERPRISESYSTEMLABEL["2027年"];
break;
case '2028年':
yearValue = labelEnum.ENTERPRISESYSTEMLABEL["2028年"];
break;
// default:
// yearValue = labelEnum.ENTERPRISESYSTEMLABEL["其他年份"];
}
if (rowData[11]) {
labels.push({
labelId: yearValue,
labelId: labelEnum.ENTERPRISESYSTEMLABEL[rowData[11]],
labelType: labelEnum.LABELTYPE.入驻年份,
state: true
});
}
// 3. 所属物业(PROPERTY)
let property = rowData['property'];
if (property && property != "-") {
let propertyValue;
switch (property) {
case "于田大厦":
propertyValue = labelEnum.PROPERTY.于田大厦;
break;
case "同济科技园":
propertyValue = labelEnum.PROPERTY.同济科技园;
break;
case "嘉亭荟":
propertyValue = labelEnum.PROPERTY.嘉亭荟;
break;
case "智驾园":
propertyValue = labelEnum.PROPERTY.智驾园;
break;
case "汽车创新港":
propertyValue = labelEnum.PROPERTY.汽车创新港;
break;
case "汽车城大厦":
propertyValue = labelEnum.PROPERTY.汽车城大厦;
break;
}
labels.push({
labelId: propertyValue,
labelType: labelEnum.LABELTYPE.所属物业,
state: true
});
}
// 4. 企业性质 enterpriseNature: EnterpriseNatureMap[rowData.enterpriseNature] || labelEnum.ENTERPRISENATURE.实体型
let enterpriseNature = rowData['enterpriseNature'];
if (enterpriseNature && enterpriseNature != "-") {
let enterpriseNatureValue;
switch (enterpriseNature) {
case "实体型":
enterpriseNatureValue = labelEnum.ENTERPRISENATURE.实体型;
break;
case "注册型":
enterpriseNatureValue = labelEnum.ENTERPRISENATURE.注册型;
break;
case "虚拟型":
enterpriseNatureValue = labelEnum.ENTERPRISENATURE.虚拟型;
break;
}
labels.push({
labelId: enterpriseNatureValue,
labelType: labelEnum.LABELTYPE.企业性质,
state: true
});
}
// // 2. 入驻年份标签 (ENTERPRISESYSTEMLABEL)
// let entryYear = rowData['parkEntryTime'];
// if (entryYear && entryYear != "-") {
// let yearValue;
// switch (entryYear.toString()) {
// case '2023年':
// yearValue = labelEnum.ENTERPRISESYSTEMLABEL["2023年"];
// break;
// case '2024年':
// yearValue = labelEnum.ENTERPRISESYSTEMLABEL["2024年"];
// break;
// case '2025年':
// yearValue = labelEnum.ENTERPRISESYSTEMLABEL["2025年"];
// break;
// case '2026年':
// yearValue = labelEnum.ENTERPRISESYSTEMLABEL["2026年"];
// break;
// case '2027年':
// yearValue = labelEnum.ENTERPRISESYSTEMLABEL["2027年"];
// break;
// case '2028年':
// yearValue = labelEnum.ENTERPRISESYSTEMLABEL["2028年"];
// break;
// // default:
// // yearValue = labelEnum.ENTERPRISESYSTEMLABEL["其他年份"];
// }
// labels.push({
// labelId: yearValue,
// labelType: labelEnum.LABELTYPE.入驻年份,
// state: true
// });
// }
// // 3. 所属物业(PROPERTY)
// let property = rowData['property'];
// if (property && property != "-") {
// let propertyValue;
// switch (property) {
// case "于田大厦":
// propertyValue = labelEnum.PROPERTY.于田大厦;
// break;
// case "同济科技园":
// propertyValue = labelEnum.PROPERTY.同济科技园;
// break;
// case "嘉亭荟":
// propertyValue = labelEnum.PROPERTY.嘉亭荟;
// break;
// case "智驾园":
// propertyValue = labelEnum.PROPERTY.智驾园;
// break;
// case "汽车创新港":
// propertyValue = labelEnum.PROPERTY.汽车创新港;
// break;
// case "汽车城大厦":
// propertyValue = labelEnum.PROPERTY.汽车城大厦;
// break;
// }
// labels.push({
// labelId: propertyValue,
// labelType: labelEnum.LABELTYPE.所属物业,
// state: true
// });
// }
// // 4. 企业性质 enterpriseNature: EnterpriseNatureMap[rowData.enterpriseNature] || labelEnum.ENTERPRISENATURE.实体型
// let enterpriseNature = rowData['enterpriseNature'];
// if (enterpriseNature && enterpriseNature != "-") {
// let enterpriseNatureValue;
// switch (enterpriseNature) {
// case "实体型":
// enterpriseNatureValue = labelEnum.ENTERPRISENATURE.实体型;
// break;
// case "注册型":
// enterpriseNatureValue = labelEnum.ENTERPRISENATURE.注册型;
// break;
// case "虚拟型":
// enterpriseNatureValue = labelEnum.ENTERPRISENATURE.虚拟型;
// break;
// }
// labels.push({
// labelId: enterpriseNatureValue,
// labelType: labelEnum.LABELTYPE.企业性质,
// state: true
// });
// }
return labels;
}
......@@ -17,7 +17,8 @@ export async function getLabel(labelType?) {
labelDbList.forEach( info => {
dataList.push({
key: info.id,
value: info.labelName
value: info.labelName,
type: info.labelType
})
})
......
......@@ -6,7 +6,7 @@ import * as verificationEnumTools from "../util/verificationEnum";
import * as configEnum from "../config/enum";
import * as industryEnum from "../config/enum/industryEnum";
import * as manageData from "../data/manage";
import { checkChange, extractData } from "../util/piecemeal";
import { checkChange, extractData, getManageData } from "../util/piecemeal";
import * as splitResultConfig from '../config/splitResultConfig';
import { eccFormParam } from "../util/verificationParam";
import { ManageAddConfig, ManageUpdateConfig } from "../config/eccParam/admin";
......@@ -38,7 +38,7 @@ export async function manageList(name:string, year:number, period:number, page:n
}
/**需要用到的查询数据 */
let manageDbList = await manageData.findManageListToPage(selectParam, (page - 1) * 10);
let manageDbList = await manageData.findManageListToPageSort(selectParam, (page - 1) * 10, {year: -1});
let count = await manageData.findManageCount(selectParam);//符合查询条件的数据总数
/**组合返回结果 */
......@@ -67,8 +67,9 @@ export async function manageCreate(param) {
/**校验枚举 */
verificationEnumTools.eccEnumValue('管理后台新增经营数据', 'period', configEnum.PERIOD, param.period);
let enterpriseInfo = await manageData.findManageByParam({name:param.name});
if (enterpriseInfo && enterpriseInfo.name) throw new BizError(ERRORENUM.该企业已存在, `${param.name}已经在库中存在`);
/**校验经营数据是否重复 */
let isAdd = await getManageData(param.uscc, param.year, param.period);
if (!isAdd) throw new BizError(ERRORENUM.请勿重复提交填报数据, `${param.uscc}已有${param.year}${param.period}时间经营数据`);
let manageInfo = {
id: randomId(TABLEID.企业经营数据),
......@@ -168,7 +169,7 @@ export async function manageDelete(id:string) {
* @param period 数据期间 上半年、下半年、全年
* @returns 二维数组,第一行为表头,后续行为数据
*/
export async function outPutManageData(name: string, year: number, period: number) {
export async function outPutManageData(name: string, year: number, period: number, id:string[]) {
/** 拼接查询条件 */
let selectParam: any = {};
if (name) {
......@@ -180,6 +181,9 @@ export async function outPutManageData(name: string, year: number, period: numbe
if (period) {
selectParam.period = period;
}
if (id) {
selectParam.id = {"$in": id};
}
/** 查询经营数据 */
let manageDbList = await manageData.findManageListByParam(selectParam);
......@@ -220,7 +224,7 @@ export async function outPutManageData(name: string, year: number, period: numbe
/** 枚举值转文本 */
changeData.period = verificationEnumTools.changeEnumValue(configEnum.PERIOD, changeData.period) || "未选择";
changeData.isSubmit = changeData.isSubmit ? "已提交" : "未提交";
changeData.isSubmit = info.isSubmit ? "已提交" : "未提交";
/** 数字格式化(保留两位小数) */
const numberKeys = ["BI", "VAT", "CIT", "PIT", "RD"];
......
......@@ -187,7 +187,7 @@ export async function negotiationDelete(id:string) {
* @param contactDepartment 对接部门
* @returns 二维数组,第一行为表头,后续行为数据
*/
export async function outPutNegotiationData(name:string, industry:string[], registrationStatus:number, primaryContact:string, contactDepartment:string) {
export async function outPutNegotiationData(name:string, industry:string[], registrationStatus:number, primaryContact:string, contactDepartment:string, id:string[]) {
/** 拼接查询条件 */
let selectParam: any = {};
if (name) {
......@@ -207,6 +207,9 @@ export async function outPutNegotiationData(name:string, industry:string[], regi
if (contactDepartment) {
selectParam.contactDepartment = {"$regex": `${contactDepartment}`};
}
if (id) {
selectParam.id = {"$in": id};
}
/** 查询在谈在跟数据 */
let negotiationDbList = await negotiationData.findNegotiationListByParam(selectParam);
......@@ -219,7 +222,7 @@ export async function outPutNegotiationData(name:string, industry:string[], regi
"注册情况",
"负责人/首谈人",
"对接部门",
"创建时间"
// "创建时间"
];
/** 字段映射 */
......@@ -230,7 +233,7 @@ export async function outPutNegotiationData(name:string, industry:string[], regi
"registrationStatus",
"primaryContact",
"contactDepartment",
"createTime"
// "createTime"
];
let dataList = [titleList]; // 第一行为表头
......@@ -249,7 +252,7 @@ export async function outPutNegotiationData(name:string, industry:string[], regi
changeData.progressStatus = verificationEnumTools.changeEnumValue(configEnum.PROGRESSSTATUS, changeData.progressStatus) || "未选择";
/** 时间格式化 */
changeData.createTime = changeData.createTime ? moment(changeData.createTime).format("YYYY-MM-DD HH:mm:ss") : "-";
// changeData.createTime = changeData.createTime ? moment(changeData.createTime).format("YYYY-MM-DD HH:mm:ss") : "-";
/** 生成一行数据 */
let row = [];
......
......@@ -17,9 +17,9 @@ import { ERRORENUM } from "../config/errorEnum";
/**
* 政策-列表
* @param title 活动标题
* @param startTime 活动开始时间
* @param endTime 活动结束时间
* @param title 政策标题
* @param startTime 政策开始时间
* @param endTime 政策结束时间
* @param policyType 政策类型 财政补贴 资质申报 政策扶持
* @param page 页
*/
......@@ -29,15 +29,16 @@ export async function policyList(title:string, startTime:number, endTime:number,
selectParam.title = {"$regex":`${title}`};
}
if (startTime && endTime) {
selectParam.startTime = { "$gte": startTime };
selectParam.endTime = { "$lte": endTime };
// 条件:政策开始时间 <= 传入结束时间 且 政策结束时间 >= 传入开始时间
selectParam.startTime = { "$lte": endTime };
selectParam.endTime = { "$gte": startTime };
}
if (policyType) {
verificationEnumTools.eccEnumValue('管理后台获取政策列表', 'policyType', configEnum.POLICYTYPE, policyType);
selectParam.policyType = policyType;
}
/**需要用到的查询数据 */
let policyDbList = await policyData.findPolicyListToPage(selectParam, (page - 1) * 10);
let policyDbList = await policyData.findPolicyListToPageSort(selectParam, (page - 1) * 10, {createTime: -1});
let count = await policyData.findPolicyCount(selectParam);//符合查询条件的数据总数
/**组合返回结果 */
......@@ -78,6 +79,7 @@ export async function policyCreate(param) {
endTime: param.endTime,
source: param.source,
desc:param.desc,
createTime: new Date().valueOf(),
}
await policyData.createDataByParam(policyInfo);
......@@ -159,26 +161,29 @@ export async function policyDelete(id:string) {
* @param policyType 政策类型
* @returns 二维数组,第一行为表头,后续行为数据
*/
export async function outPutPolicyData(title: string, startTime: number, endTime: number, policyType: number) {
export async function outPutPolicyData(title: string, startTime: number, endTime: number, policyType: number, id: string[]) {
/** 拼接查询条件 */
let selectParam: any = {};
if (title) {
selectParam.title = { "$regex": `${title}` };
}
if (startTime && endTime) {
selectParam.startTime = { "$gte": startTime };
selectParam.endTime = { "$lte": endTime };
selectParam.startTime = { "$lte": endTime };
selectParam.endTime = { "$gte": startTime };
} else if (startTime) {
selectParam.startTime = { "$gte": startTime };
selectParam.startTime = { "$lte": endTime };
} else if (endTime) {
selectParam.endTime = { "$lte": endTime };
selectParam.endTime = { "$gte": startTime };
}
if (policyType) {
selectParam.policyType = policyType;
}
if (id) {
selectParam.id = {"$in": id};
}
/** 查询政策数据 */
let policyDbList = await policyData.findPolicyListByParam(selectParam);
let policyDbList = await policyData.findPolicyByParamSort(selectParam, {createTime: -1});
/** 表头定义 */
const titleList = [
......@@ -187,7 +192,7 @@ export async function outPutPolicyData(title: string, startTime: number, endTime
"生效时间",
"失效时间",
"政策来源",
"政策内容"
// "政策内容"
];
let dataList = [titleList]; // 第一行为表头
......@@ -216,7 +221,7 @@ export async function outPutPolicyData(title: string, startTime: number, endTime
changeData.startTime,
changeData.endTime,
changeData.source || "-",
descText
// descText
];
dataList.push(row);
......
/**
* 企查查数据同步
*/
import moment from "moment";
import * as configEnum from "../config/enum";
import * as enterpriseData from "../data/enterprise";
import * as labelData from "../data/label";
import * as enterpriseRiskData from "../data/enterpriseRisk";
import * as dishonestPersonData from "../data/dishonestPerson";
import * as illegalityData from "../data/illegality";
import * as qualificationsData from "../data/qualifications";
import { systemConfig } from "../config/serverConfig";
import { getQcc } from "../util/request";
import { formatAddress, randomId } from "../tools/system";
import { TABLEID } from "../config/enum/dbEnum";
import { LABELGOAL, LABELTYPE } from "../config/enum/labelEnum";
const md5 = require("md5");
/**
* 接口更新
* 设置定时器,每天刷新一次数据
*/
export async function initApiDataStorage() {
updateQCCDataTask();
setInterval(async function () {
updateQCCDataTask();
}, 3600 * 1000 * 24);
}
/**
* 同步企查查数据
* 逻辑:获取数据库所有企业uscc,进行企查查数据同步
*/
export async function updateQCCDataTask() {
let enterpriseList = await enterpriseData.findEnterpriseListByParam({isSettled: configEnum.STATE.});
console.log(`开始同步企查查数据,${moment(new Date().valueOf()).format("YYYY-MM-DD HH:mm:ss")}:本次同步同${enterpriseList.length}家`);
for (let i = 0; i < enterpriseList.length; i++) {
let info = enterpriseList[i];
await updateItemQCCData(info.uscc, info.name);
console.log(`下标 ${i} => name:${info.name},uscc:${info.uscc}`);
}
console.log(`${enterpriseList.length}家企业同步成功`);
}
/**
* 更新单个企业
* @param uscc
* @param name
*/
export async function updateItemQCCData(uscc, name) {
await 工商信息(uscc);
await 准入尽职调查(uscc);
await 失信核查(uscc);
await 严重违法核查(uscc);
await 科创分(uscc);
await 资质证书查询(uscc);
//"91310114MA1GY5G71E"
}
/**
* 封装了一个请求方法
* @param uscc
* @returns
*/
function getReqParam(uscc, isKeyNo?) {
const TimeSpan = Math.round(new Date().valueOf()/ 1000);
let header = {
Token:md5(`${systemConfig.qccKey}${TimeSpan}${systemConfig.qccSecretKey}`).toUpperCase(),
Timespan:TimeSpan
};
let query:any = {};
if (isKeyNo == "isKeyNo") {
query = {
key:systemConfig.qccKey,
keyNo:uscc,
};
} else if (isKeyNo == "Id") {
query = {
key:systemConfig.qccKey,
id:uscc,
};
} else if (isKeyNo == "certId") {
query = {
key:systemConfig.qccKey,
certId:uscc,
};
} else if (isKeyNo == "企业名称") {
query = {
key:systemConfig.qccKey,
keyword:uscc,
}
} else {
query = {
key:systemConfig.qccKey,
searchKey:uscc,
// keyNo:"云合智网(上海)技术有限公司"
};
}
return {header, query};
}
/**
* 同步工商信息数据
* @param uscc
* @param eId
* @returns
*/
async function 工商信息(uscc) {
let {header, query} = getReqParam(uscc);
let 工商信息:any = await getQcc('https://api.qichacha.com/ECIInfoVerify/GetInfo', query, header);//获取工商信息
if (Object.keys(工商信息).length) {
let enterInfo = await enterpriseData.findEnterpriseByUscc(uscc);
let khsfsb = getReqParam(uscc);
let 客户身份识别:any = await getQcc('https://api.qichacha.com/CustomerDueDiligence/KYC', khsfsb.query, khsfsb.header);//获取工商信息
let TermEnd = "无固定期限";
if (工商信息.TermEnd) TermEnd = moment(工商信息.TermEnd).format("YYYY-MM-DD");
if (工商信息.OperName) {
enterInfo.legalPerson = 工商信息.OperName;
}
//企业基础信息
let guanWang = "";
if (工商信息.ContactInfo &&工商信息.ContactInfo.WebSite && 工商信息.ContactInfo.WebSite[0]) {
enterInfo.guanWang = 工商信息.ContactInfo.WebSite[0].Url || "";
}
if (客户身份识别.Data && 客户身份识别.Data.Scale) {
switch (客户身份识别.Data.Scale) {
case "L": enterInfo.qiYeGuiMo = configEnum.ENTERPRISESIZE.大型; break;
case "M": enterInfo.qiYeGuiMo = configEnum.ENTERPRISESIZE.中型; break;
case "S": enterInfo.qiYeGuiMo = configEnum.ENTERPRISESIZE.小型; break;
case "XS": enterInfo.qiYeGuiMo = configEnum.ENTERPRISESIZE.微型; break;
}
}
if (工商信息.Address) {
let logonAddressList = formatAddress(工商信息.Address); //解析注册地址
enterInfo.logonAddress = logonAddressList;
}
enterInfo.zhuCeHao = 工商信息.No;
enterInfo.zuZhiJiGouDaiMa = 工商信息.OrgNo;
enterInfo.logonTime = new Date(工商信息.StartDate).valueOf();
if (!enterInfo.jingYingFanWei) enterInfo.jingYingFanWei = 工商信息.Scope; //经营范围
/**
* 股权结构
*/
if (工商信息.Partners) {
let ownershipList = [];
工商信息.Partners.forEach(info => {
let addInfo:any = {
name:info.StockName,
finalBenefitPercent:info.FinalBenefitPercent,
stockPercent:info.StockPercent,
stockType:info.StockType,
realCapi:info.RealCapi,
paidUpCapitalUnit:info.PaidUpCapitalUnit,
subscribedCapital:info.SubscribedCapital,
subscribedCapitalUnit:info.SubscribedCapitalUnit,
};
// if (info.CapiDate) addInfo.capiDate = getMySqlMs(info.CapiDate);
// if (info.ShoudDate) addInfo.shoudDate = getMySqlMs(info.ShoudDate);
ownershipList.push(addInfo);
});
enterInfo.guQuanJieGou = ownershipList;
}
/**
* 企业标签表
*/
if (工商信息.TagList) {
for (let i = 0; i < 工商信息.TagList.length; i++) {
let info = 工商信息.TagList[i];
let {Type, Name} = info;
if (Name == "曾用名") continue
let labelInfo = await labelData.selectLabelOne({labelName:Name});
if (!labelInfo || !labelInfo.id) {
//添加
labelInfo = {
id:LABELTYPE.自定义标签,
labelName:Name,
ctMs:new Date().valueOf(),
goal:LABELGOAL.企业,
labelType:LABELTYPE.自定义标签, //todo
state:false
};
await labelData.createOneLabel(labelInfo);
}
let thisEnterpriseHaveLabel = false;
enterInfo.labels.forEach(itemLabelInfo => {
if (itemLabelInfo.labelId == labelInfo.id) thisEnterpriseHaveLabel = true;
})
if (!thisEnterpriseHaveLabel) enterInfo.labels.push({labelId:labelInfo.id, labelType:LABELTYPE.自定义标签, state:true});
}
}
await enterInfo.save();
} else {
console.log(`企查查获取不到该企业数据:${uscc}`);
}
}
/**
* 准入尽职调查
* 逻辑:增量更新
* @param uscc
* @returns
*/
async function 准入尽职调查(uscc) {
let enterpriseInfo = await enterpriseData.findEnterpriseByUscc(uscc);
let {header, query} = getReqParam(uscc);
let qccselectdata:any = await getQcc('https://api.qichacha.com/AcctScan/GetInfo', query, header);
if (qccselectdata.Data) {
for (let i = 0; i < qccselectdata.Data.length; i++) {
let info = qccselectdata.Data[i];
let item = await enterpriseRiskData.findOnce({uscc, title:info.Title});
if (!item || !item.id) {
let addInfo:any = {
id:randomId(TABLEID.准入尽职调查),
uscc,
enterpriseName:enterpriseInfo.name,
title:info.Title,
description:info.Description,
passage:info.Passage,
riskType:info.RiskType,
};
if (info.TypeCode) addInfo.typeCode = parseInt(info.TypeCode);
await enterpriseRiskData.createDataByParam(addInfo);
}
}
}
}
/**
* 失信核查
* 逻辑:全量更新 删除之前所有的 再添加
* @param uscc
* @returns
*/
async function 失信核查(uscc) {
let enterpriseInfo = await enterpriseData.findEnterpriseByUscc(uscc);
let {header, query} = getReqParam(uscc);
let qccselectdata:any = await getQcc('https://api.qichacha.com/ShixinCheck/GetList', query, header);
await dishonestPersonData.removeMany({uscc});
if (qccselectdata.Data) {
let addList = [];
qccselectdata.Data.forEach(info => {
let addInfo:any = {
id:randomId(TABLEID.失信核查),
uscc,
enterpriseName:enterpriseInfo.name,
anno:info.Anno,
executegov:info.Executegov,
executestatus:info.Executestatus,
executeno:info.Executeno,
actionRemark:info.ActionRemark,
amount:info.Amount,
};
addList.push(addInfo);
});
await dishonestPersonData.addMany(addList);
}
}
/**
* 严重违法核查
* 逻辑:全量更新 删除之前所有的 再添加
* @param uscc
* @returns
*/
async function 严重违法核查(uscc) {
let enterpriseInfo = await enterpriseData.findEnterpriseByUscc(uscc);
let {header, query} = getReqParam(uscc);
let qccselectdata:any = await getQcc('https://api.qichacha.com/SeriousIllegalCheck/GetList', query, header);
await illegalityData.removeMany({uscc});
if (qccselectdata.Data) {
let addList = [];
qccselectdata.Data.forEach(info => {
let addInfo:any = {
id:randomId(TABLEID.严重违法核查),
uscc,
enterpriseName:enterpriseInfo.name,
type:info.Type,
addReason:info.AddReason,
addOffice:info.AddOffice,
removeReason:info.RemoveReason,
removeOffice:info.RemoveOffice,
};
addList.push(addInfo);
});
await illegalityData.addMany(addList);
}
}
/**
* 科创分
* 有则更新,无则添加
* @param uscc
* @returns
*/
async function 科创分(uscc) {
let enterpriseInfo = await enterpriseData.findEnterpriseByUscc(uscc);
let {header, query} = getReqParam(uscc);
let qccselectdata:any = await getQcc('https://api.qichacha.com/TechScore/GetInfo', query, header);
if (qccselectdata.Data) {
let kcf = {
industry:qccselectdata.Data.Industry.Industry,
subIndustry:qccselectdata.Data.Industry.SubIndustry,
industryRanking:qccselectdata.Data.IndustryRanking,
score:qccselectdata.Data.Score,
};
enterpriseInfo.kcf = kcf;
}
}
async function 资质证书详情查询(id) {
let {header, query} = getReqParam(id, "certId");
let qccselectdata:any = await getQcc('https://api.qichacha.com/ECICertification/GetCertificationDetailById', query, header);
return qccselectdata;
}
async function 资质证书查询(uscc) {
let enterpriseInfo = await enterpriseData.findEnterpriseByUscc(uscc);
let {header, query} = getReqParam(uscc);
let qccselectdata:any = await getQcc('https://api.qichacha.com/ECICertification/SearchCertification', query, header);
await qualificationsData.removeMany({uscc});
if (Array.isArray(qccselectdata)) {
let addList = [];
for (let i = 0; i < qccselectdata.length; i++) {
let qcc资质证书详情 = {};
let info = qccselectdata[i];
let qcc资质证书Id = info.Id;
qccselectdata[i]["qcc资质证书详情"] = await 资质证书详情查询(qcc资质证书Id);
}
qccselectdata.forEach(info => {
let addInfo:any = {
uscc,
enterpriseName:enterpriseInfo.name,
id:randomId('qua'),
name:info.Name,
type:info.Type,
no:info.No,
typeDesc:info.TypeDesc,
institutionList:info.InstitutionList ? info.InstitutionList[0] :"",
status:info.Status,
};
if (info.StartDate) addInfo.startDate = new Date(info.StartDate).valueOf();
if (info.EndDate) addInfo.endDate = new Date(info.EndDate).valueOf();
addList.push(addInfo);
});
await qualificationsData.addMany( addList);
}
return qccselectdata;
}
......@@ -9,32 +9,105 @@ import * as labelData from "../data/label";
import * as enterpriseRiskData from "../data/enterpriseRisk";
import * as dishonestPersonData from "../data/dishonestPerson";
import * as illegalityData from "../data/illegality";
import * as manageData from "../data/manage";
import * as qualificationsData from "../data/qualifications";
import { systemConfig } from "../config/serverConfig";
import { getQcc } from "../util/request";
import { formatAddress, randomId } from "../tools/system";
import { TABLEID } from "../config/enum/dbEnum";
import { LABELGOAL, LABELTYPE } from "../config/enum/labelEnum";
import { ENTERPRISESYSTEMLABEL, LABELGOAL, LABELTYPE } from "../config/enum/labelEnum";
const md5 = require("md5");
// 批次大小配置
const BATCH_SIZE = 100; // 每批次处理企业数量
const BATCH_INTERVAL = 5 * 60 * 1000; // 批次间隔时间:5分钟
/**
* 接口更新
* 设置定时器,分批刷新数据
*/
export async function initApiDataStorage() {
updateQCCDataTask();
setInterval(async function () {
updateQCCDataTask();
}, 3600 * 1000 * 24); // 每天启动一次完整的数据同步
}
/**
* 同步企查查数据
* 逻辑:获取数据库所有企业uscc,进行企查查数据同步
* 逻辑:分批次获取数据库所有企业uscc,进行企查查数据同步
*/
export async function updateQCCDataTask() {
let enterpriseList = await enterpriseData.findEnterpriseListByParam({isSettled: configEnum.STATE.});
console.log(`开始同步企查查数据,${moment(new Date().valueOf()).format("YYYY-MM-DD HH:mm:ss")}:本次同步同${enterpriseList.length}家`);
for (let i = 0; i < enterpriseList.length; i++) {
let info = enterpriseList[i];
try {
// 获取所有需要同步的企业
let enterpriseList = await enterpriseData.findEnterpriseListByParam({isSettled: configEnum.STATE., labels:{"$elemMatch":{labelId:{"$in":ENTERPRISESYSTEMLABEL["3.73平方公里"]} } }});
const totalCount = enterpriseList.length;
console.log(`开始同步企查查数据,${moment(new Date().valueOf()).format("YYYY-MM-DD HH:mm:ss")}:本次同步共${totalCount}家企业,将分${Math.ceil(totalCount/BATCH_SIZE)}批进行同步`);
// 分批处理企业数据
for (let batchIndex = 0; batchIndex < Math.ceil(totalCount/BATCH_SIZE); batchIndex++) {
const startIndex = batchIndex * BATCH_SIZE;
const endIndex = Math.min(startIndex + BATCH_SIZE, totalCount);
const batchList = enterpriseList.slice(startIndex, endIndex);
console.log(`开始处理第${batchIndex + 1}批数据,企业数量:${batchList.length},时间:${moment().format("HH:mm:ss")}`);
// 处理当前批次的所有企业
await processBatch(batchList, batchIndex);
// 如果不是最后一批,等待指定的时间间隔
if (endIndex < totalCount) {
console.log(`第${batchIndex + 1}批处理完成,等待5分钟后处理下一批...`);
await sleep(BATCH_INTERVAL);
}
}
console.log(`所有${totalCount}家企业数据同步完成`);
} catch (error) {
console.error(`同步企查查数据时发生错误:`, error);
}
}
/**
* 处理单个批次的企业数据
* @param batchList 当前批次的企业列表
* @param batchIndex 批次索引
*/
async function processBatch(batchList, batchIndex) {
const results = [];
const errors = [];
// 使用传统的 Promise 链处理
for (let i = 0; i < batchList.length; i++) {
const info = batchList[i];
try {
await updateItemQCCData(info.uscc, info.name);
console.log(`批次${batchIndex + 1},企业${i + 1}/${batchList.length} => name:${info.name},uscc:${info.uscc}`);
results.push({ success: true, uscc: info.uscc, name: info.name });
} catch (error) {
console.error(`批次${batchIndex + 1},处理企业${info.name}(${info.uscc})时出错:`, error);
results.push({ success: false, uscc: info.uscc, name: info.name, error: error.message });
errors.push({ uscc: info.uscc, name: info.name, error: error.message });
}
}
const successCount = results.filter(r => r.success).length;
const failedCount = results.length - successCount;
console.log(`批次${batchIndex + 1}处理完成,成功:${successCount},失败:${failedCount}`);
console.log(`下标 ${i} => name:${info.name},uscc:${info.uscc}`);
if (errors.length > 0) {
console.log(`批次${batchIndex + 1}失败的企业:`, errors);
}
console.log(`${enterpriseList.length}家企业同步成功`);
}
/**
* 睡眠函数
* @param ms 毫秒数
*/
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
/**
* 更新单个企业
......@@ -43,6 +116,7 @@ export async function updateQCCDataTask() {
*/
export async function updateItemQCCData(uscc, name) {
await 工商信息(uscc);
await 年报同步经营数据(uscc);
await 准入尽职调查(uscc);
await 失信核查(uscc);
await 严重违法核查(uscc);
......@@ -104,7 +178,6 @@ function getReqParam(uscc, isKeyNo?) {
*/
async function 工商信息(uscc) {
let {header, query} = getReqParam(uscc);
let 工商信息:any = await getQcc('https://api.qichacha.com/ECIInfoVerify/GetInfo', query, header);//获取工商信息
if (Object.keys(工商信息).length) {
let enterInfo = await enterpriseData.findEnterpriseByUscc(uscc);
......@@ -177,15 +250,16 @@ async function 工商信息(uscc) {
let info = 工商信息.TagList[i];
let {Type, Name} = info;
if (Name == "曾用名") continue
/**添加标签表 */
let labelInfo = await labelData.selectLabelOne({labelName:Name});
if (!labelInfo || !labelInfo.id) {
//添加
labelInfo = {
id:LABELTYPE.自定义标签,
id:randomId(TABLEID.企业标签表), //todo
labelName:Name,
ctMs:new Date().valueOf(),
goal:LABELGOAL.企业,
labelType:LABELTYPE.自定义标签, //todo
labelType:LABELTYPE.自定义标签,
state:false
};
......@@ -193,17 +267,22 @@ async function 工商信息(uscc) {
}
let thisEnterpriseHaveLabel = false;
/**添加企业标签 */
enterInfo.labels.forEach(itemLabelInfo => {
if (itemLabelInfo.labelId == labelInfo.id) thisEnterpriseHaveLabel = true;
})
if (!thisEnterpriseHaveLabel) enterInfo.labels.push({labelId:labelInfo.id, labelType:LABELTYPE.自定义标签, state:true});
if (!thisEnterpriseHaveLabel) {
enterInfo.labels.push({
labelId:labelInfo.id,
labelType:LABELTYPE.自定义标签,
state:true
});
}
}
}
await enterInfo.save();
} else {
console.log(`企查查获取不到该企业数据:${uscc}`);
}
......@@ -211,6 +290,72 @@ async function 工商信息(uscc) {
/**
* 年报同步经营数据
* @param uscc
*/
async function 年报同步经营数据(uscc) {
let {query, header} = getReqParam(uscc, "isKeyNo");
let 年报信息:any = await getQcc('https://api.qichacha.com/AR/GetAnnualReport', query, header); //获取公司年报信息
for (let i = 0; i < 年报信息.length; i++) {
let this年报 = 年报信息[i];
let PublishDate = moment(this年报.PublishDate).format('YYYY');
let manageInfo = await manageData.findManageListByParam({uscc, year:PublishDate});
let enterInfo = await enterpriseData.findEnterpriseByUscc(uscc);
if (manageInfo.length <= 0) {
if (this年报.AssetsData.GrossTradingIncome != "企业选择不公示" && this年报.AssetsData.TotalTaxAmount != "企业选择不公示") {
// 处理营业收入:从字符串中提取数字部分
let BIStr = this年报.AssetsData.GrossTradingIncome; // "42372.210275万元"
let BI = 0; //营业收入(万元)
if (BIStr && typeof BIStr === 'string') {
// 使用正则表达式提取数字部分(包括小数点)
let numMatch = BIStr.match(/[\d\.]+/);
if (numMatch && numMatch[0]) {
BI = parseFloat(numMatch[0]);
}
}
// 企查查只有纳税总额,没有分开的企业所得税和个人所得税
// let CITStr = this年报.AssetsData.TotalTaxAmount; // "企业选择不公示" 或 "1234.56万元"
// let CIT = 0; //企业所得税(万元)
// if (CITStr && typeof CITStr === 'string' && CITStr !== "企业选择不公示") {
// let numMatch = CITStr.match(/[\d\.]+/);
// if (numMatch && numMatch[0]) {
// CIT = parseFloat(numMatch[0]);
// }
// }
let CIT = 0; //企业所得税(万元)
let VAT = 0; //企业增值税(万元)
let PIT = 0; //个人所得税(万元)
let RD = 0; //研发投入(万元)
let manageInfo = {
id: randomId(TABLEID.企业经营数据),
uscc: uscc,
name: enterInfo.name,
year: PublishDate,
period: configEnum.PERIOD.全年,
BI,
VAT,
CIT,
PIT,
RD,
isSubmit:true,
createTime:new Date().valueOf(),
}
await manageData.createDataByParam(manageInfo);
console.log(`企业${uscc}同步营业收入数据成功`)
}
}
}
}
/**
* 准入尽职调查
* 逻辑:增量更新
* @param uscc
......@@ -402,5 +547,3 @@ async function 资质证书查询(uscc) {
......@@ -382,7 +382,7 @@ export async function trackDelete(id:string) {
* @param trackType 需求跟进状态
* @returns 二维数组,第一行为表头,后续行为数据(空行分隔)
*/
export async function outPutTrackDetailsData(name: string, demand: number, trackType: number) {
export async function outPutTrackDetailsData(name: string, demand: number, trackType: number, id:string[]) {
/** 拼接查询条件 */
let selectParam: any = {};
if (name) {
......@@ -394,6 +394,9 @@ export async function outPutTrackDetailsData(name: string, demand: number, track
if (trackType) {
selectParam.trackType = trackType;
}
if (id) {
selectParam.id = {"$in": id};
}
/** 查询服务追踪数据 */
let trackDbList = await trackData.findTrackListByParam(selectParam);
......
......@@ -87,7 +87,7 @@ export const EnterpriseUpdateConfig = {
labels:{type:"[String]"}, //企业标签
industry:{type:"[Number]"}, //行业领域
property:{type:"Number"}, //企业所属物业
enterpriseNature:{type:"Number"}, //企业性质
enterpriseNature:{type:"String"}, //企业性质
leasedArea:{type:"Number"}, //租赁面积(㎡)
RAS:{type:"Number"}, //登记状态
jingYingFanWei:{type:"String"}, //经营范围
......@@ -147,7 +147,7 @@ export const TrackAddConfig = {
contactUs:{type:"String"}, //企业联系方式
// trackType:{type:"Number"}, //需求跟进状态 同步详情记录的跟进状态
createTime:{type:"Number"}, //创建服务追踪时间
details:{type:"Array"}, //服务追踪记录
details:{type:"Array", notMustHave:true}, //服务追踪记录
};
......@@ -178,7 +178,7 @@ export const TrackUpdateConfig = {
contactUs:{type:"String"}, //企业联系方式
// trackType:{type:"Number"}, //需求跟进状态 同步详情记录的跟进状态
createTime:{type:"Number"}, //创建服务追踪时间
details:{type:"Array"}, //服务追踪记录
details:{type:"Array", notMustHave:true}, //服务追踪记录
};
......@@ -202,7 +202,7 @@ export const TrackDetailsUpdateConfig = {
*/
export const ActivityAddConfig = {
title:{type:"String"}, //活动标题
state:{type:"Number"}, //活动状态
// state:{type:"Number"}, //活动状态
startTime:{type:"Number"}, //活动开始时间
endTime:{type:"Number"}, //活动结束时间
target:{type:"[Number]"}, //活动类型
......@@ -218,7 +218,7 @@ export const ActivityAddConfig = {
*/
export const ActivityUpdateConfig = {
title:{type:"String"}, //活动标题
state:{type:"Number"}, //活动状态
// state:{type:"Number"}, //活动状态
startTime:{type:"Number"}, //活动开始时间
endTime:{type:"Number"}, //活动结束时间
target:{type:"[Number]"}, //活动类型
......
......@@ -2,8 +2,6 @@
* 事件标签枚举
*
*/
export enum LABELTYPE {
基础标签 = 1,
入驻年份 = 2,
......@@ -13,7 +11,6 @@ export enum LABELTYPE {
}
/**
* 企业系统标签
*/
......
......@@ -81,7 +81,10 @@ export enum ERRORENUM {
该账号已存在,
该标签不存在,
该活动已存在,
该政策已存在
该政策已存在,
企业性质不可多选,
所属物业不可多选,
入驻年份不可多选
}
export enum ERRORCODEENUM {
......
......@@ -39,6 +39,9 @@ export const enterpriseListConfig = {
zhuceziben:{key:"注册资本"},
property:{key:"所属物业"},
enterpriseNature:{key:"企业性质"},
logonAddress:{key:"注册地址"},
legalPerson:{key:"法人"},
dianHua:{key:"联系电话"},
};
......
......@@ -8,7 +8,7 @@ import {sasp} from '../db/mongo/dbInit';
const activitySchema = new Schema({
id:{type:String, index:true}, //唯一标识
title:String, //活动标题
state:{type:Number, default:1}, //活动状态 未开始、活动中、已结束
// state:{type:Number, default:1}, //活动状态 未开始、活动中、已结束 -- 移除state字段,根据startTime和endTime动态计算状态
startTime:Number, //活动开始时间
endTime:Number, //活动结束时间
target:{type:[Number], default:[]}, //活动类型
......
......@@ -161,6 +161,17 @@ export async function save(throwError=false) {
/**
* 分页获取所有企业-排序
* @param selectParam 查询参数
* @param skipCount 跳过数量
* @returns [] 在跟在谈企业列表
*/
export async function findEnterpriseListToPageSort(selectParam, skipCount, sortParam) {
return await enterpriseModel.find(selectParam).sort(sortParam).skip(skipCount).limit(10);
}
/**
* 分页获取所有企业
* @param selectParam 查询参数
* @param skipCount 跳过数量
......@@ -202,6 +213,15 @@ export async function findEnterpriseListByParam(selectParam) {
/**
* 获取按时间排序的符合条件的企业列表
* @param selectParam
*/
export async function findEnterpriseListByParamSort(selectParam, sortParam) {
return await enterpriseModel.find(selectParam).sort(sortParam);
}
/**
* 获取符合条件的单个企业
* @param selectParam
*/
......
......@@ -56,6 +56,17 @@ export async function findManageListToPage(selectParam, skipCount) {
/**
* 分页获取所有经营数据
* @param selectParam 查询参数
* @param skipCount 跳过数量
* @returns [] 经营数据列表
*/
export async function findManageListToPageSort(selectParam, skipCount, sortParam) {
return await manageModel.find(selectParam).sort(sortParam).skip(skipCount).limit(10);
}
/**
* 获取符合条件的经营数据数量
* @param selectParam 查询参数
* @returns number 数据数量
......
......@@ -14,6 +14,7 @@ const policySchema = new Schema({
endTime:Number, //政策结束时间
source:String, //来源,发布单位
desc:String, //政策详情
createTime:Number, //创建时间
})
......@@ -43,7 +44,7 @@ export async function save(throwError=false) {
* 分页获取所有政策
* @param selectParam 查询参数
* @param skipCount 跳过数量
* @returns [] 在跟在谈政策列表
* @returns [] 政策列表
*/
export async function findPolicyListToPage(selectParam, skipCount) {
return await policyModel.find(selectParam).skip(skipCount).limit(10);
......@@ -51,6 +52,17 @@ export async function findPolicyListToPage(selectParam, skipCount) {
/**
* 分页获取所有政策-排序
* @param selectParam 查询参数
* @param skipCount 跳过数量
* @returns [] 政策列表
*/
export async function findPolicyListToPageSort(selectParam, skipCount, sortParam) {
return await policyModel.find(selectParam).sort(sortParam).skip(skipCount).limit(10);
}
/**
* 获取符合条件的政策数量
* @param selectParam 查询参数
* @returns number 数据数量
......@@ -70,6 +82,15 @@ export async function findPolicyByParam(selectParam) {
/**
* 获取符合条件的政策
* @param selectParam
*/
export async function findPolicyByParamSort(selectParam, sortParam) {
return await policyModel.find(selectParam).sort(sortParam);
}
/**
* 获取符合条件的政策列表
* @param selectParam
*/
......
import { updateQCCDataTask } from "./biz/qccInit";
import { initApiDataStorage } from "./biz/qccInit";
import { initConfig, systemConfig} from "./config/serverConfig";
import { initDB } from "./db/mongo/dbInit";
import { httpServer } from "./net/http_server";
......@@ -10,14 +10,13 @@ async function lanuch() {
/**初始化数据库 */
await initDB();
/**初始化底表数据 */
// await initBasicData();
await initBasicData();
/**创建http服务 */
httpServer.createServer(systemConfig.port);
console.log('This indicates that the server is started successfully.');
/**初始化企查查数据 */
// await updateQCCDataTask();
await initApiDataStorage();
}
......
......@@ -5,7 +5,7 @@ import compression = require('compression');
import { watch } from '../middleware/watch';
import { httpErrorHandler } from '../middleware/httpErrorHandler';
import * as path from "path";
// import * as fallback from 'express-history-api-fallback';
import fallback from 'express-history-api-fallback';
export class httpServer {
static createServer(port:number) {
......@@ -34,7 +34,7 @@ export class httpServer {
httpServer.use(express.static("./files") );
const root = path.join(__dirname, "../../public");
httpServer.use(express.static(root));
// httpServer.use(fallback('index.html', { root }));
httpServer.use(fallback('index.html', { root }));
httpServer.use(compression());
httpServer.use(watch);
httpServer.use(bodyParser.json({limit:"5000kb"}));
......
......@@ -94,11 +94,11 @@ async function delActivity(req, res) {
* @param res
*/
async function outPutActivityList(req, res) {
let reqConf = {title:'String', startTime:'Number', endTime:'Number', target:'[Number]', state:'Number'};
const NotMustHaveKeys = ['title', 'startTime', 'endTime', 'target', 'state'];
let {title, startTime, endTime, target, state} = eccReqParamater(reqConf, req.body, NotMustHaveKeys);
let reqConf = {title:'String', startTime:'Number', endTime:'Number', target:'[Number]', state:'Number', id:'[String]'};
const NotMustHaveKeys = ['title', 'startTime', 'endTime', 'target', 'state', 'id'];
let {title, startTime, endTime, target, state, id} = eccReqParamater(reqConf, req.body, NotMustHaveKeys);
let result = await activityBiz.outPutActivityData(title, startTime, endTime, target, state);
let result = await activityBiz.outPutActivityData(title, startTime, endTime, target, state, id);
res.success(result);
}
......
......@@ -94,11 +94,11 @@ async function delEnterprise(req, res) {
* @param res
*/
async function outPutEnterprise(req, res) {
let reqConf = {name:'String', industry:'[Number]', parkEntryTime:'Number', logonTime:'Number', labelIdList:'[String]', dataType:'Number'};
const NotMustHaveKeys = ['name', 'industry', 'parkEntryTime', 'logonTime', 'labelIdList', 'dataType'];
let {name, industry, parkEntryTime, logonTime, labelIdList, dataType} = eccReqParamater(reqConf, req.body, NotMustHaveKeys);
let reqConf = {name:'String', industry:'[Number]', parkEntryTime:'Number', logonTime:'Number', labelIdList:'[String]', dataType:'Number', uscc:'[String]'};
const NotMustHaveKeys = ['name', 'industry', 'parkEntryTime', 'logonTime', 'labelIdList', 'dataType', 'uscc'];
let {name, industry, parkEntryTime, logonTime, labelIdList, dataType, uscc} = eccReqParamater(reqConf, req.body, NotMustHaveKeys);
let result = await enterpriseBiz.outPutEnterpriseData(name, industry, parkEntryTime, logonTime, labelIdList, dataType);
let result = await enterpriseBiz.outPutEnterpriseData(name, industry, parkEntryTime, logonTime, labelIdList, dataType, uscc);
res.success(result);
}
......
......@@ -94,11 +94,11 @@ async function delManage(req, res) {
* @param res
*/
async function outPutManageList(req, res) {
let reqConf = {name:'String', year:'Number', period:'Number'};
const NotMustHaveKeys = ['name', 'year', 'period'];
let {name, year, period} = eccReqParamater(reqConf, req.body, NotMustHaveKeys);
let reqConf = {name:'String', year:'Number', period:'Number', id:'[String]'};
const NotMustHaveKeys = ['name', 'year', 'period', 'id'];
let {name, year, period, id} = eccReqParamater(reqConf, req.body, NotMustHaveKeys);
let result = await manageBiz.outPutManageData(name, year, period);
let result = await manageBiz.outPutManageData(name, year, period, id);
res.success(result);
}
......
......@@ -89,16 +89,16 @@ async function delNegotiation(req, res) {
/**
* 在谈在跟-列表
* 在谈在跟-导出
* @param req
* @param res
*/
async function outPutNegotiation(req, res) {
let reqConf = {name:'String', industry:'[Number]', registrationStatus:'Number', primaryContact:'String', contactDepartment:'String'};
const NotMustHaveKeys = ['name', 'industry', 'registrationStatus', 'primaryContact', 'contactDepartment'];
let {name, industry, registrationStatus, primaryContact, contactDepartment} = eccReqParamater(reqConf, req.body, NotMustHaveKeys);
let reqConf = {name:'String', industry:'[Number]', registrationStatus:'Number', primaryContact:'String', contactDepartment:'String', id:'[String]'};
const NotMustHaveKeys = ['name', 'industry', 'registrationStatus', 'primaryContact', 'contactDepartment', 'id'];
let {name, industry, registrationStatus, primaryContact, contactDepartment, id} = eccReqParamater(reqConf, req.body, NotMustHaveKeys);
let result = await negotiationBiz.outPutNegotiationData(name, industry, registrationStatus, primaryContact, contactDepartment);
let result = await negotiationBiz.outPutNegotiationData(name, industry, registrationStatus, primaryContact, contactDepartment, id);
res.success(result);
}
......
......@@ -94,11 +94,11 @@ async function delPolicy(req, res) {
* @param res
*/
async function outPutPolicyList(req, res) {
let reqConf = {title:'String', startTime:'Number', endTime:'Number', policyType:'Number'};
const NotMustHaveKeys = ['title', 'startTime', 'endTime', 'policyType'];
let {title, startTime, endTime, policyType} = eccReqParamater(reqConf, req.body, NotMustHaveKeys);
let reqConf = {title:'String', startTime:'Number', endTime:'Number', policyType:'Number', id:'[String]'};
const NotMustHaveKeys = ['title', 'startTime', 'endTime', 'policyType', 'id'];
let {title, startTime, endTime, policyType, id} = eccReqParamater(reqConf, req.body, NotMustHaveKeys);
let result = await policyBiz.outPutPolicyData(title, startTime, endTime, policyType);
let result = await policyBiz.outPutPolicyData(title, startTime, endTime, policyType, id);
res.success(result);
}
......
......@@ -109,11 +109,11 @@ async function delTrack(req, res) {
* @param res
*/
async function outPutTrackList(req, res) {
let reqConf = {name:'String', demand:'Number', trackType:'Number'};
const NotMustHaveKeys = ['name', 'demand', 'trackType'];
let {name, demand, trackType} = eccReqParamater(reqConf, req.body, NotMustHaveKeys);
let reqConf = {name:'String', demand:'Number', trackType:'Number', id:'[String]'};
const NotMustHaveKeys = ['name', 'demand', 'trackType', 'id'];
let {name, demand, trackType, id} = eccReqParamater(reqConf, req.body, NotMustHaveKeys);
let result = await trackBiz.outPutTrackDetailsData(name, demand, trackType);
let result = await trackBiz.outPutTrackDetailsData(name, demand, trackType, id);
res.success(result);
}
......
......@@ -10,6 +10,7 @@ import * as labelEnum from "../config/enum/labelEnum";
import { createDataByParam, findEnterpriseByUscc } from "../data/enterprise";
import { formatAddress, getPwdMd5, randomId } from "./system";
import { TABLEID } from "../config/enum/dbEnum";
import moment from "moment";
let xlsx = require('node-xlsx');
let path = require('path');
let md5 = require("md5");
......@@ -151,6 +152,7 @@ function parseIndustry(industryCategoryGb, industryMajorGb) {
};
}
/**
* 处理日期字符串
* @param {string} dateStr
......@@ -160,8 +162,36 @@ function parseDateString(dateStr) {
if (!dateStr || dateStr === '-') return null;
try {
// 处理"2024年"格式的日期
if (typeof dateStr === 'string' && dateStr.includes('年')) {
// 提取年份数字,例如:"2024年" -> 2024
const yearMatch = dateStr.match(/(\d{4})年/);
if (yearMatch && yearMatch[1]) {
const year = parseInt(yearMatch[1], 10);
// 返回该年份1月1日的时间戳
return new Date(`${year}-01-01`).getTime();
}
}
// 处理Excel日期格式(如:2020-07-16)
if (typeof dateStr === 'string') {
// 尝试多种日期格式
const dateFormats = [
'YYYY-MM-DD',
'YYYY/MM/DD',
'YYYY年MM月DD日',
'YYYY-MM',
'YYYY年'
];
for (const format of dateFormats) {
const parsedDate = moment(dateStr, format, true);
if (parsedDate.isValid()) {
return parsedDate.valueOf();
}
}
// 如果上述格式都不匹配,尝试原生Date解析
let date = new Date(dateStr);
return isNaN(date.getTime()) ? null : date.getTime();
}
......@@ -179,6 +209,7 @@ function parseDateString(dateStr) {
}
}
/**
* 处理注册资本和实缴资本
* @param {string} capitalStr
......@@ -192,6 +223,7 @@ function parseCapital(capitalStr) {
return match ? match[1] + '万元' : capitalStr;
}
/**
* 处理参保人数
* @param {string|number} peopleStr
......@@ -208,6 +240,7 @@ function parsePeopleCount(peopleStr) {
return isNaN(num) ? 0 : num;
}
/**
* 处理租赁面积
* @param {string|number} areaStr
......@@ -224,6 +257,7 @@ function parseLeasedArea(areaStr) {
return isNaN(num) ? 0 : num;
}
/**
* 处理数字字段
*/
......@@ -240,6 +274,7 @@ function parseNumber(value, defaultValue = 0) {
return isNaN(num) ? defaultValue : num;
}
/**
* 处理企业标签
* @param {Object} rowData Excel行数据
......@@ -295,22 +330,22 @@ function parseLabels(rowData) {
if (entryYear && entryYear != "-") {
let yearValue;
switch (entryYear.toString()) {
case '2023':
case '2023':
yearValue = labelEnum.ENTERPRISESYSTEMLABEL["2023年"];
break;
case '2024':
case '2024':
yearValue = labelEnum.ENTERPRISESYSTEMLABEL["2024年"];
break;
case '2025':
case '2025':
yearValue = labelEnum.ENTERPRISESYSTEMLABEL["2025年"];
break;
case '2026':
case '2026':
yearValue = labelEnum.ENTERPRISESYSTEMLABEL["2026年"];
break;
case '2027':
case '2027':
yearValue = labelEnum.ENTERPRISESYSTEMLABEL["2027年"];
break;
case '2028':
case '2028':
yearValue = labelEnum.ENTERPRISESYSTEMLABEL["2028年"];
break;
// default:
......@@ -659,7 +694,8 @@ async function initEnterpriseFromExcel() {
logonTime: parseDateString(rowData.logonTime),
parkEntryTime: parseDateString(rowData.parkEntryTime),
leasedArea: parseNumber(rowData.leasedArea, 0),
enterpriseNature: EnterpriseNatureMap[rowData.enterpriseNature] || labelEnum.ENTERPRISENATURE.实体型,
// enterpriseNature: EnterpriseNatureMap[rowData.enterpriseNature] || labelEnum.ENTERPRISENATURE.实体型,
enterpriseNature: EnterpriseNatureMap[rowData.enterpriseNature] || null,
property: propertyMap[rowData.property] || null,
//用户相关
......
......@@ -221,5 +221,114 @@ export function formatAddress(original) {
}
/**
* 更完善的注册资本格式化函数
* @param {string|number} value 注册资本值
* @returns {string} 格式化后的注册资本字符串
*/
export function formatRegisteredCapital(value) {
if (value === null || value === undefined) {
return '';
}
// 如果输入是数字,转换为字符串
if (typeof value === 'number') {
value = value.toString();
}
// 确保是字符串类型
if (typeof value !== 'string') {
return String(value);
}
// 去除首尾空格
value = value.trim();
// 空字符串直接返回
if (value === '') {
return value;
}
// 特殊情况:如果是"-"或其他占位符,直接返回
if (value === '-' || value === '--' || value === 'N/A' || value === 'null' || value === 'undefined') {
return value;
}
// 判断是否已经包含单位
// 定义常见单位列表
const units = [
'万元', '万', 'w', 'W',
'元', '¥',
'亿', '亿元',
'美元', '美金', 'usd', 'USD',
'人民币', 'RMB', 'CNY',
'欧元', 'EUR', 'euro',
'日元', 'JPY', 'yen',
'港元', '港币', 'HKD',
'英镑', 'GBP', 'pound'
];
// 检查是否已包含单位(不区分大小写)
const lowerValue = value.toLowerCase();
for (const unit of units) {
if (lowerValue.endsWith(unit.toLowerCase()) ||
lowerValue.includes(unit.toLowerCase() + ' ') ||
lowerValue.includes(' ' + unit.toLowerCase())) {
return value; // 已包含单位,直接返回
}
}
// 检查常见的外币符号
const currencySymbols = ['¥', '¥', '$', '€', '£', '¥'];
for (const symbol of currencySymbols) {
if (value.includes(symbol)) {
return value; // 包含货币符号,直接返回
}
}
// 尝试提取纯数字部分
// 移除所有非数字字符(除了小数点、逗号和负号)
const numericString = value.replace(/[^0-9.,-]/g, '');
// 检查是否包含有效数字
if (numericString && /^-?\d[\d,]*\.?\d*$/.test(numericString)) {
// 移除逗号并转换为数字
const numericValue = parseFloat(numericString.replace(/,/g, ''));
// 根据数值大小选择合适的单位
if (!isNaN(numericValue)) {
// 如果数字大于等于10000万(即1亿),可以考虑使用"亿元"
if (numericValue >= 100000000) {
const billionValue = (numericValue / 100000000).toFixed(2);
// 去除末尾的.00
const formatted = billionValue.replace(/\.00$/, '');
return formatted + '亿元';
}
// 如果数字大于等于1000,使用"万元"
else if (numericValue >= 1000) {
const tenThousandValue = (numericValue / 10000).toFixed(2);
const formatted = tenThousandValue.replace(/\.00$/, '');
return formatted + '万元';
}
// 否则直接添加"万元"
else {
// 如果是整数,不显示小数位
if (Number.isInteger(numericValue)) {
return numericValue + '万元';
} else {
return numericValue.toFixed(2).replace(/\.00$/, '') + '万元';
}
}
}
}
// 如果无法解析为数字,但看起来像是金额(包含数字)
if (/\d/.test(value)) {
return value + '万元';
}
// 其他情况返回原值
return value;
}
......@@ -2,7 +2,7 @@
* 标签相关处理工具方法
*/
import { LABELUPDATEROAD } from "../config/enum/labelEnum";
import { LABELTYPE, LABELUPDATEROAD } from "../config/enum/labelEnum";
import * as labelData from "../data/label";
......@@ -151,6 +151,7 @@ export async function generateEnterpriseLabels(enterpriseData, activeLabels = nu
if (labelInfo && labelInfo.state === false) {
enterpriseLabels.push({
labelId: labelIdStr,
labelType: LABELTYPE.基础标签,
state: true
});
}
......@@ -166,6 +167,7 @@ export async function generateEnterpriseLabels(enterpriseData, activeLabels = nu
if (labelInfo && labelInfo.state === false && !labelExists(natureLabelId, enterpriseLabels)) {
enterpriseLabels.push({
labelId: natureLabelId,
labelType: LABELTYPE.企业性质,
state: true
});
}
......@@ -179,6 +181,7 @@ export async function generateEnterpriseLabels(enterpriseData, activeLabels = nu
if (labelInfo && labelInfo.state === false && !labelExists(propertyLabelId, enterpriseLabels)) {
enterpriseLabels.push({
labelId: propertyLabelId,
labelType: LABELTYPE.所属物业,
state: true
});
}
......@@ -192,6 +195,7 @@ export async function generateEnterpriseLabels(enterpriseData, activeLabels = nu
if (labelInfo && labelInfo.state === false && !labelExists(yearLabelId, enterpriseLabels)) {
enterpriseLabels.push({
labelId: yearLabelId,
labelType: LABELTYPE.入驻年份,
state: true
});
}
......@@ -234,3 +238,78 @@ export async function updateEnterpriseLabels(enterpriseData) {
return await generateEnterpriseLabels(enterpriseData, activeLabels);
}
/**
* 转换前端传入的labels数据为数据库存储格式(基于标签表查询)
* @param {Array<string>} labelIds 前端传入的标签ID数组,如:["4", "6", "601", "2025", "el_35ee4ddafbf7eaf9191071b893adb806"]
* @returns {Promise<Array<Object>>} 数据库存储格式的标签数组
*/
export async function convertLabelsToDbFormat(labelIds) {
if (!labelIds || !Array.isArray(labelIds) || labelIds.length === 0) {
return [];
}
try {
// 批量查询标签信息,提高性能
const labelInfos = await labelData.selectLabelList({
id: { $in: labelIds }
});
// 创建标签ID到标签信息的映射
const labelInfoMap = new Map();
labelInfos.forEach(info => {
labelInfoMap.set(info.id, info);
});
const dbLabels = [];
for (const labelId of labelIds) {
if (!labelId || typeof labelId !== 'string') {
continue;
}
// 从查询结果中获取标签信息
const labelInfo = labelInfoMap.get(labelId);
let labelType = 0;
if (labelInfo) {
// 如果标签表中有定义,使用定义中的类型
labelType = labelInfo.labelType || 0;
} else {
// 如果标签表中没有定义,根据ID格式推断类型
// 1. 入驻年份标签(2023-2028年的纯数字)
if (/^\d{4}$/.test(labelId)) {
const year = parseInt(labelId);
if (year >= 2023 && year <= 2028) {
labelType = 2; // 假设2表示入驻年份标签类型
} else {
// 其他纯数字标签,可能是系统标签
labelType = 1; // 假设1表示系统标签类型
}
}
// 2. 自定义标签(以el_开头)
else if (labelId.startsWith('el_')) {
labelType = 5; // 假设5表示自定义标签类型
}
// 3. 其他情况
else {
labelType = 0; // 未知类型
}
}
dbLabels.push({
labelId: labelId,
labelType: labelType,
state: true // 默认启用状态
});
}
return dbLabels;
} catch (error) {
console.error('转换标签格式时出错:', error);
}
}
......@@ -3,6 +3,8 @@
*/
import moment = require("moment");
import { findEnterpriseListByParam } from "../data/enterprise";
import { findManageByParam } from "../data/manage";
/**
* 匹配新旧对象变化
......@@ -68,3 +70,38 @@ export function checkDataHaveNull(data:object, sensitive:boolean) {
}
return success;
}
/**
* 获取所有企业库已有企业Map
* @returns
*/
export async function getEnterpriseMap() {
let enterpriseDbList = await findEnterpriseListByParam({});
let enterpriseMap = {};
enterpriseDbList.forEach( info => {
enterpriseMap[info.uscc] = info.name;
})
return enterpriseMap;
}
/**
* 获取经营数据是否有相同记录
* @param uscc
* @param year
* @param period
* @returns
*/
export async function getManageData(uscc, year, period) {
let manageDbInfo = await findManageByParam({uscc, year, period});
let isAdd = true;
/**如果有数据代表重复 */
if (manageDbInfo) {
isAdd = false
}
return isAdd
}
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