Commit 90c802e7 by lixinming

no message

parent 8b3ac431
......@@ -4,30 +4,23 @@
* 孵化器相关逻辑 包括孵化器的增删改查
*
*/
import { ERRORENUM } from "../../config/errorEnum";
import { BaseParamUpdateConfig } from "../../config/checkParamConfig";
import { findFuHuaQiByUSCC } from "../../data/fuHuaQi/fuhuaqi";
import { BizError } from "../../util/bizError";
import * as tools from "../../util/tools";
/**
* 更新孵化器基础数据
* @param uscc 孵化器统一信用代码
*/
/**
* name:string, virtualEnterpriseNum:number, logonTime:number, incubatedAcreage:number, acreageTotal:number,
acreagePersonalUse:number, lv:number, identificationTime:number, industry, institutionalNature:number, liaison:string, liaisonPhone:string,
personInCharge:string, personInChargePhone:string, personInChargeAdd:string, siteAcreage:number, leasePrice:number
* @param param 表单内容
* @returns {isSuccess:true/false};
*/
export async function updateFuHuaQiBaseData(uscc:string, param) {
let baseDataInfo = await findFuHuaQiByUSCC(uscc);
/**校验参数 */
checkParamater(param);
let changeList = checkChange(param, baseDataInfo);
tools.checkParamater("更新孵化器基础数据", BaseParamUpdateConfig, param);
let changeList = tools.checkChange(param, baseDataInfo);
for (let i = 0; i < changeList.length; i++) {
let key = changeList[i];
baseDataInfo[key] = param[key];
......@@ -38,69 +31,11 @@ export async function updateFuHuaQiBaseData(uscc:string, param) {
return {isSuccess:true};
}
/**
* 校验参数
* @param param
*/
function checkParamater(param) {
let keyTypeConf = {
name:"String",
virtualEnterpriseNum:"Number",
logonTime:"Number",
incubatedAcreage:"Number",
acreageTotal:"Number",
acreagePersonalUse:"Number",
lv:"Number",
identificationTime:"Number",
industry:"[Number]",
institutionalNature:"Number",
liaison:"String",
liaisonPhone:"String",
personInCharge:"String",
personInChargePhone:"String",
personInChargeAdd:"String",
siteAcreage:"Number",
leasePrice:"Number"
};
for (let key in keyTypeConf ) {
if ( !param[key] ) throw new BizError(ERRORENUM.表单校验失败, '孵化器基础数据更新', `缺失${key}字段`);
let type = typeof param[key];
switch(keyTypeConf[key]) {
case 'Number':
if ( type != 'number' ) throw new BizError(ERRORENUM.表单校验失败, '孵化器基础数据更新', `${key}应是number型 而不是${type}`);
break;
case 'String':
if ( type != 'string' ) throw new BizError(ERRORENUM.表单校验失败, '孵化器基础数据更新', `${key}应是number型 而不是${type}`);
break;
case '[Number]':
if ( !Array.isArray(param[key]) ) throw new BizError(ERRORENUM.表单校验失败, '孵化器基础数据更新', `${key}应是数组型 而不是${type}`);
for (let i =0; i < param[key].length; i++) {
let item = param[key][i];
if ( typeof item != 'number' ) {
throw new BizError(ERRORENUM.表单校验失败, '孵化器基础数据更新', `${key}应是number型数组其中下标${i}${typeof item}`);
}
}
break;
}
}
for (let key in param) {
if (!keyTypeConf[key]) throw new BizError(ERRORENUM.表单校验失败, '孵化器基础数据更新', `多余${key}字段`);
}
}
function checkChange(newObj, oldObj) {
let changeKeyList = [];
for (let newKey in newObj) {
if (`${newObj[newKey]}` != `${oldObj[newKey]}`) changeKeyList.push(newKey);
}
return changeKeyList;
}
/**
* 查询孵化器基础数据
* @param uscc 孵化器统一信用代码
* @returns {data:{}}
*/
export async function selectFuHuaQiBaseData(uscc:string) {
let dataBaseInfo = await findFuHuaQiByUSCC(uscc);
......
/**
* 月度表单逻辑层
* 作者: 陈金晶
*/
import { ERRORENUM } from "../../config/errorEnum";
import { BizError } from "../../util/bizError";
import * as monthData from "../../data/fuHuaQi/monthTable";
import { getTaskId } from "../../util/tools";
import moment = require("moment");
/**
* 孵化月度填报 新增报表
* 新添加孵化器月度填报
* @param uscc 孵化器的统一信用代码
* @param occupancyRate 本月出租率
*/
export async function createReport(uscc:string, occupancyRate:number) {
if (typeof uscc != "string" || isNaN(occupancyRate)) throw new BizError(ERRORENUM.参数错误, uscc, occupancyRate);
let name = "1月孵化器月度填报";
let monthInfo = await monthData.addOnceReport(name, uscc, occupancyRate);
//不允许有重复的
const TaskId = getTaskId(uscc);
let dataBaseInfo = await monthData.findmonthTableListByTaskId(TaskId);
if (!dataBaseInfo || !dataBaseInfo.taskId) throw new BizError(ERRORENUM.该孵化器月度填报已存在, `${uscc}重复提交了月度填报值为${occupancyRate}`);
const MonthNumber = moment().subtract(1, 'months').month() + 1;
const MonthTableName = `${MonthNumber}月孵化器月度填报`;
await monthData.addOnceReport(MonthTableName, uscc, occupancyRate);
return monthInfo;
return;
}
/**
* 校验参数所用的配置
*
*/
/**
* 更新孵化器基础数据的表单配置
*/
export const BaseParamUpdateConfig = {
name:"String",
virtualEnterpriseNum:"Number",
logonTime:"Number",
incubatedAcreage:"Number",
acreageTotal:"Number",
acreagePersonalUse:"Number",
lv:"Number",
identificationTime:"Number",
industry:"[Number]",
institutionalNature:"Number",
liaison:"String",
liaisonPhone:"String",
personInCharge:"String",
personInChargePhone:"String",
personInChargeAdd:"String",
siteAcreage:"Number",
leasePrice:"Number"
}
......@@ -5,7 +5,8 @@ export enum ERRORENUM {
不能重复提交任务,
表单校验失败,
该企业已存在,
数据无更新
数据无更新,
该孵化器月度填报已存在,
}
let bizErrorMsgMap = {};
......
/**
* 企业信息表
*
* draftLock 草稿锁 当任务提交的时候,将此字段改为true
*/
import {Schema} from 'mongoose';
......@@ -66,6 +66,7 @@ export async function updateEnterpriseDraftLock(taskId:string) {
/**
* 通过企业统一信用代码获取企业信息
* 支持.save方法保存对象修改
* @param uscc 企业统一信用代码
* @returns {}
*/
......
/**
* 企业投资信息表
* draftLock 草稿锁 当任务提交的时候,将此字段改为true
* 一个企业在一个月只能录入一个融资数据 2023-02-07 确定此需求
*/
import {Schema} from 'mongoose';
import { baseDB } from '../../db/dbInit';
......@@ -42,17 +48,18 @@ export async function save(throwError=false) {
/**
* 通过taskId 获取此次任务添加的融资列表
* @param taskId
* @returns
* @param taskId 任务id 格式遵循tool中getTaskId
* @returns [{}]
*/
export async function findFinancingListByTaskId(taskId:string) {
return await financingModel.find({taskId}).exec();
}
/**
* 通过taskId和uscc获取融资信息你
* @param taskId
* @returns
* 通过taskId和uscc获取融资信息
* 支持.save方法保存对象修改
* @param taskId 任务id 格式遵循tool中getTaskId
* @returns {}
*/
export async function findFinancingInfoByTaskIdAndSucc(taskId:string, uscc:string) {
return await financingModel.selectOnceData({taskId, uscc}).exec();
......@@ -60,16 +67,18 @@ export async function findFinancingInfoByTaskIdAndSucc(taskId:string, uscc:strin
/**
* 修改特定taskId的锁为true
* @param taskId 任务id
* 将所有taskId匹配数据draftLock字段修改为true
* @param taskId 任务id 格式遵循tool中getTaskId
*/
export async function updateFinancingDraftLock(taskId:string) {
return await financingModel.update({taskId}, {$set:{draftLock:true}}, {upsert:true});
}
/**
* 创建新的融资数据
* @param param
* 添加新的融资数据
* @param fuHuaQiUscc 孵化器统一信用代码
* @param taskId 任务id 格式遵循tool中getTaskId
* @param param 所添加表单 需要提前验证
*/
export async function createFinancing(fuHuaQiUscc:string, taskId:string, param) {
let addInfo = Object.assign({fuHuaQiUscc, taskId, createTime:new Date().valueOf()}, param);
......
/**
* 孵化器信息表
* operationName不可修改 2023-02-06 确定此需求
* uscc不可修改 2023-02-06 确定此需求
*/
import {Schema} from 'mongoose';
import { baseDB } from '../../db/dbInit';
......@@ -47,7 +53,9 @@ export async function save(throwError=false) {
/**
* 通过统一信用代码获取孵化器信息
* @param uscc 统一信用代码
* 支持.save方法保存对象修改
* @param uscc 孵化器统一信用代码
* @returns {}
*/
export async function findFuHuaQiByUSCC(uscc:string) {
return await fuHuaQiModel.selectOnceData({uscc}).exec();
......@@ -56,6 +64,7 @@ export async function findFuHuaQiByUSCC(uscc:string) {
/**
* 通过孵化器名称获取孵化器信息
* @param name 孵化器名称
* @returns {}
*/
export async function findFuHuaQiByName(name:string) {
return await fuHuaQiModel.findOne({name}).exec();
......
/**
* 孵化器月度填报表
* draftLock 草稿锁 当任务提交的时候,将此字段改为true
* occupancyRate 取%号前的数据 例如 填报数据为80% 库中数据为80
* name 为系统生成 此月填报上一月内容 即2月填报时 name中月份为1月 2023-02-06 确定此需求
*
*/
import {Schema} from 'mongoose';
import { baseDB } from '../../db/dbInit';
......@@ -5,7 +13,7 @@ const monthTableSchema = new Schema({
taskId:String,//任务id
name:String,//任务名称
fuHuaQiUscc:String,//任务所属孵化器id
occupancyRate:Number,//出租率(%)
occupancyRate:Number,//出租率 单位为%
createTime:Number,//创建时间
draftLock:{type:Boolean, default:false},//草稿锁,true为提交之后,false为草稿
});
......@@ -33,8 +41,8 @@ export async function save(throwError=false) {
/**
* 通过taskId 获取此次任务添加的月度列表
* @param taskId
* @returns
* @param taskId 任务id 格式遵循tool中getTaskId
* @returns {}
*/
export async function findmonthTableListByTaskId(taskId:string) {
return await monthTableModel.find({taskId}).exec();
......@@ -42,8 +50,9 @@ export async function findmonthTableListByTaskId(taskId:string) {
/**
* 通过taskId 获取此次月度任务
* @param taskId
* @returns
* 支持.save方法保存对象修改
* @param taskId 任务id 格式遵循tool中getTaskId
* @returns {}
*/
export async function findmonthTableByTaskId(taskId:string) {
let monthTableInfo = await monthTableModel.selectOnceData({taskId}).exec();
......@@ -52,13 +61,13 @@ export async function findmonthTableByTaskId(taskId:string) {
/**
* 孵化器月度填报 新增报表
* @param name 任务名称
* @param fuHuaQiUscc 孵化器信用代码
* @param name 任务名称 系统生成
* @param fuHuaQiUscc 孵化器统一信用代码
* @param occupancyRate 出租率
* @param createTime 创建时间
* @returns
*
*/
export async function addOnceReport(name:string, uscc:string, occupancyRate:number) {
let monthInfo = {name, fuHuaQiUscc:uscc, occupancyRate, createTime:new Date().valueOf()}
return await monthTableModel.create(monthInfo);
await monthTableModel.create(monthInfo);
}
/**
* 孵化器任务表
* 任务标识为 YYYYMM
* 任务id 格式遵循tool中getTaskId
* 每种任务一个月只能提交一次 2023-02-06 确定此需求
* 任务提交之后将不会出现在列表中 2023-02-06 确定此需求
* 任务不能提交后不能修改和删除 2023-02-06 确定此需求
* type 依赖枚举
*/
import {Schema} from 'mongoose';
import { baseDB } from '../../db/dbInit';
......@@ -19,7 +28,7 @@ export function initModel(){
* 通过统一信用代码和任务日期标识 查询孵化器任务
* @param uscc 孵化器代码
* @param key 任务日期标识
* @returns
* @returns {YYYYMM:{}, YYYYMM:{}}
*/
export async function findFuHuaQiTaskByKeyAndUscc(uscc:string, key:string) {
let findList = await fuHuaQiTaskModel.find({uscc, key}).exec() || [];
......
const fs = require('fs');
const xlsx = require('node-xlsx');
const path = require('path');
//获取单个目录下的单个excel文件数据 只能有一个文件
export function getExcelDataByPath (dir) {
console.log(path.join(__dirname,dir))
let files = fs.readdirSync( path.join(__dirname,dir));
for (let i = 0; i < files.length; i++) {
if (files[i].indexOf('~') == 0 || files[i].indexOf('.') == 0) continue;
const workSheetsFromFile = xlsx.parse(dir+'/'+files[i]);
let sheetMap = {};
let sheetList = [];
for (let i = 0; i < workSheetsFromFile.length; i++) {
let sheetInfo = workSheetsFromFile[i];
sheetMap[sheetInfo.name] = sheetInfo.data;
sheetList.push(sheetInfo.data)
}
return {sheetMap, sheetList}
}
}
export function updateExcel(data, fileName) {
try{
fs.writeFileSync('output.xlsx', xlsx.build(data), "binary");
console.log(`写入 ${fileName} 成功`);
}catch(err) {
console.log(err);
}
}
//获取单个excel文件的数据
export function getExcelDataByFile(filePath) {
const workSheetsFromFile = xlsx.parse(filePath);
let sheetMap = {};
let sheetList = [];
for (let i = 0; i < workSheetsFromFile.length; i++) {
let sheetInfo = workSheetsFromFile[i];
sheetMap[sheetInfo.name] = sheetInfo.data;
sheetList.push(sheetInfo);
}
return {sheetMap, sheetList}
}
export function arrayToObject(dataArr, keyNameArr) {
let obj = {};
for (let i = 0; i < dataArr.length; i++) {
obj[keyNameArr[i]] = dataArr[i];
}
return obj;
}
\ No newline at end of file
/**
*
* @param keyList 要生成的键名称集合 例如: ["键1", "键2"]
* @param valLen 要生成的值的长度 例如 十位数就传1 百位数就传2 例如: 1 则会生成 键1或键2 的数据是1-10的随机数
* @param haveUnit 单位信息: 如果传 % 号则会把生成的随机数再求百分比 传false 则不生成单位 传 数组 例如:["家","个"] 则 键1的单位是 家, 键2的单位是个
* @param title 数据标题
* @param subTitle 数据副标题
* @param total 是否要求和
* @returns
*/
export function mock键值数据模板(keyList, valLen, haveUnit, title, subTitle, total) {
let data = {
"title": "",
"subTitle": "",
"total": 0,
"list": []
};
if (title) data.title = title;
if (subTitle) data.subTitle = subTitle || title;
if ( haveUnit && haveUnit == "%" ) {
let random = Math.ceil( Math.random() * 20 );
let avg = Math.ceil((100 - random) / keyList.length);
keyList.forEach((key, index) => {
let valut = index == 0 ? avg + random : avg;
let onceInfo:any = {
"key":key,
"value": valut,
unit:"%"
};
data.list.push(onceInfo);
});
} else {
let unitIndex = 0;
for (let i = 0; i < keyList.length; i++) {
let key = keyList[i];
let onceInfo:any = {
"key":key,
"value": getValueByLength(valLen)
};
if (haveUnit) {
if (typeof haveUnit == "string") onceInfo.unit = haveUnit;
else onceInfo.unit = haveUnit[unitIndex];
}
data.list.push(onceInfo);
unitIndex += 1;
}
if (total) {
data.list.forEach(keyValue=>{
data.total += keyValue.value;
})
}
}
return data;
}
//键值数据 值为字符串
export function mock键值数据字符串模板(title, subTitle, obj) {
let data = { title: "", subTitle: "", total: 0, list: [] };
if (title) data.title = title;
if (subTitle) data.subTitle = subTitle || title;
for (let key in obj) {
data.list.push({
key,
value:obj[key]
});
}
return data;
}
//列表数据 obj:{ "表格1":{title1:1, title2:2, title3:3... } }
export function mock列表模板( obj, number ) {
let tableNumber = Object.keys(obj).length;
if (tableNumber > 1) {
let data = [];
for (let key in obj) {
let onceTable:any = {title:key, total:number, subTitle:key, titleList:[], valueList:[] };
onceTable.titleList = Object.keys(obj[key]);
for (let i = 0; i < number; i++) {
onceTable.valueList.push(Object.values(obj[key]) );
}
data.push(onceTable);
}
return data;
} else {
let onceTable:any = {};
for (let key in obj) {
onceTable = {title:key, total:number, subTitle:key, titleList:[], valueList:[] };
onceTable.titleList = Object.keys(obj[key]);
for (let i = 0; i < number; i++) {
onceTable.valueList.push(Object.values(obj[key]) );
}
}
return onceTable;
}
}
export function mock图形数据模板(keyList, title, number?, subTitleList?) {
if (!number) number = 1;
if (number == 1) {
let data = {
"title": title ? title : "测试标题",
"yMaxValue": 100,
"yMinValue": 0,
"yStepValue": 10,
"unit": "个",
"data": {
"title": "测试数据标题",
"subTitle": "测试数据副标题",
"total": 1,
"list": []
}
}
for (let i = 0; i < keyList.length; i++) {
let key = keyList[i];
let onceInfo:any = {
key,
"value": Math.floor(Math.random()*99+1),
"unit": "个"
};
data.data.list.push(onceInfo)
}
data.data.list.forEach(keyValue=>{
data.data.total += keyValue.value;
});
return data;
} else {
let data = {
"title": title ? title : "测试标题",
"yMaxValue": 100,
"yMinValue": 0,
"yStepValue": 10,
"unit": "个",
"data": []
};
for (let y = 0; y < number; y++) {
let onceData = {
"title": subTitleList[y],
"subTitle": subTitleList[y],
"total": 1,
"list": []
}
for (let i = 0; i < keyList.length; i++) {
let key = keyList[i];
let onceInfo:any = {
key,
"value": Math.floor(Math.random()*99+1),
"unit": "个"
};
onceData.list.push(onceInfo)
}
onceData.list.forEach(keyValue=>{
onceData.total += keyValue.value;
});
data.data.push(onceData);
}
return data;
}
}
// 柱状图数据模板 模拟数据
export function mock柱状图数据模板(len, title?) {
let data = {
"title": title ? title : "测试标题",
"yMaxValue": 100,
"yMinValue": 0,
"yStepValue": 10,
"unit": "个",
"data": {
"title": "测试数据标题",
"subTitle": "测试数据副标题",
"total": 1,
"list": [
]
}
}
for (let i = 0; i < len; i++) {
let onceInfo:any = {
"key": 2010 + i,
"value": Math.floor(Math.random()*99+1),
"unit": "个"
};
data.data.list.push(onceInfo)
}
data.data.list.forEach(keyValue=>{
data.data.total += keyValue.value;
})
return data;
}
export function mock多柱柱状数据模板(len, 数组长度, title?) {
let data = {
"title": title ? title : "测试标题",
"yMaxValue": 100,
"yMinValue": 0,
"yStepValue": 10,
"unit": "个",
"data": []
}
for (let arrLen = 0; arrLen < 数组长度; arrLen++) {
let obj = {
"title": "测试数据标题",
"subTitle": "测试数据副标题",
"total": 0,
"list": [
]
}
for (let i = 0; i < len; i++) {
let onceInfo:any = {
"key": 2010 + i,
"value": Math.floor(Math.random()*99+1),
"unit": "个"
};
obj.list.push(onceInfo)
}
obj.list.forEach(keyValue=>{
obj.total += keyValue.value;
});
data.data.push(obj);
}
return data;
}
//获取特定长度的测试文字
export function getTestStrByLength(strLen, strType) {
let testStr = ``;
if (strType == 'c') {//中文
if (strLen < 5) {
testStr += `测试文本`.substring(0, strLen);
} else {
testStr += `测试`;
getPlaByLength((strLen - 4), () => {
testStr += '-';
});
testStr += `文本`
}
} else {//英文
testStr += `te`;
getPlaByLength((strLen - 4), () => {
testStr += '-';
});
testStr += `st`
}
return testStr;
}
function getValueByLength(length) {
let i = 1;
getPlaByLength(length, () => {
i= i * 10;
});
return Math.floor(Math.random() * i);
}
//获取特定长度的 占位符号
function getPlaByLength(num, callback) {
for (let i =0; i < num; i++) {
callback();
}
}
// 地图数据模板 模拟数据
export function mock地图数据模板(len) {
let data = {
"typeNameList": [
"type1","type2","type3"
],
"list": [
]
}
for (let i = 0; i < len; i++) {
data.list.push({
"x": Math.floor(Math.random()*500),
"y": Math.floor(Math.random()*500),
"typeName": "type"+(i%3+1),
"title": "测试标题",
"address": "测试地址",
"data": "测试数据<b>加粗</b></br>等等"
})
}
return data;
}
export function mock表数据模板(表头长度, 数据长度) {
let data = {
title:"",
titleList:[],
valueList:[]
}
for (let i = 0; i < 表头长度; i++) {
data.titleList.push("表头"+i);
}
for(let j = 0; j < 数据长度; j++) {
for (let i = 0; i < 表头长度; i++) {
data.titleList.push("数据"+i);
}
}
}
export function randomNumber(max, min=0) {
return Math.floor(Math.random()*(max-min))+min;
}
\ No newline at end of file
import { ERRORENUM } from "../config/errorEnum";
import { BizError } from "./bizError";
/**
* 生成任务id
* @param uscc 企业标识
......@@ -13,4 +16,58 @@ export function getTaskId(uscc:string) {
*/
export function getTimeKey() {
return `${new Date().getFullYear()}${new Date().getMonth() + 1 }`
}
/**
* 通过config校验参数param
* 包括类型 String, Number, Boolean, [Number]
* @param name 被调用的方法名
* @param config 校验配置
* @param param 需要校验的参数
*/
export function checkParamater(name:string, keyTypeConf:object, param:object) {
for (let key in keyTypeConf ) {
if ( !param[key] ) throw new BizError(ERRORENUM.表单校验失败, name, `缺失${key}字段`);
let type = typeof param[key];
switch(keyTypeConf[key]) {
case 'Number':
if ( type != 'number' ) throw new BizError(ERRORENUM.表单校验失败, name, `${key}应是number型 而不是${type}`);
break;
case 'String':
if ( type != 'string' ) throw new BizError(ERRORENUM.表单校验失败, name, `${key}应是string型 而不是${type}`);
break;
case 'Boolean':
if ( type != 'boolean' ) throw new BizError(ERRORENUM.表单校验失败, name, `${key}应是boolean型 而不是${type}`);
break;
case '[Number]':
if ( !Array.isArray(param[key]) ) throw new BizError(ERRORENUM.表单校验失败, name, `${key}应是数组型 而不是${type}`);
for (let i =0; i < param[key].length; i++) {
let item = param[key][i];
if ( typeof item != 'number' ) {
throw new BizError(ERRORENUM.表单校验失败, name, `${key}应是number型数组其中下标${i}${typeof item}`);
}
}
break;
}
}
for (let key in param) {
if (!keyTypeConf[key]) throw new BizError(ERRORENUM.表单校验失败, name, `多余${key}字段`);
}
return true;
}
/**
* 匹配新旧对象变化
* 将newObj 与 oldObj 比对,将newObj中发生变化的key返回
* 使用前需要校验对象中的内容
* @param newObj 新对象
* @param oldObj 旧对象
* @returns [key] 发生变化的key
*/
export function checkChange(newObj, oldObj) {
let changeKeyList = [];
for (let newKey in newObj) {
if (`${newObj[newKey]}` != `${oldObj[newKey]}`) changeKeyList.push(newKey);
}
return changeKeyList;
}
\ No newline at end of file
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