Commit 90c802e7 by lixinming

no message

parent 8b3ac431
...@@ -4,30 +4,23 @@ ...@@ -4,30 +4,23 @@
* 孵化器相关逻辑 包括孵化器的增删改查 * 孵化器相关逻辑 包括孵化器的增删改查
* *
*/ */
import { BaseParamUpdateConfig } from "../../config/checkParamConfig";
import { ERRORENUM } from "../../config/errorEnum";
import { findFuHuaQiByUSCC } from "../../data/fuHuaQi/fuhuaqi"; import { findFuHuaQiByUSCC } from "../../data/fuHuaQi/fuhuaqi";
import { BizError } from "../../util/bizError"; import * as tools from "../../util/tools";
/** /**
* 更新孵化器基础数据 * 更新孵化器基础数据
* @param uscc 孵化器统一信用代码 * @param uscc 孵化器统一信用代码
*/ * @param param 表单内容
/** * @returns {isSuccess:true/false};
* 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
*/ */
export async function updateFuHuaQiBaseData(uscc:string, param) { export async function updateFuHuaQiBaseData(uscc:string, param) {
let baseDataInfo = await findFuHuaQiByUSCC(uscc); let baseDataInfo = await findFuHuaQiByUSCC(uscc);
/**校验参数 */
checkParamater(param); tools.checkParamater("更新孵化器基础数据", BaseParamUpdateConfig, param);
let changeList = checkChange(param, baseDataInfo);
let changeList = tools.checkChange(param, baseDataInfo);
for (let i = 0; i < changeList.length; i++) { for (let i = 0; i < changeList.length; i++) {
let key = changeList[i]; let key = changeList[i];
baseDataInfo[key] = param[key]; baseDataInfo[key] = param[key];
...@@ -38,69 +31,11 @@ export async function updateFuHuaQiBaseData(uscc:string, param) { ...@@ -38,69 +31,11 @@ export async function updateFuHuaQiBaseData(uscc:string, param) {
return {isSuccess:true}; 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 孵化器统一信用代码 * @param uscc 孵化器统一信用代码
* @returns {data:{}}
*/ */
export async function selectFuHuaQiBaseData(uscc:string) { export async function selectFuHuaQiBaseData(uscc:string) {
let dataBaseInfo = await findFuHuaQiByUSCC(uscc); let dataBaseInfo = await findFuHuaQiByUSCC(uscc);
......
/**
* 月度表单逻辑层
* 作者: 陈金晶
*/
import { ERRORENUM } from "../../config/errorEnum"; import { ERRORENUM } from "../../config/errorEnum";
import { BizError } from "../../util/bizError"; import { BizError } from "../../util/bizError";
import * as monthData from "../../data/fuHuaQi/monthTable"; import * as monthData from "../../data/fuHuaQi/monthTable";
import { getTaskId } from "../../util/tools";
import moment = require("moment");
/** /**
* 孵化月度填报 新增报表 * 新添加孵化器月度填报
* @param uscc 孵化器的统一信用代码
* @param occupancyRate 本月出租率 * @param occupancyRate 本月出租率
*/ */
export async function createReport(uscc:string, occupancyRate:number) { export async function createReport(uscc:string, occupancyRate:number) {
if (typeof uscc != "string" || isNaN(occupancyRate)) throw new BizError(ERRORENUM.参数错误, uscc, occupancyRate); //不允许有重复的
let name = "1月孵化器月度填报"; const TaskId = getTaskId(uscc);
let monthInfo = await monthData.addOnceReport(name, uscc, occupancyRate); 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 { ...@@ -5,7 +5,8 @@ export enum ERRORENUM {
不能重复提交任务, 不能重复提交任务,
表单校验失败, 表单校验失败,
该企业已存在, 该企业已存在,
数据无更新 数据无更新,
该孵化器月度填报已存在,
} }
let bizErrorMsgMap = {}; let bizErrorMsgMap = {};
......
/** /**
* 企业信息表 * 企业信息表
* * draftLock 草稿锁 当任务提交的时候,将此字段改为true
*/ */
import {Schema} from 'mongoose'; import {Schema} from 'mongoose';
...@@ -66,6 +66,7 @@ export async function updateEnterpriseDraftLock(taskId:string) { ...@@ -66,6 +66,7 @@ export async function updateEnterpriseDraftLock(taskId:string) {
/** /**
* 通过企业统一信用代码获取企业信息 * 通过企业统一信用代码获取企业信息
* 支持.save方法保存对象修改
* @param uscc 企业统一信用代码 * @param uscc 企业统一信用代码
* @returns {} * @returns {}
*/ */
......
/**
* 企业投资信息表
* draftLock 草稿锁 当任务提交的时候,将此字段改为true
* 一个企业在一个月只能录入一个融资数据 2023-02-07 确定此需求
*/
import {Schema} from 'mongoose'; import {Schema} from 'mongoose';
import { baseDB } from '../../db/dbInit'; import { baseDB } from '../../db/dbInit';
...@@ -42,17 +48,18 @@ export async function save(throwError=false) { ...@@ -42,17 +48,18 @@ export async function save(throwError=false) {
/** /**
* 通过taskId 获取此次任务添加的融资列表 * 通过taskId 获取此次任务添加的融资列表
* @param taskId * @param taskId 任务id 格式遵循tool中getTaskId
* @returns * @returns [{}]
*/ */
export async function findFinancingListByTaskId(taskId:string) { export async function findFinancingListByTaskId(taskId:string) {
return await financingModel.find({taskId}).exec(); return await financingModel.find({taskId}).exec();
} }
/** /**
* 通过taskId和uscc获取融资信息你 * 通过taskId和uscc获取融资信息
* @param taskId * 支持.save方法保存对象修改
* @returns * @param taskId 任务id 格式遵循tool中getTaskId
* @returns {}
*/ */
export async function findFinancingInfoByTaskIdAndSucc(taskId:string, uscc:string) { export async function findFinancingInfoByTaskIdAndSucc(taskId:string, uscc:string) {
return await financingModel.selectOnceData({taskId, uscc}).exec(); return await financingModel.selectOnceData({taskId, uscc}).exec();
...@@ -60,16 +67,18 @@ export async function findFinancingInfoByTaskIdAndSucc(taskId:string, uscc:strin ...@@ -60,16 +67,18 @@ export async function findFinancingInfoByTaskIdAndSucc(taskId:string, uscc:strin
/** /**
* 修改特定taskId的锁为true * 将所有taskId匹配数据draftLock字段修改为true
* @param taskId 任务id * @param taskId 任务id 格式遵循tool中getTaskId
*/ */
export async function updateFinancingDraftLock(taskId:string) { export async function updateFinancingDraftLock(taskId:string) {
return await financingModel.update({taskId}, {$set:{draftLock:true}}, {upsert:true}); 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) { export async function createFinancing(fuHuaQiUscc:string, taskId:string, param) {
let addInfo = Object.assign({fuHuaQiUscc, taskId, createTime:new Date().valueOf()}, 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 {Schema} from 'mongoose';
import { baseDB } from '../../db/dbInit'; import { baseDB } from '../../db/dbInit';
...@@ -47,7 +53,9 @@ export async function save(throwError=false) { ...@@ -47,7 +53,9 @@ export async function save(throwError=false) {
/** /**
* 通过统一信用代码获取孵化器信息 * 通过统一信用代码获取孵化器信息
* @param uscc 统一信用代码 * 支持.save方法保存对象修改
* @param uscc 孵化器统一信用代码
* @returns {}
*/ */
export async function findFuHuaQiByUSCC(uscc:string) { export async function findFuHuaQiByUSCC(uscc:string) {
return await fuHuaQiModel.selectOnceData({uscc}).exec(); return await fuHuaQiModel.selectOnceData({uscc}).exec();
...@@ -56,6 +64,7 @@ export async function findFuHuaQiByUSCC(uscc:string) { ...@@ -56,6 +64,7 @@ export async function findFuHuaQiByUSCC(uscc:string) {
/** /**
* 通过孵化器名称获取孵化器信息 * 通过孵化器名称获取孵化器信息
* @param name 孵化器名称 * @param name 孵化器名称
* @returns {}
*/ */
export async function findFuHuaQiByName(name:string) { export async function findFuHuaQiByName(name:string) {
return await fuHuaQiModel.findOne({name}).exec(); return await fuHuaQiModel.findOne({name}).exec();
......
/**
* 孵化器月度填报表
* draftLock 草稿锁 当任务提交的时候,将此字段改为true
* occupancyRate 取%号前的数据 例如 填报数据为80% 库中数据为80
* name 为系统生成 此月填报上一月内容 即2月填报时 name中月份为1月 2023-02-06 确定此需求
*
*/
import {Schema} from 'mongoose'; import {Schema} from 'mongoose';
import { baseDB } from '../../db/dbInit'; import { baseDB } from '../../db/dbInit';
...@@ -5,7 +13,7 @@ const monthTableSchema = new Schema({ ...@@ -5,7 +13,7 @@ const monthTableSchema = new Schema({
taskId:String,//任务id taskId:String,//任务id
name:String,//任务名称 name:String,//任务名称
fuHuaQiUscc:String,//任务所属孵化器id fuHuaQiUscc:String,//任务所属孵化器id
occupancyRate:Number,//出租率(%) occupancyRate:Number,//出租率 单位为%
createTime:Number,//创建时间 createTime:Number,//创建时间
draftLock:{type:Boolean, default:false},//草稿锁,true为提交之后,false为草稿 draftLock:{type:Boolean, default:false},//草稿锁,true为提交之后,false为草稿
}); });
...@@ -33,8 +41,8 @@ export async function save(throwError=false) { ...@@ -33,8 +41,8 @@ export async function save(throwError=false) {
/** /**
* 通过taskId 获取此次任务添加的月度列表 * 通过taskId 获取此次任务添加的月度列表
* @param taskId * @param taskId 任务id 格式遵循tool中getTaskId
* @returns * @returns {}
*/ */
export async function findmonthTableListByTaskId(taskId:string) { export async function findmonthTableListByTaskId(taskId:string) {
return await monthTableModel.find({taskId}).exec(); return await monthTableModel.find({taskId}).exec();
...@@ -42,8 +50,9 @@ export async function findmonthTableListByTaskId(taskId:string) { ...@@ -42,8 +50,9 @@ export async function findmonthTableListByTaskId(taskId:string) {
/** /**
* 通过taskId 获取此次月度任务 * 通过taskId 获取此次月度任务
* @param taskId * 支持.save方法保存对象修改
* @returns * @param taskId 任务id 格式遵循tool中getTaskId
* @returns {}
*/ */
export async function findmonthTableByTaskId(taskId:string) { export async function findmonthTableByTaskId(taskId:string) {
let monthTableInfo = await monthTableModel.selectOnceData({taskId}).exec(); let monthTableInfo = await monthTableModel.selectOnceData({taskId}).exec();
...@@ -52,13 +61,13 @@ export async function findmonthTableByTaskId(taskId:string) { ...@@ -52,13 +61,13 @@ export async function findmonthTableByTaskId(taskId:string) {
/** /**
* 孵化器月度填报 新增报表 * 孵化器月度填报 新增报表
* @param name 任务名称 * @param name 任务名称 系统生成
* @param fuHuaQiUscc 孵化器信用代码 * @param fuHuaQiUscc 孵化器统一信用代码
* @param occupancyRate 出租率 * @param occupancyRate 出租率
* @param createTime 创建时间 * @param createTime 创建时间
* @returns *
*/ */
export async function addOnceReport(name:string, uscc:string, occupancyRate:number) { export async function addOnceReport(name:string, uscc:string, occupancyRate:number) {
let monthInfo = {name, fuHuaQiUscc:uscc, occupancyRate, createTime:new Date().valueOf()} 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 {Schema} from 'mongoose';
import { baseDB } from '../../db/dbInit'; import { baseDB } from '../../db/dbInit';
...@@ -19,7 +28,7 @@ export function initModel(){ ...@@ -19,7 +28,7 @@ export function initModel(){
* 通过统一信用代码和任务日期标识 查询孵化器任务 * 通过统一信用代码和任务日期标识 查询孵化器任务
* @param uscc 孵化器代码 * @param uscc 孵化器代码
* @param key 任务日期标识 * @param key 任务日期标识
* @returns * @returns {YYYYMM:{}, YYYYMM:{}}
*/ */
export async function findFuHuaQiTaskByKeyAndUscc(uscc:string, key:string) { export async function findFuHuaQiTaskByKeyAndUscc(uscc:string, key:string) {
let findList = await fuHuaQiTaskModel.find({uscc, key}).exec() || []; let findList = await fuHuaQiTaskModel.find({uscc, key}).exec() || [];
......
//新的解析
const fs = require('fs');
const xlsx = require('node-xlsx');
const path = require('path');
const moment = require('moment');
/**
* getExcelDataBySheetName 将excel文件解析成数据块数据
* @param fileName 文件名称
* @param sheetName 表名称
* @returns thisBlockData 返回数据块集合 格式:blockList = [ {blockData:数据块(二维数组), blockTitle:"数据标题"}]
*/
export function getExcelDataBySheetName(fileName, sheetName) {
//todo 这里使用win10的打包方式 要写成根目录
let {sheetMap, sheetList} = getExcel(`./res/${fileName}` );
// let {sheetMap, sheetList} = getExcel( path.join(__dirname.substring(0,__dirname.indexOf("out")), "res", fileName ));
let thisBlockData = getBlockData(sheetMap[sheetName]);
return thisBlockData;
}
/**
* getBlockDataByData 将excel解析出来的二维数组解析成数据块模式
* @param dataList excel解出来的数据
* @returns thisBlockData 返回数据块集合 格式:blockList = [ {blockData:数据块(二维数组), blockTitle:"数据标题"}]
*/
export function getBlockDataByData(dataList) {
let thisBlockData = getBlockData(dataList);
return thisBlockData;
}
/**
* analysisExcelDataOfObject 将excel解出来的数据块按需求解析成可用数据
* @param dataList excel解出来的数据
* @param isJumpTitle 是否跳过解析表头
* @param keyInX key是否横向排列
* @returns 返回 {"数据标题":数据对象 }
*/
export function analysisExcelDataOfObject(dataList, isJumpTitle?, keyInX?) {
let result = {};
if (keyInX) {
let keyList = dataList[0];
let valueList = dataList[1];
let i = isJumpTitle ? 1:0;
for (; i < keyList.length; i++) {
let key = keyList[i];
let value = valueList[i] || null;
result[key] = value;
}
} else {
let y = isJumpTitle ? 1: 0;
for (; y < dataList.length; y++) {
let childList = dataList[y];
let key = childList[0];
let value = childList[1] || null;
result[key] = value;
}
}
return result;
}
export function analysisExcelDataTime(dataList, isJumpTitle?, keyInX?) {
const HOURS = new Date().getHours() + 1;//获取当前时间
let result = {};
if (keyInX) {
let keyList = dataList[0];
let valueList = dataList[1];
let i = isJumpTitle ? 1:0;
for (; i < keyList.length; i++) {
let key = keyList[i];
let value = valueList[i] || null;
result[key] = value;
}
} else {
let y = isJumpTitle ? 1: 0;
for (; y <= HOURS; y++) {
let childList = dataList[y];
let key = childList[0];
let value = childList[1] || null;
result[key] = value;
}
}
return result;
}
/**
* analysisExcelDataOfMoreObject 将excel解出来的数据块按需求解析成可用数据
* @param dataList excel解出来的数据
* @param isJumpTitle 是否跳过解析表头
* @param headerInx 第一个表头数据是否横向排列
* @returns 返回 {"第一个表头数据":{"表头数据":值...} }
*/
export function analysisExcelDataOfMoreObject(dataList, headerInx?) {
let result = {};
let titleList = dataList[0];
if (!headerInx) {
for (let y =1; y < dataList.length; y++) {
let dataTitle = dataList[y][0];
let thisData = {};
for (let x = 1; x < dataList[y].length; x++) {
let key = titleList[x];
thisData[key] = dataList[y][x];
}
result[dataTitle] = thisData;
}
} else {
let indexKeyMap = {};
titleList.forEach((thisTitle, index) => {
if (!index) return;
indexKeyMap[index] = thisTitle;
result[thisTitle] = {};
});
for (let y =1; y < dataList.length; y++) {
let thisKey = dataList[y][0];
for (let x = 1; x < dataList[y].length; x++) {
let thisTitle = indexKeyMap[x];
result[thisTitle][thisKey] = dataList[y][x];
}
}
}
return result;
}
/**
* analysisExcelDataOfList 将excel解出来的数据块按需求解析成可用数据
* @param dataList excel解出来的数据
* @param keyObject 对应关系 {dataList表头名称: 英文}
* @param headerInx 第一个表头数据是否横向排列
* @returns 返回 {"第一个表头数据":{"表头数据":值...} }
*/
export function analysisExcelDataOfList(dataList, keyObject, headerInx?) {
let result = [];
if (!headerInx) {//在y轴上排列
let titleList = dataList[0];
let indexKeyNameMap = {};
titleList.forEach( (info, index) => {
indexKeyNameMap[index + 1] = info;
});
for (let i = 1; i < dataList.length; i++) {
let onceInfo = {};
let subList = dataList[i];
subList.forEach( (info, index) => {
let key = indexKeyNameMap[index + 1];
let checkKey = keyObject[key];
onceInfo[checkKey] = info;
});
result.push(onceInfo);
}
} else {//在x轴上排列
let indexKeyNameMap = {};
dataList.forEach( (info, index) => {
indexKeyNameMap[index + 1] = info[0];
});
let dataMap = {};
for(let y = 0; y < dataList.length; y++) {
let xList = dataList[y];
for (let x = 1; x < xList.length; x++) {
if (!dataMap[x]) dataMap[x] = {};
let key = indexKeyNameMap[y + 1];
let checkKey = keyObject[key];
dataMap[x][checkKey] = xList[x];
}
}
result = Object.values(dataMap);
}
return result;
}
export function analysisExcelDataOfStringList(dataList) {
let result = [];
for (let i = 0; i < dataList.length; i++) {
if (!i) continue;
let subList = dataList[i];
result.push(subList[1]);
}
return result;
}
export function testmain() {
let {sheetMap, sheetList} = getExcel(`${__dirname.substring(0,__dirname.indexOf("out"))}res\\数据模板.xlsx`);
//根据配置表解析成对应数据
let resultMap = {};
for (let sheetName in sheetMap) {
let thisSheetBlockList = getBlockData(sheetMap[sheetName]);
resultMap[sheetName] = thisSheetBlockList;
}
console.log(resultMap);
return resultMap;
}
/**
* getBlockData 数据分块
* @param dataList 解析出来的excel二维数组
* @returns 返回数据块集合 格式:blockList = [ {blockData:数据块(二维数组), blockTitle:"数据标题"}]
*/
function getBlockData(dataList) {
let blockList = [];
for (let i = 0; i < 999; i++) {
let {blockData, blockTitle, notItem, delDataList} = checkBlock(dataList);
if (notItem) break;
dataList = delDataList;
if (blockTitle) blockList.push({blockData, blockTitle});
}
return blockList;
}
function getListFristNotNullItemIndex(list) { //获取起始坐标
if (!list.length) return null;
for (let i = 0; i < list.length; i++) {
if (list[i]) return i;
}
}
function getListFirstNullItemIndex(startX, list) { //获取第一个为空的坐标
if (!list.length) return null;
let checkItem = false;
let firstItemIndex = 0;
for (let i = startX; i <= list.length; i++) {
let item = list[i];
if (!checkItem && item) checkItem = true;
if (checkItem && !item) {
firstItemIndex = i;
break;
}
}
return firstItemIndex;
}
function listRegionIsNull(list, startX, endX) { //指定区间内数据是否未空
let isNull = true;
if ( !list.length ) return isNull;
for (let i = startX; i < endX; i++) {
let item = list[i];
if (item) {
isNull = false;
break;
}
}
return isNull;
}
function thisListNotItem(list) {
for (let i = 0; i < list.length; i++) {
if (list[i]) return false;
}
return true
}
function checkBlock(dataList) {
//纵向有效起始点
let startY = 0;
let startX = 0;
let isNotBlockTitle = false; //没有块标题
let isLook = false;
let endX = 0;//x轴最长结束下标 【包括下标】
let blockTitle = ''; //标题块名称
let notItem = true;
for (let i = 0; i < dataList.length; i++) {
let childList = dataList[i] || [];
if (!thisListNotItem(childList)) {
if ( !isLook ) {
let thisRoowStartX = getListFristNotNullItemIndex(childList);
let thisRoowLastItem = childList[thisRoowStartX + 1];
let LastList = dataList[i+1] || [];
// let lastRoowStartX = getListFristNotNullItemIndex(LastList);
let lastRoowHaveItem = LastList[thisRoowStartX];
if ( thisRoowLastItem || (LastList.length && lastRoowHaveItem) ) {
if (lastRoowHaveItem && thisRoowLastItem ) {
isNotBlockTitle = true; //不存在标题块
blockTitle = `${thisRoowStartX}_${i}`;
startY = i;
startX = thisRoowStartX;
}
else {
blockTitle = dataList[i][thisRoowStartX];
dataList[i][thisRoowStartX] = null;
if ( thisRoowLastItem ) { // 同行存在元素 标题在y轴上
startY = i;
startX = thisRoowStartX + 1;
} else { // 同行存在元素 标题在x轴上
startY = i + 1;
startX = thisRoowStartX;
}
}
isLook = true;
} else { //只有标题 无内容
console.log(dataList[i][thisRoowStartX]);
dataList[i][thisRoowStartX] = null;
}
} else {
//测量最大连续长度
let firstNullX = getListFirstNullItemIndex(startX, childList);
if (firstNullX) endX = Math.max(endX, firstNullX-1);
break;
}
notItem = false;
}
}
let endY = 0;//y轴连续下标 【包括下标】
let yInfoStart = false;
let yInfoEnd = false;
for (let y = startY; y < dataList.length; y++) {
//纵向找连续性
let thisRoow = dataList[y];
let regionIsNull = listRegionIsNull(thisRoow, startX, endX);
if (!regionIsNull) {
endY = y;
if (!yInfoStart) yInfoStart = true;
}
if (yInfoStart && regionIsNull) yInfoEnd = true;
if (yInfoEnd) break;
}
let blockData = [];
for (let y = startY; y <= endY; y++) {
let onceList = [];
for (let x = startX; x <= endX; x++) {
onceList.push(dataList[y][x]);
dataList[y][x] = null;
}
blockData.push(onceList);
}
return {blockData, blockTitle, delDataList:dataList,notItem};
}
//获取单个excel文件的数据
function getExcel(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}
}
\ No newline at end of file
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 * 生成任务id
* @param uscc 企业标识 * @param uscc 企业标识
...@@ -13,4 +16,58 @@ export function getTaskId(uscc:string) { ...@@ -13,4 +16,58 @@ export function getTaskId(uscc:string) {
*/ */
export function getTimeKey() { export function getTimeKey() {
return `${new Date().getFullYear()}${new Date().getMonth() + 1 }` 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