Commit abff7bbf by chenjinjing

项目搭建

parents
.idea
/out
/node_modules
/test
/public
/logs
/video
*.logs
*.zip
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "启动程序",
"program": "${workspaceFolder}/src/main.ts",
"outFiles": [
"${workspaceFolder}/**/*.js"
]
}
]
}
\ No newline at end of file
{
}
\ No newline at end of file
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"霍兰德测试API初始化完成"}
{"level":"info","message":"霍兰德测试API初始化完成"}
{"level":"info","message":"霍兰德测试API初始化完成"}
{"level":"info","message":"霍兰德测试API初始化完成"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"info","message":"答题提交成功"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
{"level":"error","message":"答题提交失败:"}
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "screen",
"version": "1.0.0",
"description": "",
"main": "main.ts",
"dependencies": {
"@alicloud/sms-sdk": "^1.1.6",
"@types/node": "^10.12.18",
"bson": "^6.1.0",
"compression": "^1.7.4",
"connect-history-api-fallback": "^2.0.0",
"express": "^4.21.2",
"express-async-handler": "^1.1.4",
"express-history-api-fallback": "^2.2.1",
"formidable": "^1.2.1",
"log4js": "^6.6.1",
"lru-cache": "^4.1.5",
"md5": "^2.2.1",
"moment": "^2.24.0",
"mongoose": "^7.6.0",
"mysql": "^2.18.1",
"mysql2": "^3.6.0",
"node-xlsx": "^0.16.1",
"nodemailer": "^6.1.1",
"pyfl": "^1.1.4",
"qs": "^6.11.0",
"request": "^2.88.0",
"sequelize": "^6.32.1",
"svg-captcha": "^1.3.12",
"tencentcloud-sdk-nodejs": "^4.0.562",
"winston": "^3.17.0",
"ws": "^5.2.2",
"xml2js": "^0.4.23"
},
"devDependencies": {
"@types/express": "^5.0.0"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "cjj",
"license": "ISC",
"bin": "./out/main.js",
"pkg": {
"scripts": "out/**/*.js",
"assets": [
"public/**/*",
"res/**/*",
"images/**/*",
"video/**/*"
],
"outputPath": "dist"
}
}
File added
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 8099;
server_name 127.0.0.1;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
server {
listen 8098;
server_name 127.0.0.1;
#access_log logs/host.access.log main;
location / {
root html2;
index index.html index.htm;
}
location ^~/api {
# rewrite ^.+api/?(.*)$ /$1 break;
# include uwsgi_params;
proxy_pass http://192.168.1.250:4321;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
server {
listen 8097;
server_name 127.0.0.1;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
location ^~/api {
# rewrite ^.+api/?(.*)$ /$1 break;
# include uwsgi_params;
proxy_pass http://192.168.1.250:4321;
}
location /gettyjr/ {
# rewrite ^.+api/?(.*)$ /$1 break;
# include uwsgi_params;
proxy_pass http://218.78.8.206:40013/gettyjr/;
}
location /getfwjl/ {
# rewrite ^.+api/?(.*)$ /$1 break;
# include uwsgi_params;
proxy_pass http://218.78.8.206:40013/getfwjl/;
}
location /lagou/ {
try_files $uri /lagou/index.html;
root /var/www/html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
<config>
<port>13277</port>
<sign></sign>
<dbServer>http://127.0.0.1:13275</dbServer>
<mysqldb>
<!-- 本地mysql配置 -->
<mysqlHost>192.168.0.71</mysqlHost>
<mysqlPort>3306</mysqlPort>
<mysqlUser>root</mysqlUser>
<mysqlPwd>123456</mysqlPwd>
<dataBase>ljz_answer</dataBase>
<!-- 服务器mysql配置 -->
<!-- <mysqlHost>127.0.0.1</mysqlHost>
<mysqlPort>3306</mysqlPort>
<mysqlUser>root</mysqlUser>
<mysqlPwd>qaz123456</mysqlPwd>
<dataBase>ljz_answer</dataBase> -->
</mysqldb>
<qw>
<url>https://ls.sunyah.com/API/SanLin/SanLin_QueryPost.ashx?appid=98092D9C-0161-4181-9522-8548A9B14BC8</url>
<page>1</page>
<size>200</size>
</qw>
</config>
import moment from "moment";
import { TABLENAME } from "../config/dbEnum";
import { selectDataCountByParam, selectDataListByParam, selectDataListToPageByParam, selectOneDataByParam } from "../data/findData";
import { CHAPTER, HLDTYPE, HUOLANDE, QUESTION, TESTTYPE } from "../config/enum";
import { changeEnumValue } from "../tools/eccEnum";
import { BizError } from "../util/bizError";
import { ERRORENUM } from "../config/errorEnum";
/**
* 登录
* @param username
* @param password
*/
export async function login(username, password) {
let findUserData = await selectOneDataByParam(TABLENAME.超级管理员表, {username, password}, []);
let findUser = findUserData.data;
if (!findUser || !findUser.username) throw new BizError(ERRORENUM.账号或密码错误);
if (findUser.password != password ) throw new BizError(ERRORENUM.账号或密码错误);
let dataInfo = {
username: findUser.username,
realName: findUser.real_name,
phone: findUser.phone,
sex: findUser.sex,
mail: findUser.mail,
remark: findUser.remark
};
return dataInfo;
}
/**
* 获取用户列表
* @param card
* @param createStartTime
* @param createEndTime
* @param area
* @param current
* @returns
*/
export async function getUserList(phone, createStartTime, createEndTime, current) {
let selectParam = {"name":{"%ne%":"测试"}, "phone":{"%ne%":"17255558888"}};
if (phone) selectParam["phone"] = phone;
if (createStartTime && createEndTime) selectParam["test_date"] = {"%between%":[createStartTime, createEndTime]};
let findData = await selectDataListToPageByParam(TABLENAME.测试信息表, selectParam, ["infoid", "name", "card", "phone", "email", "area", "create_time", "test_date", "test_type", "last_update_time"], current, 10);
let dataCount = await selectDataCountByParam(TABLENAME.测试信息表, selectParam);
let dataList = [];
for (let i = 0; i < findData.data.length; i++) {
let info = findData.data[i];
let {infoid, name, card, phone, email, area, create_time, test_type, last_update_time, test_date} = info;
let inforecordData = await selectDataListByParam(TABLENAME.测试信息记录表, {infoid, test_type}, []);
if (inforecordData.data.length) {
dataList.push({
infoid, name, card, phone, email, area,
createTime: moment(test_date).format("YYYY-MM-DD HH:mm:ss"),
testType: test_type
})
}
}
return {dataList, dataCount:dataCount.data};
}
/**
* 查看列表详情
* @param infoid
* @param test_type
* @returns
*/
export async function getUserInfoById(infoid, test_type) {
let testReport = {};
if (test_type == TESTTYPE.创业) {
testReport = await getChuangYe(infoid);
} else if (test_type == TESTTYPE.霍兰德) {
testReport = await getHuoLanDe(infoid);
}
return testReport;
}
/**
* 创业答题详情
* @param infoid
* @returns
*/
async function getChuangYe(infoid) {
let findUserData = await selectOneDataByParam(TABLENAME.测试信息表, {infoid, test_type:2}, []);
let findData = await selectDataListByParam(TABLENAME.测试信息记录表, {infoid, test_type:2}, []);
let optionsInfo = [];
let score = 0;
for (let data = 0; data < findData.data.length; data++) {
let info = findData.data[data];
let {chapter, title_str, option_str} = info;
// optionsInfo[chapter] = {};
let title = JSON.parse(title_str);
let option = JSON.parse(option_str);
for (let i = 0; i < option.length; i++) {
let optionList = option[i];
let optionName = "";
for (let o = 0; o < optionList.length; o++) {
let findOption = await selectOneDataByParam(TABLENAME.题目选项表, {oid:optionList[o]}, []);
score += findOption.data["points"];
optionName = findOption.data["option_name"].slice(2);
}
optionsInfo.push({title:title[i], option:optionName});
}
}
let testReport = {
name:findUserData.data.name,
card:findUserData.data.card,
phone:findUserData.data.phone,
score,
time: moment(findUserData.data.test_date).format("YYYY年MM月DD日HH时mm分"),
report:optionsInfo,
};
return testReport;
}
/**
* 霍兰德详情
* @param infoid
* @returns
*/
async function getHuoLanDe(infoid) {
let findUserData = await selectOneDataByParam(TABLENAME.测试信息表, {infoid, test_type:1}, []);
let findData = await selectDataListByParam(TABLENAME.测试信息记录表, {infoid, test_type:1}, []);
let optionsInfo = {};
for (let data = 0; data < findData.data.length; data++) {
let info = findData.data[data];
let {chapter, title_str, option_str} = info;
optionsInfo[chapter] = {};
let title = JSON.parse(title_str);
let option = JSON.parse(option_str);
for (let i = 0; i < option.length; i++) {
let optionList = option[i];
let score = 0;
for (let o = 0; o < optionList.length; o++) {
let findOption = await selectOneDataByParam(TABLENAME.题目选项表, {oid:optionList[o]}, []);
score += findOption.data["points"];
}
optionsInfo[chapter][title[i]] = score;
}
}
let optionData = [];
let countInfo = {};
for (let key in optionsInfo) {
let maxKey = "";
let maxValue = 0;
for (let values in optionsInfo[key]) {
const value = optionsInfo[key][values];
if (value > maxValue) {
maxKey = values;
maxValue = value;
}
if(!countInfo[values]) countInfo[values] = 0
countInfo[values] += value;
}
let title = changeEnumValue(CHAPTER, parseInt(key));
let maxNum = HLDTYPE[maxKey];
optionData.push({key:title, value:maxKey, index:maxNum});
}
let countData = [];
for (let key in countInfo) {
let keyNum = HLDTYPE[key];
let keyName = changeEnumValue(QUESTION, keyNum);
countData.push({key:keyName, value:countInfo[key]});
}
let sortedEntries:any = Object.entries(countInfo);
sortedEntries.sort((a, b) => b[1] - a[1]);
let topThreeKeys = sortedEntries.slice(0, 3).map(entry => entry[0]);
let topThreeStr = topThreeKeys.join("");
// let findCareer = await selectOneDataByParam(TABLENAME.职业对照表, {statistics:topThreeStr}, []);
let selectParam = {"%literal%":``};
topThreeKeys.forEach( info => {
if (!selectParam["%literal%"]) selectParam["%literal%"] = `statistics REGEXP '[${info}]' `;
selectParam["%literal%"] += `and statistics REGEXP '[${info}]' `;
})
let findCareer = await selectDataListByParam(TABLENAME.职业对照表, selectParam, []);
let testReport = {
name:findUserData.data.name,
card:findUserData.data.card,
phone:findUserData.data.phone,
time: moment(findUserData.data.test_date).format("YYYY年MM月DD日HH时mm分"),
report1:optionData,
report2:countData,
statistics:topThreeStr,
recommend:""
}
findCareer.data.forEach( info => {
testReport.recommend += info.recommend;
})
if (!testReport.recommend) {
for (let i = 0; i < topThreeStr.length; i++) {
testReport.recommend += HUOLANDE[topThreeStr[i]];
}
}
return testReport;
}
/**
* 数据导出
* @param card
* @param createStartTime
* @param createEndTime
* @param area
* @param current
* @returns
*/
export async function outPutData(card, createStartTime, createEndTime, area) {
let selectParam = {"name":{"%ne%":"362527199309194932"}, "phone":{"%ne%":"17255558888"}};
// let selectParam = {};
if (card) selectParam["card"] = card;
if (createStartTime && createEndTime) selectParam["test_date"] = {"%between%":[createStartTime, createEndTime]};
if (area) selectParam["area"] = area;
let findData = await selectDataListByParam(TABLENAME.测试信息表, selectParam, ["infoid", "name", "card", "phone", "email", "area", "create_time", "test_type", "last_update_time", "test_date"]);
let dataTitle = ["姓名", "身份证号", "联系方式", "电子邮箱", "所属区域", "测试日期", "测评类型"];
let dataList = [dataTitle];
findData.data.forEach( info => {
let {name, card, phone, email, area, create_time, test_type, last_update_time, test_date} = info;
let createTime = moment(test_date).format("YYYY-MM-DD HH:mm:ss");
let testType = changeEnumValue(TESTTYPE, test_type);
let subList = [
name || "",
card || "",
phone || "",
email || "",
area || "",
createTime || "",
testType || ""
];
dataList.push(subList);
})
return dataList;
}
/**
* 岗位信息
*/
import { ERRORENUM } from "../config/errorEnum";
import { systemConfig } from "../config/serverConfig";
import { employmentTableData } from "../data/table/employment";
import { BizError } from "../util/bizError";
import { get } from "../util/request";
let fs = require("fs");
/**缓存区网数据 */
// let qwJobInfo;
// export async function getQwData() {
// let qwPostList = await get(systemConfig.qwUrl);
// if(!qwPostList || !qwPostList['body'] || !qwPostList['body']['PostList']) throw new BizError(ERRORENUM.接口数据获取失败, `区网岗位信息列表获取接口失败`);
// else qwJobInfo = qwPostList['body']['PostList'];
// }
/**
* 竖屏岗位信息
* @param req
* @param res
*/
export function getVerticalScreen(req, res) {
let name = req.body.name;
// let name = null;
let tableData = employmentTableData();
//'gsmc:公司名称', 'gwmc:岗位名称', 'xlyq:学历要求', 'nlfw:年龄范围', 'zprs:招聘人数', 'fbsj:发布时间', 'xzdy:薪资待遇',
//'gzsj:工作时间', 'gzdd:工作地点', 'gwyq:岗位要求', 'gwzz:岗位职责'
let ret:any = {};
let oldConf = ['gwmc', 'zprs', 'zpjd', 'fbsj', 'lggw', 'tyjryx', 'syyhg'];
tableData['招聘岗位信息'].dataList.sort((a, b) => {
return Date.parse(b.fbsj) - Date.parse(a.fbsj);
})
let newConf = ['岗位名称', '招聘人数', '招聘进度', '发布时间', '零工岗位', '退役军人优先', '生育友好岗'];
let jobTableDataList = change(oldConf, newConf, tableData['招聘岗位信息'].dataList, name, 'gwmc');
ret['jobInformation'] = jobTableDataList;
res.send(ret);
}
/**
* 竖屏岗位详情
* @param req
* @param res
*/
export function getVerticalJobDetailed(req, res) {
let company = req.body.company;
if (!company) throw new BizError(ERRORENUM.参数错误, `缺失竖屏岗位详情===>company参数`);
let tableData = employmentTableData();
let ret:any = {};
let oldConf = ['gwmc', 'zprs', 'fbsj', 'xzdy', 'gzsj', 'gzdd', 'gwzz', 'lggw', 'tyjryx', 'syyhg'];
let newConf = ['岗位名称', '招聘人数', '发布时间', '薪资待遇', '工作时间', '工作地点', '岗位职责', '零工岗位', '退役军人优先', '生育友好岗'];
let jobDetailed = change(oldConf, newConf, tableData['招聘岗位信息'].dataList, company, 'gsmc');
ret['jobDetailed'] = jobDetailed;
res.send(ret);
}
/**
* 政策文件
* @param req
* @param res
*/
export function getVerticalPolicy(req, res) {
let ret:any = {};
let zcwjInfo = fs.readdirSync('img/政策图片');
let policyInfo = [];
for (let i = 0; i < zcwjInfo.length; i++) {
let fileName = 'img/政策图片/' + zcwjInfo[i];
let list = fs.readdirSync(fileName);
let fileList = [];
for (let file = 0; file < list.length; file++) {
fileList.push(`/政策图片/${zcwjInfo[i]}/${list[file]}`)
}
policyInfo.push({name: zcwjInfo[i], list:fileList});
}
ret['policy'] = policyInfo;
res.send(ret);
}
/**
* 大屏区网岗位信息
* @param req
* @param res
*/
export async function getQWLargeScreen(req, res) {
let ret:any = {};
let qwPostList = await get(systemConfig.qwUrl);
if(!qwPostList || !qwPostList['PostList']) throw new BizError(ERRORENUM.接口数据获取失败, `区网岗位信息列表获取接口失败`);
let qwJobInfo = qwPostList['PostList'];
let qwJobInformation = {dataList: [], total: qwPostList['TotalRecord']};
qwJobInfo.forEach( info => {
let qwList = [];
qwList.push(
{
key: '岗位编码',
value: info.PostCode
},
{
key: '公司名称',
value: info.UnitName
},
{
key: "岗位名称",
value: info.PostName
},
{
key: '招聘人数',
value: info.RecruitmentPersonCount
},
{
key: '发布时间',
value: info.CreateDateText
}
)
let jobDetailed = {name:"", list:[]};
let {UnitName, PostName, View_Education, View_Salary, View_AgeRange, View_WorkArea, View_PostDescriptionC, View_PostDescriptionB,
View_PostDescriptionA, View_WorkNature, WorkClass, PostCode} = info;
jobDetailed.name = UnitName;
jobDetailed.list.push(
// {
// key: '公司名称',
// value: info.UnitName
// },
{
key: '招聘岗位',
value: PostName
},
{
key: '岗位职责',
value: View_PostDescriptionA
},
{
key: '工作性质',
value: View_WorkNature
},
{
key: '工作时间',
value: WorkClass||'暂无'
},
{
key: '工资待遇',
value: View_Salary
},
{
key: '工作地点',
value: View_WorkArea + View_PostDescriptionC
},
{
key: '岗位编码',
value: PostCode
},
)
qwJobInformation.dataList.push({base:qwList, detailed:jobDetailed});
})
ret['qwJobInformation'] = qwJobInformation;
res.send(ret);
}
/**
* 大屏塘桥岗位信息
* @param req
* @param res
*/
export function getPXLargeScreen(req, res) {
let tableData = employmentTableData();
let ret:any = {};
let oldConf = ['gsmc', 'zprs', 'fbsj', 'lggw', 'tyjryx', 'syyhg'];
let newConf = ['公司名称', '招聘人数', '发布时间', '零工岗位', '退役军人优先', '生育友好岗'];
tableData['招聘岗位信息'].dataList.sort((a, b) => {
return Date.parse(b.fbsj) - Date.parse(a.fbsj);
})
let jobTableDataList = change(oldConf, newConf, tableData['招聘岗位信息'].dataList, '', 'gwmc');
let jobTableData = [];
jobTableDataList.forEach(info => {
let {name, list} = info;
let recruit = {key:'', value:0};
for (let i = 0; i < list.length; i++) {
recruit['key'] = '招聘人数';
// console.log(list[i][1].value);
// console.log(isNaN(list[i][1].value));
if(isNaN(list[i][1].value)) {
recruit['value'] = list[i][1].value;
break;
}
else recruit['value'] += parseInt(list[i][1].value);
}
let dataList = [list[0][0], recruit, list[0][2], list[0][3], list[0][4], list[0][5]];
jobTableData.push(dataList)
})
console.log(jobTableData);
ret['jobInformation'] = jobTableData;
res.send(ret);
}
/**
* 大屏塘桥岗位详情
* @param req
* @param res
*/
export function getPXJobDetailed(req, res) {
let company = req.body.company;
if (!company) throw new BizError(ERRORENUM.参数错误, `缺失竖屏岗位详情===>company参数`);
let tableData = employmentTableData();
let ret:any = {};
let oldConf = ['gwmc', 'gwzz', 'gzsj', 'xzdy', 'gzdd', 'lggw', 'tyjryx', 'syyhg'];
let newConf = ['招聘岗位', '岗位职责', '工作时间', '工资待遇', '工作地点', '零工岗位', '退役军人优先', '生育友好岗'];
let jobDetailed = change(oldConf, newConf, tableData['招聘岗位信息'].dataList, company, 'gsmc');
ret['jobDetailed'] = jobDetailed;
res.send(ret);
}
/**
* 修改数据结构
* @param oldConf 表格数据原本的key
* @param newConf 需要修改成的中文key
* @param dataList 表格数据
* @param name 匹配数据的参数
* @param subName 参数匹配数据的字段key
* @returns
*/
export function change(oldConf, newConf, dataList, name, subName){
let reg = new RegExp(name);
let data = {};
dataList.forEach((subList) => {
if (reg.test(subList[subName]) || name == subList[subName]) {
if (!data[subList['gsmc']]) data[subList['gsmc']] = [];
let gsList = [];
for(let i = 0; i < newConf.length; i++) {
if (newConf[i] == "招聘进度") {
gsList.push({
key: newConf[i],
value: '招聘中'
})
} else {
gsList.push({
key: newConf[i],
value: subList[oldConf[i]] || ""
})
}
}
data[subList['gsmc']].push(gsList);
}
});
let result = [];
for (let key in data) {
result.push({
name: key,
list: data[key]
})
}
return result;
}
/**
* 霍兰德
*/
import moment from "moment";
import { TABLENAME } from "../config/dbEnum";
import { CHAPTER, HLDTYPE, HUOLANDE, QUESTION, QUESTIONTITLE, TESTTYPE } from "../config/enum";
import { ERRORENUM } from "../config/errorEnum";
import { addData } from "../data/addData";
import { selectDataListByParam, selectDataToTableAssociation, selectDataToTableAssociationToPage, selectOneDataByParam } from "../data/findData";
import { changeEnumValue, eccEnumValue } from "../tools/eccEnum";
import { BizError } from "../util/bizError";
import { updateManyData } from "../data/updateData";
/**
* 个人信息填写
* @param test_type 题目类型:1. 霍兰德 2. 创业
* @param card
* @param name
* @param phone
* @param area
* @param email 非必填,没有传null
* @returns
*/
export async function addUsers(testType, name, phone, card?) {
let findCardData = await selectOneDataByParam(TABLENAME.测试信息表, {test_type:testType, name, phone}, []);
// if (findCardData.data.core) throw new BizError(ERRORENUM.该身份证号码重复);
let addcyParam:any = {
test_type:testType,
name,
phone,
test_date:moment(new Date()).format("YYYY-MM-DD HH:mm:ss")
};
if (card) addcyParam.card = card;
if (!findCardData.data.phone) {
await addData(TABLENAME.测试信息表, addcyParam);
} else {
await updateManyData(TABLENAME.测试信息表, {test_type:testType, name, phone}, addcyParam);
}
// let addhldParam = {
// test_type:TESTTYPE.霍兰德,
// name,
// phone,
// test_date:moment(new Date()).format("YYYY-MM-DD 00:00:00")
// };
// if (card) addhldParam[card] = card;
// if (!findCardData.data.phone) {
// await addData(TABLENAME.测试信息表, addhldParam);
// } else {
// await updateManyData(TABLENAME.测试信息表, {test_type:testType, phone}, addhldParam);
// }
let userInfo = await selectOneDataByParam(TABLENAME.测试信息表, {test_type:testType, phone}, ["infoid", "name", "test_date"]);
return userInfo.data;
}
/**
* 下拉选择所属区域
*/
export async function getArea() {
let findData = await selectDataListByParam(TABLENAME.省市区表, {pid:"310100"}, ["id", "name"]);
return findData.data;
}
/**
* 获取题目
* @param test_type 题目类型:1. 霍兰德 2. 创业
* @param chapter 章节
* 1.霍兰德(一、我感兴趣的活动)2.霍兰德(二、我能完成的活动)3.霍兰德(三、我喜欢的职业)
* 4.霍兰德(四、我的能力类型简评A)5.霍兰德(四、我的能力类型简评B)
* 6.创业(技能)7.创业(经验)8.创业(您开办的新创业组织)9.创业(创办企业)10.符合你的特点
* @param isTest 是否演示版 0:否 1:是
* @returns
*/
export async function getQuestion(testType, chapter, isTest, isPrevious?) {
if(!testType) testType = 1;
eccEnumValue("获取题目", "test_type", TESTTYPE, testType);
eccEnumValue("获取题目", "chapter", CHAPTER, chapter);
let selectParam:any = {};
if (testType == TESTTYPE.霍兰德) selectParam = {is_del:0, test_type:1, chapter:1};
else if (testType == TESTTYPE.创业) selectParam = {is_del:0, test_type:2, chapter:6};
if (testType) selectParam.test_type = testType;
if (chapter) selectParam.chapter = chapter;
/** includeConf:关联表配置*/
let includeConf = {};
includeConf[TABLENAME.题目选项表] = {colum:["option_name", "points"], where:{is_del:0} }; // colum:关联表需要查询的字段,where:关联表查询条件
/** questionInfo:多表联查*/
let questionInfo = await selectDataToTableAssociation(TABLENAME.题目表, includeConf, selectParam, ["qid", "sort", "chapter", "title"]);
let questionData = [];
questionInfo.data.forEach( info => {
let {qid, title, options} = info;
let optionList = [];
options.forEach( option => {
let {sort, oid, option_name, points} = option;
optionList.push({oid, optionName:option_name, points, sort});
})
let chapter = changeEnumValue(CHAPTER, info.chapter);
questionData.push({sort:info.sort, qid, chapter, title, option:optionList})
})
if (!isPrevious) {
if (testType == TESTTYPE.创业) questionData = getRandomQuestions(questionData, chapter);
if (isTest == 1) questionData = getRandomQuestions(questionData, chapter, isTest);
} else {
questionData = [];
for (let i = 0; i < isPrevious.length; i++) {
let questionInfo = await selectDataToTableAssociation(TABLENAME.题目表, includeConf, {qid:isPrevious[i]}, ["qid", "sort", "chapter", "title"]);
questionInfo.data.forEach( info => {
let {qid, title, options} = info;
let optionList = [];
options.forEach( option => {
let {sort, oid, option_name, points} = option;
optionList.push({oid, optionName:option_name, points, sort});
})
let chapter = changeEnumValue(CHAPTER, info.chapter);
questionData.push({sort:info.sort, qid, chapter, title, option:optionList})
})
}
}
return questionData;
}
/**
* 添加测试信息记录
* @param infoid 测试用户id
* @param chapter 章节 一个章节一条数据
* @param option [{ qid:1, answerIds:[1,2,3] }, { qid:2, answerIds:[4,5,6] }, ......]
* @param test_type 题目类型:1. 霍兰德 2. 创业
* @param isTest 是否演示版 0:否 1:是
*/
export async function addUsersInfo(infoid, chapter, option, testType, isTest) {
// if(findData.data && findData.data.length) throw new BizError("不可重复提交"); //判断一个用户一个章节答题不可重复提交
let addParam = {infoid, chapter, test_type:testType, title_str:"", option_str:""}
let optionData = JSON.parse(option);
let title_str = [];
let option_str = [];
for(let i = 0; i < optionData.length; i++) {
let info = optionData[i];
let {qid, answerIds} = info;
let findData = await selectOneDataByParam(TABLENAME.题目表, {qid}, []);
let title = "";
if (testType == TESTTYPE.霍兰德) title = findData.data["title"].charAt(0);
else if (testType == TESTTYPE.创业) title = findData.data["title"];
title_str.push(title);
option_str.push(answerIds);
}
addParam.title_str = JSON.stringify(title_str);
addParam.option_str = JSON.stringify(option_str);
if (isTest == 1) {
let findData = await selectDataListByParam(TABLENAME.演示版测试信息记录表, {infoid, chapter}, []);
if (findData.data && findData.data.length) {
await updateManyData(TABLENAME.演示版测试信息记录表, {infoid, chapter}, addParam);
} else {
await addData(TABLENAME.演示版测试信息记录表, addParam);
}
}
else if (isTest == 0) {
let findData = await selectDataListByParam(TABLENAME.测试信息记录表, {infoid, chapter}, []);
if (findData.data && findData.data.length) {
await updateManyData(TABLENAME.测试信息记录表, {infoid, chapter}, addParam);
} else {
await addData(TABLENAME.测试信息记录表, addParam);
}
}
return {isSuccess:true};
}
/**
* 霍兰德 获取分数
* @param infoid 测试用户id
* @param isTest 是否演示版 0:否 1:是
*/
export async function getFinalScore(infoid, isTest) {
let findUserData = await selectOneDataByParam(TABLENAME.测试信息表, {infoid}, []);
let findData:any = {};
if (isTest == 1) findData = await selectDataListByParam(TABLENAME.演示版测试信息记录表, {infoid, test_type:1}, []);
else if (isTest == 0) findData = await selectDataListByParam(TABLENAME.测试信息记录表, {infoid, test_type:1}, []);
let optionsInfo = {};
for (let data = 0; data < findData.data.length; data++) {
let info = findData.data[data];
let {chapter, title_str, option_str} = info;
optionsInfo[chapter] = {};
let title = JSON.parse(title_str);
let option = JSON.parse(option_str);
for (let i = 0; i < option.length; i++) {
let optionList = option[i];
let score = 0;
for (let o = 0; o < optionList.length; o++) {
let findOption = await selectOneDataByParam(TABLENAME.题目选项表, {oid:optionList[o]}, []);
score += findOption.data["points"];
}
optionsInfo[chapter][title[i]] = score;
}
}
let optionData = [];
let countInfo = {};
for (let key in optionsInfo) {
let maxKey = "";
let maxValue = 0;
for (let values in optionsInfo[key]) {
const value = optionsInfo[key][values];
if (value > maxValue) {
maxKey = values;
maxValue = value;
}
if(!countInfo[values]) countInfo[values] = 0
countInfo[values] += value;
}
let title = changeEnumValue(CHAPTER, parseInt(key));
let maxNum = HLDTYPE[maxKey];
optionData.push({key:title, value:maxKey, index:maxNum});
}
let countData = [];
for (let enumkey in HLDTYPE) {
let anyKey: any = enumkey;
let keyNum = 0;
let keyName = changeEnumValue(QUESTION, HLDTYPE[enumkey]);
if (isNaN(anyKey)) {
if (countInfo[enumkey]) keyNum = countInfo[enumkey];
countData.push({key:keyName, value:keyNum});
}
}
let sortedEntries:any = Object.entries(countInfo);
sortedEntries.sort((a, b) => b[1] - a[1]);
let topThreeKeys = sortedEntries.slice(0, 3).map(entry => entry[0]);
let topThreeStr = topThreeKeys.join("");
// let selectParam = {"$and":[]};
// topThreeKeys.forEach( info => {
// selectParam["$and"].push({"statistics":{"%regexp%":`[${info}]`}});
// })
let selectParam = {"%literal%":``};
topThreeKeys.forEach( info => {
if (!selectParam["%literal%"]) selectParam["%literal%"] = `statistics REGEXP '[${info}]' `;
selectParam["%literal%"] += `and statistics REGEXP '[${info}]' `;
})
let findCareer = await selectDataListByParam(TABLENAME.职业对照表, selectParam, []);
let time = moment(new Date()).format("YYYY年MM月DD日HH时mm分");
let testReport = {
name:findUserData.data.name,
time,
report1:optionData,
report2:countData,
statistics:topThreeStr,
recommend:""
}
findCareer.data.forEach( info => {
testReport.recommend += info.recommend;
})
if (!testReport.recommend) {
for (let i = 0; i < topThreeStr.length; i++) {
testReport.recommend += HUOLANDE[topThreeStr[i]];
}
}
return testReport;
}
/**
* 创业 获取分数
* 评分标准为:A.5分;B.4分;C. 3分;D.2分;E.1分
* @param infoid 测试用户id
* @returns 姓名、分数、所有题目和所选答案
*/
export async function getChuangYeScore(infoid, isTest) {
let findUserData = await selectOneDataByParam(TABLENAME.测试信息表, {infoid}, []);
let findData:any = {};
if (isTest == 1) findData = await selectDataListByParam(TABLENAME.演示版测试信息记录表, {infoid, test_type:2}, []);
else if (isTest == 0) findData = await selectDataListByParam(TABLENAME.测试信息记录表, {infoid, test_type:2}, []);
let optionsInfo = [];
let score = 0;
for (let data = 0; data < findData.data.length; data++) {
let info = findData.data[data];
let {chapter, title_str, option_str} = info;
// optionsInfo[chapter] = {};
let title = JSON.parse(title_str);
let option = JSON.parse(option_str);
for (let i = 0; i < option.length; i++) {
let optionList = option[i];
let optionName = "";
for (let o = 0; o < optionList.length; o++) {
let findOption = await selectOneDataByParam(TABLENAME.题目选项表, {oid:optionList[o]}, []);
score += findOption.data["points"];
optionName = findOption.data["option_name"].slice(2);
}
optionsInfo.push({title:title[i], option:optionName});
}
}
let testReport = {
score,
name:findUserData.data.name,
time: moment(new Date()).format("YYYY年MM月DD日HH时mm分"),
report:optionsInfo,
}
if (isTest == 1) testReport.score = 91;
return testReport;
}
/**
* 创业 根据不同章节返回不同数量的题目
* 题目抽取比例为:技能取3题;经验取4题;您开办的新创业组织取5题;创办企业取8题;以下的每一条描述,你觉得它在多大程度上符合你的特点取10题
* @param data
* @param chapter 章节
* @returns
*/
function getRandomQuestions(data, chapter, isTest?) {
let numberOfQuestions = 0;
if (chapter == CHAPTER.技能) numberOfQuestions = 3;
else if (chapter == CHAPTER.经验) numberOfQuestions = 4;
else if (chapter == CHAPTER.您开办的新创业组织) numberOfQuestions = 5;
else if (chapter == CHAPTER.创办企业) numberOfQuestions = 8;
else if (chapter == CHAPTER.符合你的特点) numberOfQuestions = 10;
if (isTest == 1) numberOfQuestions = 1;
// 使用 Fisher-Yates 洗牌算法打乱数组
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]]; // 交换元素
}
return array;
}
// 打乱数据集
const shuffledData = shuffleArray([...data]);
// 返回打乱后的前 numberOfQuestions 个条目
return shuffledData.slice(0, numberOfQuestions);
}
/**大屏弹窗标识-退役军人 */
import { getHzdw, getJyfwjl, getPopup, getTyjrxm } from "../data/table/employment";
import { keyValuePackage } from "../dataPackage/inFrontOut";
import { getKeyValueOut } from "../dataPackage/out";
const CJWNAME = {
"巨峰":"巨峰居委",
"证一":"证大第一居委",
"证二":"证大第二居委",
"双桥":"双桥居委",
"凌八":"凌河路八居委",
"荷一":"荷泽路一居委",
"凌四":"凌河路四居委",
"凌一":"凌河路第一居委",
"凌二":"凌河路二居委",
"凌三":"凌河路三居委",
"凌五":"凌河路五居委",
"凌七":"凌河路七居委",
"凌六":"凌河路第六居委",
"东一":"东陆路一居委",
"东二":"东陆路二居委",
"东荷":"东荷居委",
"东五":"东陆路五居委",
"龙臣":"龙臣居委",
"金鹏":"金鹏居委",
"荷三":"荷泽路三居委",
"东三":"东陆路三居委",
"东四":"东陆路四居委",
"牟平":"牟平居委",
"银桥":"银桥居委",
"金桥湾":"金桥湾居委",
"金泽苑":"金泽苑居委",
"中大":"中大居委",
"浦一":"浦兴路一居委",
"浦二":"浦兴路第二居委",
"浦三":"浦兴路三居委",
"金东":"金东居委",
"长岛":"长岛路居委",
"台儿庄":"台儿庄居委",
"平度":"平度居委",
"胶一":"胶东路第一居委",
"胶二":"胶东路第二居委",
"胶三":"胶东路第三居委",
"金桥":"金桥居委",
"金鑫":"金鑫居委",
"荷五":"荷泽路五居委",
}
const newDate = new Date().getFullYear();
let jyfwjlTableData = getJyfwjl(newDate);
// let lastYearJyfwjl = getJyfwjl(newDate-1); //2023年记录
// lastYearJyfwjl["服务记录"].dataList.forEach( item => {
// jyfwjlTableData["服务记录"].dataList.push(item);
// })
let jyfwjl = {};
let jyfwjlData = jyfwjlTableData["服务记录"].dataList;
jyfwjlData.forEach( info => {
if (!jyfwjl[info.sfz]) jyfwjl[info.sfz] = [];
jyfwjl[info.sfz].push(info);
})
/**
* 大屏村居委弹窗
* @param req
* @param res
*/
export function getTyjr(req, res) {
let cjw = req.query.cjw || '平度居委';
let type = req.query.type || '就业困难人员';
let tableData = getPopup(type);
let tyjrxmTableData = getTyjrxm();
let ret:any = {};
let tyjrTableData = tableData[`${type}`].dataList;
let tyjrData = tyjrxmTableData['退役军人'].dataList; //退役军人名单
let oldConf = [ "xh", "xm", "xb", "sfzh", "nl", "ssjz", "cjw", "mqzk", "hjdz", "rylb", "whcd", "gld", "zxgxsj", "lxdh", "sjhm", "fwcs"];
let newConf = ['序号', '姓名', '性别', '身份证号', '年龄', '所属街镇', '村居委', '目前状况', '户籍地址', '人员类别', '文化程度', '管理地', '最新更新时间', '联系电话', '手机号码', '服务次数'];
let fwcsData = {};
tyjrTableData.forEach( subList => {
subList["fwcs"] = 1;
fwcsData[subList.sfzh] = subList;
if(jyfwjl[subList.sfzh]) fwcsData[subList.sfzh]["fwcs"] = jyfwjl[subList.sfzh].length;
else fwcsData[subList.sfzh]["fwcs"] = 0;
});
let reg = new RegExp(CJWNAME[cjw]);
let tyjrPopData = [];
for(let sfz in fwcsData) {
if (reg.test(fwcsData[sfz]["cjw"])) {
let gsList = {};
for(let i = 0; i < newConf.length; i++) {
gsList[newConf[i]] = fwcsData[sfz][oldConf[i]];
}
gsList["是否退役军人"] = "否";
gsList["cardId"] = gsList["身份证号"];
gsList["身份证号"] = gsList["身份证号"].slice(0, 14)+"****";
tyjrData.forEach( info => {
let {key, value} = info;
if (sfz == value) {
gsList["是否退役军人"] = "是";
tyjrPopData.unshift(gsList);
}
});
tyjrPopData.push(gsList);
}
}
ret["tcsj"] = tyjrPopData;
res.send(ret);
}
/**
* 就业服务记录二级弹窗表格
* @param req
* @param res
*/
export function getFwjl(req, res) {
//cardId
let cardId = req.query.cardId || '';
let ret:any = {};
let jyfwData = jyfwjl[cardId];
let jyfw = [];
jyfwData.forEach( info => {
let fwsj = new Date(info.fwsj).valueOf();
info["changefwsj"] = fwsj;
jyfw.push(info);
})
jyfw.sort( (a, b) => {
return b.changefwsj - a.changefwsj;
})
ret["jyfw"] = jyfw;
res.send(ret);
}
/**
* 合作单位数据
* @param req
* @param res
*/
export function getHzdwsj(req, res) {
let tableData = getHzdw();
let ret:any = {};
let hzdwData = tableData['合作单位数据'].dataList;
let hzdw = [];
hzdwData.forEach( info => {
hzdw.push(info.value);
})
ret['hzdw'] = {title:'合作单位', count:hzdw.length, dataList:hzdw};
res.send(ret);
}
/**
* 标题数据
*/
import { titleTableData } from "../data/table/employment";
import { keyValuePackage } from "../dataPackage/inFrontOut";
import { getStringOut } from "../dataPackage/out";
/**
* 大屏标题
* @param req
* @param res
*/
export function getLargeScreenTitle(req, res) {
let tableData = titleTableData();
let ret:any = {};
let largeScreenPackageData = keyValuePackage(tableData['大屏标题信息'].dataList);
ret['largeScreen'] = getStringOut('大屏标题信息', largeScreenPackageData);
res.send(ret);
}
/**
* 竖屏标题
* @param req
* @param res
*/
export function getVerticalScreenTitle(req, res) {
let tableData = titleTableData();
let ret:any = {};
let verticalScreenPackageData = keyValuePackage(tableData['竖屏标题信息'].dataList);
ret['verticalScreen'] = getStringOut('竖屏标题信息', verticalScreenPackageData);
res.send(ret);
}
/**
* 请求数据中心类型
*/
export enum OPERATIONALDATATYPE {
增加 = '/puxin/dataserver/mysql/table/add',
修改 = '/puxin/dataserver/mysql/table/update',
删除 = '/puxin/dataserver/mysql/table/delete',
查询单个 = '/puxin/dataserver/mysql/table/find/one',
查询多个 = '/puxin/dataserver/mysql/table/find/many',
分页查询 = '/puxin/dataserver/mysql/table/find/manytopage',
查询数据量 = '/puxin/dataserver/mysql/table/find/count',
多表联查 = '/puxin/dataserver/mysql/table/find/aggragate',
多表分页 = '/puxin/dataserver/mysql/table/find/aggragatetopage',
多表单个 = '/puxin/dataserver/mysql/table/find/aggragateone'
}
/**
* 表名
*/
export enum TABLENAME {
省市区表 = 'area',
题目表 = 'question',
题目选项表 = 'option',
测试信息表 = 'testinfo',
测试信息记录表 = 'inforecord',
演示版测试信息记录表 = 'inforecord_test',
职业对照表 = 'career_contrast',
超级管理员表 = 'sys_user',
}
export enum OPERATIONTYPEENUM {
= 1,
,
,
}
/**上传文件类型 */
export enum FILETYPE {
word = 1,
pdf,
图片,
视频,
多类型
}
export enum TESTTYPE {
"霍兰德" = 1,
"创业" = 2,
}
/**
* 题目大标题
*/
export enum CHAPTER {
"一、我感兴趣的活动(多选)" = 1,
"二、我能完成的活动(多选)" = 2,
"三、我喜欢的职业(多选)" = 3,
"四、我的能力类型简评A(单选)" = 4,
"四、我的能力类型简评B(单选)" = 5,
"技能" = 6,
"经验" = 7,
"您开办的新创业组织" = 8,
"创办企业" = 9,
"符合你的特点" = 10
}
/**
* 题型
*/
export enum QUESTIONTITLE {
"R:实际型活动" = 1,
"S:社会型活动" = 2,
"I:研究型活动" = 3,
"E:事业型活动" = 4,
"A:艺术型活动" = 5,
"C:常规型(传统型)活动" = 6,
}
// "R:实际型活动" = 1,
// "S:社会型活动" = 2,
// "I:研究型活动" = 3,
// "E:事业型活动" = 4,
// "A:艺术型活动" = 5,
// "C:常规型(传统型)活动" = 6,
// "R:实际型活动" = 7,
// "S:社会型活动" = 8,
// "I:研究型活动" = 9,
// "E:事业型活动" = 10,
// "A:艺术型活动" = 11,
// "C:常规型(传统型)活动" = 12,
// "R:实际型活动" = 13,
// "S:社会型活动" = 14,
// "I:研究型活动" = 15,
// "E:事业型活动" = 16,
// "A:艺术型活动" = 17,
// "C:常规型(传统型)活动" = 18,
// "R型:机械操作能力" = 19,
// "I型:科学研究能力" = 20,
// "A型:艺术创作能力" = 21,
// "S型:解释表达能力" = 22,
// "E型:商业洽谈能力" = 23,
// "C型:事务执行能力" = 24,
// "R型:体育技能" = 25,
// "I型:数学技能" = 26,
// "A型:音乐技能" = 27,
// "S型:交际技能" = 28,
// "E型:领导技能" = 29,
// "C型:办公技能" = 30,
/**
* 题型简称
*/
export enum HLDTYPE {
"R" = 1,
"S" = 2,
"I" = 3,
"E" = 4,
"A" = 5,
"C" = 6
}
/**
* 返回给前端题型
*/
export enum QUESTION {
"R型实际型" = 1,
"S型社会型" = 2,
"I型研究型" = 3,
"E型事业型" = 4,
"A型艺术型" = 5,
"C型常规型" = 6,
}
export enum HUOLANDE {
R = "木匠、农民、操作X光的技师、工程师、飞机机械师、鱼类和野生动物专家、自动化技师、机械工(车工、钳工等)、电工、无线电报务员、火车司机、长途公共汽车司机、机械制图员、修理机器、电器师",
I = "气象学者、生物学者、天文学家、药剂师、动物学者、化学家、科学报刊编辑、地质学者、植物学者、物理学者、数学家、实验员、科研人员、科技作者",
A = "室内装饰专家、图书管理专家、摄影师、音乐教师、作家、演员、记者、诗人、作曲家、编剧、雕刻家、漫画家",
S = "社会学者、导游、福利机构工作者、咨询人员、社会工作者、社会科学教师、学校领导、精神病工作者、公共保健护士",
E = "推销员、进货员、商品批发员、旅馆经理、饭店经理、广告宣传员、调度员、律师、政治家、零售商",
C = "记账员、会计、银行出纳、法庭速记员、成本估算员、税务员、核算员、打字员、办公室职员、统计员、计算机操作员、秘书"
}
export enum ERRORENUM {
不存在表 = 1,
身份验证失败,
缺少必要参数_表名,
数据表不存在,
参数错误,
添加时数据对象为空,
修改时数据对象为空,
该方法仅可进行数据操作,
数据操作失败,
该方法仅可进行查询操作,
分页请设置当前页数,
数据查询失败,
该方法仅可进行联合查询操作,
数据联合查询失败,
INVALID_REQUEST,
INTERNAL_SERVER_ERROR,
文件不存在,
该身份证号码重复,
账号或密码错误,
接口数据获取失败
}
/**
* 只用做code码定义
*/
export enum ERRORCODEENUM {
身份验证失败 = 5001,
缺少必要参数_表名 = 5002,
数据表不存在,
}
let bizErrorMsgMap = {};
for (let key in ERRORENUM) {
bizErrorMsgMap[ERRORENUM[key]] = key;
}
export function getBizMsg(param) {
return bizErrorMsgMap[param];
}
\ No newline at end of file
/**
* 表统一管理
*/
export const TablesConfig = {}
export let EccTableConfig = {};
function initEccTableConfig() {
for(let tableChName in TablesConfig) {
let {tableName, schema} = TablesConfig[tableChName];
EccTableConfig[tableName] ={};
for (let filesName in schema) {
let valueType = typeof schema[filesName];
let value = schema[filesName];
EccTableConfig[tableName][filesName] = {type:'', notMustHave:false};
if (valueType == "function") {
EccTableConfig[tableName][filesName].type = value.name;
} else if (valueType == "object") {
if (!value.type) {
EccTableConfig[tableName][filesName].type = `[${value[0].name}]`;
} else {
if (typeof value.type == "function") {
EccTableConfig[tableName][filesName].type = value.type.name
} else EccTableConfig[tableName][filesName].type = `[${value.type[0].name}]`;
if (value.index) EccTableConfig[tableName][filesName].notMustHave = true;
}
}
}
}
console.log('table eccConfig init success');
}
initEccTableConfig();
\ No newline at end of file
import { table } from "console";
import { Association } from "sequelize";
const { Sequelize, DataTypes } = require('sequelize');
export const TablesConfig = [
{
tableNameCn:'题目选项表',
tableName:'option',
schema:{
oid: {
type:DataTypes.INTEGER(11), //表示属性的数据类型
allowNull:false, //表示当前列是否允许为空, false表示该列不能为空
primaryKey:true, //表示主键
unique:true, //表示该列的值必须唯一
autoIncrement:true //设置为主键并自增
},
qid: {type:DataTypes.INTEGER(11)}, //题目ID
option_name: {type:DataTypes.STRING(255)}, //选项名称
points: {type:DataTypes.INTEGER(11)}, //分值
sort: {type:DataTypes.INTEGER(11)}, //排序
last_update_time: {type:DataTypes.DATE(0)}, //最后修改时间
create_time: {type:DataTypes.DATE(0)}, //创建时间
is_del: {type:DataTypes.TINYINT(1)}, //是否删除 0.正常 1.已删除
},
association: [
// {type: "hasMany", check: "question", foreignKey: "qid"}
]
},
{
tableNameCn:'题目表',
tableName:'question',
schema:{
qid: {
type:DataTypes.INTEGER(11), //表示属性的数据类型
allowNull:false, //表示当前列是否允许为空, false表示该列不能为空
primaryKey:true, //表示主键
unique:true, //表示该列的值必须唯一
autoIncrement:true //设置为主键并自增
},
title: {type:DataTypes.STRING(255)}, //题目类型:1. 霍兰德
test_type: {type:DataTypes.TINYINT(1)}, //章节:1.霍兰德(一、我感兴趣的活动)2.霍兰德(二、我能完成的活动)3.霍兰德(三、我喜欢的职业)4.霍兰德(四、我的能力类型简评A)5.霍兰德(四、我的能力类型简评B)
chapter: {type:DataTypes.TINYINT(2)}, //章节
sort: {type:DataTypes.INTEGER(255)}, //排序
last_update_time: {type:DataTypes.DATE(0)}, //最后修改时间
create_time: {type:DataTypes.DATE(0)}, //创建时间
is_del: {type:DataTypes.TINYINT(1)}, //是否删除 0.正常 1.已删除
},
association: [
{type:"hasMany", check:"option", foreignKey:"qid"},
]
},
{
tableNameCn:'省市区表',
tableName:'area',
schema:{
id: {
type:DataTypes.INTEGER(11), //表示属性的数据类型
allowNull:false, //表示当前列是否允许为空, false表示该列不能为空
primaryKey:true, //表示主键
unique:true, //表示该列的值必须唯一
autoIncrement:true //设置为主键并自增
},
pid: {type:DataTypes.INTEGER(11),allowNull:false}, //父级ID 0表示最高节点
name: {type:DataTypes.STRING(500)}, //名字
visible: {type:DataTypes.TINYINT(4)}, //是否显示 1.不显示 2.显示
displayorder: {type:DataTypes.INTEGER(11)}, //显示顺序
level: {type:DataTypes.TINYINT(3)}, //层级别 1.省 2.市 3.区
},
association: [
// {type: "belongsTo", check: "area", foreignKey:"pid"}
]
},
{
tableNameCn:'测试信息表',
tableName:'testinfo',
schema:{
infoid: {
type:DataTypes.INTEGER(11), //表示属性的数据类型
allowNull:false, //表示当前列是否允许为空, false表示该列不能为空
primaryKey:true, //表示主键
unique:true, //表示该列的值必须唯一
autoIncrement:true //设置为主键并自增
},
test_type: {type:DataTypes.TINYINT(1)}, //题目类型:1. 霍兰德
name: {type:DataTypes.STRING(255)}, //姓名
card:{type:DataTypes.STRING(255)},//身份证号
phone: {type:DataTypes.STRING(255)}, //联系电话
email: {type:DataTypes.STRING(255)}, //电子邮箱
area:{type:DataTypes.STRING(255)}, //所在区域
final_score: {type:DataTypes.INTEGER}, //最终得分
test_date: {type:DataTypes.DATE}, //测试时间
last_update_time: {type:DataTypes.DATE,allowNull:false}, //最后修改时间
create_time: {type:DataTypes.DATE,allowNull:false}, //创建时间
is_del: {type:DataTypes.TINYINT,allowNull:false}, //是否删除 0.正常 1.已删除
// highest_letter: {type:DataTypes.TINYINT}, //最高分字母
// second_highest_letter: {type:DataTypes.TINYINT}, //第二高分字母
// third_highest_letter: {type:DataTypes.TINYINT}, //第三高分字母
},
association: [
// { type: "hasMany", check: "inforecord", foreignKey: "infoid" }
]
},
{
tableNameCn:'信息记录表',
tableName:'inforecord',
schema:{
irid: {
type:DataTypes.INTEGER(11), //表示属性的数据类型
allowNull:false, //表示当前列是否允许为空, false表示该列不能为空
primaryKey:true, //表示主键
unique:true, //表示该列的值必须唯一
autoIncrement:true //设置为主键并自增
},
infoid: {type:DataTypes.INTEGER(11),allowNull:false}, //测试信息ID
chapter: {type:DataTypes.TINYINT(2),allowNull:false}, //章节 1.霍兰德(一、我感兴趣的活动)2.霍兰德(二、我能完成的活动)3.霍兰德(三、我喜欢的职业)4.霍兰德(四、我的能力类型简评A)5.霍兰德(四、我的能力类型简评B)
test_type: {type:DataTypes.TINYINT(1)}, //题目类型:1. 霍兰德
title_str: {type:DataTypes.STRING(255),allowNull:false}, //记录标题用逗号隔开
option_str: {type:DataTypes.STRING(255),allowNull:false}, //记录结果用逗号隔开
last_update_time: {type:DataTypes.DATE(0),allowNull:false}, //最后修改时间
create_time: {type:DataTypes.DATE(0),allowNull:false}, //创建时间
is_del: {type:DataTypes.TINYINT(1),allowNull:false}, //是否删除 0.正常 1.已删除
},
association: [
//{ type: "belongsTo", check: "testinfo", foreignKey: "infoid" }
]
},
{
tableNameCn:'测试信息记录表',
tableName:'inforecord_test',
schema:{
irid: {
type:DataTypes.INTEGER(11), //表示属性的数据类型
allowNull:false, //表示当前列是否允许为空, false表示该列不能为空
primaryKey:true, //表示主键
unique:true, //表示该列的值必须唯一
autoIncrement:true //设置为主键并自增
},
infoid: {type:DataTypes.INTEGER(11),allowNull:false}, //测试信息ID
chapter: {type:DataTypes.TINYINT(2),allowNull:false}, //章节 1.霍兰德(一、我感兴趣的活动)2.霍兰德(二、我能完成的活动)3.霍兰德(三、我喜欢的职业)4.霍兰德(四、我的能力类型简评A)5.霍兰德(四、我的能力类型简评B)
test_type: {type:DataTypes.TINYINT(1)}, //题目类型:1. 霍兰德
title_str: {type:DataTypes.STRING(255),allowNull:false}, //记录标题用逗号隔开
option_str: {type:DataTypes.STRING(255),allowNull:false}, //记录结果用逗号隔开
last_update_time: {type:DataTypes.DATE(0),allowNull:false}, //最后修改时间
create_time: {type:DataTypes.DATE(0),allowNull:false}, //创建时间
is_del: {type:DataTypes.TINYINT(1),allowNull:false}, //是否删除 0.正常 1.已删除
},
association: [
//{ type: "belongsTo", check: "testinfo", foreignKey: "infoid" }
]
},
{
tableNameCn:'职业对照表',
tableName:'career_contrast',
schema:{
cid: {
type:DataTypes.INTEGER(11), //表示属性的数据类型
allowNull:false, //表示当前列是否允许为空, false表示该列不能为空
primaryKey:true, //表示主键
unique:true, //表示该列的值必须唯一
autoIncrement:true //设置为主键并自增
},
statistics: {type:DataTypes.STRING(255),allowNull:false}, //记录标题用逗号隔开
recommend: {type:DataTypes.STRING(255),allowNull:false}, //记录结果用逗号隔开
last_update_time: {type:DataTypes.DATE(0),allowNull:false}, //最后修改时间
create_time: {type:DataTypes.DATE(0),allowNull:false}, //创建时间
is_del: {type:DataTypes.TINYINT(1),allowNull:false}, //是否删除 0.正常 1.已删除
},
association: [
//{ type: "belongsTo", check: "testinfo", foreignKey: "infoid" }
]
},
{
tableNameCn:'管理员表',
tableName:'sys_user',
schema:{
id: {
type:DataTypes.INTEGER(11), //表示属性的数据类型
allowNull:false, //表示当前列是否允许为空, false表示该列不能为空
primaryKey:true, //表示主键
unique:true, //表示该列的值必须唯一
autoIncrement:true //设置为主键并自增
},
username: {type:DataTypes.STRING(255),allowNull:false}, //用户名
password: {type:DataTypes.STRING(255),allowNull:false}, //密码
real_name: {type:DataTypes.STRING(255),allowNull:false}, //真实姓名
phone: {type:DataTypes.STRING(255),allowNull:false}, //手机号码
sex: {type:DataTypes.STRING(255),allowNull:false}, //性别 1、男 2、女
mail: {type:DataTypes.STRING(255),allowNull:false}, //邮箱
remark: {type:DataTypes.STRING(255),allowNull:false}, //备注
create_time: {type:DataTypes.DATE(0),allowNull:false}, //创建时间
last_update_time: {type:DataTypes.DATE(0),allowNull:false}, //最后修改时间
},
association: [
]
}
];
\ No newline at end of file
const path = require('path');
import * as fs from "fs";
import { BizError } from "../util/bizError";
import { analysisXml } from "../util/myXML";
import { ServerConfig } from "../config/systemClass";
export let systemConfig = new ServerConfig;
const ConfigName = "serverConfig.xml";
export async function initConfig() {
try {
let buff = fs.readFileSync(path.join(__dirname.substring(0,__dirname.indexOf("out")), ConfigName));
let configStr = buff.toString();
let configInfo:any = await analysisXml(configStr);
if (!configInfo || !configInfo.config) throw new BizError('xml中无配置');
else {
let {port, sign, dbServer, mysqldb, qw } = configInfo.config;
systemConfig.port = parseInt(port[0]);
systemConfig.sign = sign[0]
systemConfig.dbPath = dbServer[0]
if (mysqldb) {
let dbConfigInfo = mysqldb[0];
systemConfig.mysqldb = {host:'', port:0, user:'', pwd:'', dataBase:''};
if (dbConfigInfo.mysqlHost && dbConfigInfo.mysqlPort && dbConfigInfo.mysqlUser && dbConfigInfo.dataBase) {
systemConfig.mysqldb.host=dbConfigInfo.mysqlHost[0];
systemConfig.mysqldb.port=parseInt(dbConfigInfo.mysqlPort[0]);
systemConfig.mysqldb.user=dbConfigInfo.mysqlUser[0];
systemConfig.mysqldb.pwd=dbConfigInfo.mysqlPwd[0] || "";
systemConfig.mysqldb.dataBase=dbConfigInfo.dataBase[0];
}
}
systemConfig.qwUrl = `${qw[0].url[0]}&page=${qw[0].page[0]}&size=${qw[0].size[0]}`;
}
console.log("config init success");
} catch(err) {
console.log('ERROR => 服务器配置解析错误 请检查根目录下 serverConfig.xml 文件是否正确');
console.log(err);
throw new BizError("服务器配置解析错误 请检查根目录下 serverConfig.xml 文件是否正确");
}
}
function analysisMongoConnectStr(path, port, dataBase, w, timeOutMs) {
return `mongodb://${path}:${port}/${dataBase}?w=${w}&wtimeoutMS=${timeOutMs}`
}
/**
* 系统配置类
*
*/
export class ServerConfig {
/**系统配置 */
port:number;
sign:string;
dbPath:string;
mysqldb:{
host:string,
port:number,
user:string,
pwd:string,
dataBase:string,
};
qwUrl:string;
}
\ No newline at end of file
import { mysqlModelMap } from "../model/sqlModelBind";
/**
* 添加数据
* @param tableModel
* @param data
* @returns
*/
export async function addData(tableName:string, data:any) {
let tableModel = mysqlModelMap[tableName];
let dataArray = [];
if (!Array.isArray(data)) {
dataArray.push(data);
} else dataArray = data;
await tableModel.bulkCreate(dataArray);
return { isSuccess:true };
}
\ No newline at end of file
export async function delData(tableModel, param) {
await tableModel.destroy({where:param});
return {isSuccess:true};
}
\ No newline at end of file
import { Op, Sequelize } from "sequelize";
import { ERRORENUM } from "../config/errorEnum";
import { mysqlModelMap } from "../model/sqlModelBind";
import { BizError } from "../util/bizError";
/**
* where条件查询参数
* @param param
* %like%:模糊查询 {列名: {"%like%": }}
* %gt%:大于 {列名: {"%gt%": }}
* %gte%:大于等于 {列名: {"%gte%": }}
* %lt%:小于 {列名: {"%lt%": }}
* %lte%:小于等于 {列名: {"%lte%": }}
* %between%:查询范围内数据 {列名: {"%between%": ["开始参数", "结束参数"]}} ---BETWEEN 开始参数 AND 结束参数 列>开始参数 and 列<结束参数
* %notBetween%:查询不在范围内数据 {列名: {"%notBetween%": ["开始参数", "结束参数"]}} ---NOT BETWEEN 开始参数 AND 结束参数
* %orderDesc%: order by DESC {"%orderDesc%": "列名"}
* %limit%: {"%limit%": 数量}
* @param column
* @returns
*/
function analysisParamToWhere(param, column) {
let where = {};
let order = [];
let group = "";
let literal = "";
let limit = 0;
for (let key in param) {
if (typeof param[key] == "object") {
where[key] = {};
for (let whereKey in param[key]) {
switch (whereKey) {
case "%like%":
where[key][Op.like] = `%${param[key]["%like%"]}%`;
break;
case "%gt%":
where[key][Op.gt] = param[key]["%gt%"];
break;
case "%gte%":
where[key][Op.gte] = param[key]["%gte%"];
break;
case "%lt%":
where[key][Op.lt] = param[key]["%lt%"];
break;
case "%lte%":
where[key][Op.lte] = param[key]["%lte%"];
break;
case "%between%":
where[key][Op.between] = param[key]["%between%"];
break;
case "%notBetween%":
where[key][Op.notBetween] = param[key]["%notBetween%"];
break;
case "%in%":
where[key][Op.in] = param[key]["%in%"];
break;
case "%notIn%":
where[key][Op.notIn] = param[key]["%notIn%"];
break;
case "%ne%":
where[key][Op.ne] = param[key]["%ne%"];
break;
case "%regexp%":
where[key][Op.regexp] = param[key]["%regexp%"];
break;
}
}
} else {
switch (key) {
case "%orderDesc%":
order = [[Sequelize.col(param[key]), "DESC"]];
break;
case "%orderAsc%":
order = [[Sequelize.col(param[key]), "ASC"]];
break;
case "%limit%":
limit = param[key];
break;
case "%group%":
group = param[key];
break;
case "%literal%":
literal = param["%literal%"];
break;
default: where[key] = param[key];
}
}
}
let selectParam: any = { where };
if (column && column.length) selectParam.attributes = column;
if (order && order.length) selectParam.order = order;
if (limit) selectParam.limit = limit;
if (group) selectParam.group = group;
if (literal) selectParam.where = Sequelize.literal(literal);
return selectParam;
}
/**
* 查询单个数据
* @param tableModel 表对象
* @param param
* @returns
*/
export async function selectOneDataByParam(tableName, param, column) {
let tableModel = mysqlModelMap[tableName];
let selectParam = analysisParamToWhere(param, column);
let data = await tableModel.findOne(selectParam);
data = data || {};
return { data };
}
/**
* 查询多个数据
* @param tableName 表对象
* @param param
* @returns
*/
export async function selectDataListByParam(tableName, param, column) {
let tableModel = mysqlModelMap[tableName];
let selectParam = analysisParamToWhere(param, column);
let data = await tableModel.findAll(selectParam);
return { data };
}
/**
* 分页查询
* @param tableModel
* @param param
* @param pageNumber
* @param pageSize
* @returns
*/
export async function selectDataListToPageByParam(tableName, param, column, pageNumber: number, pageSize: number) {
let tableModel = mysqlModelMap[tableName];
let selectParam: any = analysisParamToWhere(param, column);
selectParam.limit = pageSize || 10;
selectParam.offset = (pageNumber - 1) * 10;
let data = await tableModel.findAll(selectParam);
return { data };
}
export async function selectDataCountByParam(tableName, param) {
let tableModel = mysqlModelMap[tableName];
let selectParam: any = analysisParamToWhere(param, []);
let data = await tableModel.count(selectParam);
return { data };
}
export async function associationSelect(tableName: string, param) {
let model = mysqlModelMap[tableName];
if (!model) throw new BizError(ERRORENUM.不存在表);
let data = await model.aggragateData(param);
return {data};
// try {
// let data = await model.aggragateData(param);
// return { data };
// } catch (error) {
// throw new BizError(ERRORENUM.数据查询失败, error.message);
// }
}
/**
* 多表联查 列表
* @param tableModel
* @param includeConf {"表名":["",""] }
* @param param
* @param column
* @returns
*/
// question
export async function selectDataToTableAssociation(tableName, includeConf, param, column) {
let tableModel = mysqlModelMap[tableName];
let include = [];
for (let tableName in includeConf) {
if (!mysqlModelMap[tableName]) throw new BizError(ERRORENUM.不存在表, `尝试进行多表联查,但是不存在${tableName}`);
let {where, column} = includeConf[tableName];
let includeInfomation = analysisParamToWhere(where, column);
includeInfomation.model = mysqlModelMap[tableName];
include.push(includeInfomation);
}
let selectParam: any = analysisParamToWhere(param, column);
selectParam.include = include;
let data = await tableModel.findAll(selectParam);
return { data };
}
/**
* 多表联查 分页
* @param tableModel
* @param includeConf {"表名":["",""] }
* @param param
* @param column
* @returns
*/
export async function selectDataToTableAssociationToPage(tableName, includeConf, param, column, pageNumber: number, pageSize: number) {
let tableModel = mysqlModelMap[tableName];
let include = [];
for (let tableName in includeConf) {
if (!mysqlModelMap[tableName]) throw new BizError(ERRORENUM.不存在表, `尝试进行多表联查,但是不存在${tableName}`);
let { where, column } = includeConf[tableName];
let includeInfomation = analysisParamToWhere(where, column);
includeInfomation.model = mysqlModelMap[tableName];
include.push(includeInfomation);
}
let selectParam: any = analysisParamToWhere(param, column);
selectParam.include = include;
selectParam.limit = pageSize || 10;
selectParam.offset = (pageNumber - 1) * 10;
let data = await tableModel.findAll(selectParam);
return { data };
}
/**
* 多表查询单个
* @param tableModel
* @param includeConf
* @param param
* @param column
* @returns
*/
export async function selectOneDataToTableAssociation(tableName, includeConf, param, column) {
let tableModel = mysqlModelMap[tableName];
let include = [];
for (let tableName in includeConf) {
if (!mysqlModelMap[tableName]) throw new BizError(ERRORENUM.不存在表, `尝试进行多表联查,但是不存在${tableName}`);
let { where, column } = includeConf[tableName];
let includeInfomation = analysisParamToWhere(where, column);
includeInfomation.model = mysqlModelMap[tableName];
include.push(includeInfomation);
}
let selectParam: any = analysisParamToWhere(param, column);
selectParam.include = include;
let data = await tableModel.findOne(selectParam);
data = data || {};
return { data };
}
\ No newline at end of file
/**
* 岗位信息
*/
import { planarArrDecollateForIndex, planarArrDeconstruct, planarArrForObjectList } from "../../dataPackage/planaryArrayAnalysis";
import { onceSheetBecomeOfblockData, onceSheetBecomeOfblockDataToUrl } from "../../util/analysisExcel";
function packageDataProcess(blockDataList, titltListConfig, keyValueOrTitleList, barChartList, stringList, decollatePlanarList) {
let result = {};
for (let i = 0; i < blockDataList.length; i++) {
let {blockData, blockTitle} = blockDataList[i];
if (keyValueOrTitleList.indexOf(blockTitle) > -1) {
let titleList = titltListConfig[blockTitle] || [];
result[blockTitle] = planarArrForObjectList(blockData, 0, titleList);
}
else if (barChartList.indexOf(blockTitle) > -1) {
result[blockTitle] = planarArrDeconstruct(blockData);
}
else if (stringList.indexOf(blockTitle) > -1) result[blockTitle] = planarArrForObjectList(blockData);
else if (decollatePlanarList.indexOf(blockTitle) > -1) result[blockTitle] = planarArrDecollateForIndex(blockData);
}
return result;
}
export function employmentTableData() {
let blockDataList = onceSheetBecomeOfblockData('招聘岗位信息.xlsx', '岗位发布');
let keyValueOrTitleList = ['招聘岗位信息']; //适配 饼图 键值以及需要多个Key的
let barChartList = []; //适配 柱状图 折线图
let stringList = [];
let decollatePlanarList = []; //适配 表格
let titleListConfig = {};
let result = packageDataProcess(blockDataList, titleListConfig, keyValueOrTitleList, barChartList, stringList, decollatePlanarList);
return result;
}
export function titleTableData() {
let blockDataList = onceSheetBecomeOfblockData('标题信息.xlsx', '标题');
let keyValueOrTitleList = []; //适配 饼图 键值以及需要多个Key的
let barChartList = []; //适配 柱状图 折线图
let stringList = ['大屏标题信息', '竖屏标题信息'];
let decollatePlanarList = []; //适配 表格
let titleListConfig = {};
let result = packageDataProcess(blockDataList, titleListConfig, keyValueOrTitleList, barChartList, stringList, decollatePlanarList);
return result;
}
export function getPopup(type) {
let blockDataList = onceSheetBecomeOfblockDataToUrl(`${type}.xls`, 'Sheet1', '/弹窗');
let keyValueOrTitleList = [`${type}`]; //适配 饼图 键值以及需要多个Key的
let barChartList = []; //适配 柱状图 折线图
let stringList = [];
let decollatePlanarList = []; //适配 表格
let titleListConfig = {};
let result = packageDataProcess(blockDataList, titleListConfig, keyValueOrTitleList, barChartList, stringList, decollatePlanarList);
return result;
}
export function getTyjrxm() {
let blockDataList = onceSheetBecomeOfblockData(`大屏.xlsx`, '弹窗退役军人标识');
let keyValueOrTitleList = ['退役军人']; //适配 饼图 键值以及需要多个Key的
let barChartList = []; //适配 柱状图 折线图
let stringList = [];
let decollatePlanarList = []; //适配 表格
let titleListConfig = {};
let result = packageDataProcess(blockDataList, titleListConfig, keyValueOrTitleList, barChartList, stringList, decollatePlanarList);
return result;
}
export function getHzdw() {
let blockDataList = onceSheetBecomeOfblockData(`大屏.xlsx`, '合作单位');
let keyValueOrTitleList = ['合作单位数据']; //适配 饼图 键值以及需要多个Key的
let barChartList = []; //适配 柱状图 折线图
let stringList = [];
let decollatePlanarList = []; //适配 表格
let titleListConfig = {};
let result = packageDataProcess(blockDataList, titleListConfig, keyValueOrTitleList, barChartList, stringList, decollatePlanarList);
return result;
}
export function getJyfwjl(xlsName) {
let blockDataList = onceSheetBecomeOfblockDataToUrl(`${xlsName}.xlsx`, 'Sheet1', '/就业服务记录');
let keyValueOrTitleList = ['服务记录']; //适配 饼图 键值以及需要多个Key的
let barChartList = []; //适配 柱状图 折线图
let stringList = [];
let decollatePlanarList = []; //适配 表格
let titleListConfig = {};
let result = packageDataProcess(blockDataList, titleListConfig, keyValueOrTitleList, barChartList, stringList, decollatePlanarList);
return result;
}
import { Op, Sequelize } from "sequelize";
import { mysqlModelMap } from "../model/sqlModelBind";
/**
* where条件查询参数
* @param param
* %like%:模糊查询 {列名: {"%like%": }}
* %gt%:大于 {列名: {"%gt%": }}
* %gte%:大于等于 {列名: {"%gte%": }}
* %lt%:小于 {列名: {"%lt%": }}
* %lte%:小于等于 {列名: {"%lte%": }}
* %between%:查询范围内数据 {列名: {"%between%": ["开始参数", "结束参数"]}} ---BETWEEN 开始参数 AND 结束参数
* %notBetween%:查询不在范围内数据 {列名: {"%notBetween%": ["开始参数", "结束参数"]}} ---NOT BETWEEN 开始参数 AND 结束参数
* %orderDesc%: order by DESC {"%orderDesc%": "列名"}
* %limit%: {"%limit%": 数量}
* @returns
*/
function analysisParamToWhere(param) {
let where = {};
let order = [];
let limit = 0;
for (let key in param) {
if (typeof param[key] == "object") {
where[key] = {};
for (let whereKey in param[key]){
switch(whereKey) {
case "%like%":
where[key][Op.like] = `%${param[key]["%like%"]}%`;
break;
case "%gt%":
where[key][Op.gt] = param[key]["%gt%"];
break;
case "%gte%":
where[key][Op.gte] = param[key]["%gte%"];
break;
case "%lt%":
where[key][Op.lt] = param[key]["%lt%"];
break;
case "%lte%":
where[key][Op.lte] = param[key]["%lte%"];
break;
case "%between%":
where[key][Op.between] = param[key]["%between%"];
break;
case "%notBetween%":
where[key][Op.notBetween] = param[key]["%notBetween%"];
break;
case "%in%":
where[key][Op.in] = param[key]["%in%"];
break;
case "%notIn%":
where[key][Op.notIn] = param[key]["%notIn%"];
break;
}
}
}else {
switch (key) {
case "%orderDesc%":
order = [[Sequelize.col(param[key]), "DESC"]];
break;
case "%orderAsc%":
order = [[Sequelize.col(param[key]), "ASC"]];
break;
case "%limit%":
limit = param[key];
break;
default: where[key] = param[key];
}
}
}
let selectParam:any = {where};
if (order && order.length) selectParam.order = order;
if (limit) selectParam.limit = limit;
return selectParam;
}
export async function updateManyData(tableName, param:object, data:object) {
let tableModel = mysqlModelMap[tableName];
let where = analysisParamToWhere(param);
await tableModel.update(data, where);
return {isSuccess:true};
}
\ No newline at end of file
//打包完数据之后的处理
/**
* recombinationObject 重组对象 在打包完数据后使用 必须是keyvalue之后
* @param data [{key:key1, value:value1, unit:unit1 }, {key:key2, value:value2, unit:unit2}]
* @param check {"key2":[{key:"key1", name:""}] }
* @returns [{key:key1, value:value1, key2:key2, value2:value2}]
*/
export function recombinationObject(data, checkInfo) {
let dataMap = {};
data.forEach(info => {
let { key } = info;
dataMap[key] = info;
});
let removeKeyMap = {};
for (let checkKey in checkInfo) {
let checkList = checkInfo[checkKey];
checkList.forEach(item => {
let {key, name} = item;
removeKeyMap[key] = 1;
let onceCheck = dataMap[key];
dataMap[checkKey][name] = onceCheck.value;
dataMap[checkKey][`${name}Unit`] = onceCheck.unit;
});
}
let dataList = [];
data.forEach(info => {
let { key } = info;
if (removeKeyMap[key]) return;
dataList.push(dataMap[key]);
});
return dataList;
}
/**
* 修改表格数据结构
* @param titleList
* @param dataList
* @returns
*/
export function change(titleList, dataList) {
let data = [];
dataList.forEach(subList => {
let onceData:any = {};
subList.forEach( (item, index)=> {
let key = titleList[index];
onceData[key] = item;
} );
data.push(onceData);
});
return data;
}
/**
* 获取单条线路数据
* @param line 线路
* @param data 数据
* @param conf 配置
* @returns
*/
export function getLineOneData(line, data, conf) {
let result:any = {};
data.forEach(item => {
let dataLine = item.line;
if (line == dataLine) {
for (let name = 0; name < conf.length; name++) {
result[conf[name]] = item[conf[name]];
}
}
});
return result;
}
/**
* 单条弹窗数据
* @param line 线路
* @param data 数据
* @param conf 配置
* @returns
*/
export function getPopupOneData(line, data, conf) {
let result:any = {};
data.forEach(item => {
let dataLine = item.line;
let dataSite = item.site;
if (line == dataLine) {
if (!result[dataSite]) result[dataSite] = {};
for (let name = 0; name < conf.length; name++) {
result[dataSite][conf[name]] = item[conf[name]];
}
}
});
return result;
}
/**
* 多条弹窗数据
* @param line
* @param data
* @param conf
* @returns
*/
export function getPopupMoreData(line, data, conf) {
let result:any = {};
data.forEach(item => {
let dataLine = item.line;
let dataSite = item.site;
let pipelineRelocationData = {};
if (line == dataLine) {
if (!result[dataSite]) result[dataSite] = {site:item.site, state:item.state, data:[]};
for (let name = 0; name < conf.length; name++) {
pipelineRelocationData[conf[name]] = item[conf[name]];
}
result[dataSite]["data"].push(pipelineRelocationData);
}
});
return result;
}
/**
* 弹窗详细数据
* @param id
* @param tableData
* @param changeConf
* @param conf
* @returns
*/
export function getPopupDetailsData(id, tableData, changeConf, conf, name) {
let details:any = {};
for (let key in tableData) {
if (id == key) {
let data = change(changeConf, tableData[key].bodyList );
data.forEach(item => {
let itemName = item[name];
let detailsData = {};
if (!details[itemName]) details[itemName] = [];
for (let name = 0; name < conf.length; name++) {
detailsData[conf[name]] = item[conf[name]];
}
details[itemName].push(detailsData);
});
}
}
let detailsList = [];
for (let key in details) {
detailsList.push({name: key, dataList: details[key]})
}
return detailsList;
}
\ No newline at end of file
//out 前置逻辑
import { BizError } from "../util/bizError";
import { separateDataAndUint } from "./tool";
/**
* stringListPackage 打包验证并返回 getStringOut 需要的格式
* @param dataList [{key, value},{}]
* @param keyName
* @returns ["","",""]
*/
export function stringListPackage(dataList, keyName = "value") {
let result = [];
dataList.forEach(info => {
result.push(info[keyName]);
});
return result;
}
/**
* onceYBarChartPackage 打包验证并返回 getOnceYBarChartOut 需要的格式
* @param dataList [{name:"", data:[{key, value}...] }]
* @param inYUnit y轴单位
* @param inXUnit x轴单位
* @returns {xUnit:x轴单位, yUnit:y单位, dataInfo:{"图表名称":[{key:"数据key", value:"数据值", unit:"单位" }, {key:"数据key", value:"数据值", unit:"单位" } ] } }
*/
export function onceYBarChartPackage(inDataList, inYUnit, inXUnit="") {
let dataInfo = {};
const InYUnitIsNull = !inYUnit;
let checkingDataHaveUnitMap = {};
let yUnit = "";
inDataList.forEach(info => {
let name = info.name;
let data = info.data;
checkingError({name, data}, errorEnum.必要参数);
let onceDataList = [];
//判空 去重
let distinctMap = {};
//验证工作
data.forEach(subInfo => {
let key = subInfo.key;
let value = subInfo.value;
checkingError({name, key}, errorEnum.数据key是否为空);
checkingError({name, value}, errorEnum.数据value是否为数值);
checkingError({name, distinctMap, key}, errorEnum.barChartx轴的key重复出现);
distinctMap[key] = 1;
let {dataNum, dataUnit} = separateDataAndUint(value);
checkingDataHaveUnitMap[dataUnit] = 1;
onceDataList.push({key, value:dataNum, unit:dataUnit|| "" });
});
dataInfo[name] = onceDataList;
});
let dataUnitList = Object.keys(checkingDataHaveUnitMap);
let dataHaveUnitCount = dataUnitList.length;
if (!dataHaveUnitCount && InYUnitIsNull ) {
//todo 这里可以加逻辑 挖个坑 可以读取表格里面的所有单位取出现最多的
} else if(dataHaveUnitCount> 1) throw new BizError(`在 onceYBarChartPackage 中 单个y轴的柱状图中出现多个单位:${JSON.stringify(dataUnitList)}`);
else {
yUnit = dataUnitList[0] || inYUnit;
for (let key in dataInfo) {
dataInfo[key].forEach(info => {
info.unit = yUnit;
});
}
}
return {xUnit:inXUnit, yUnit, dataInfo };
}
/**
* doubleYBarCharPackage 打包验证并返回 getDoubleYBarChartOut 需要的格式
* @param inLeftYUnit
* @param inRightYUnit
* @param data [{name:"", data:[{key, value}...] }]
* @param rightNameList ["name", name] 右边y轴的名称
* @returns {xUnit:x轴单位, leftYUnit:左边y单位, rightYUnit:右边y单位 dataInfo:{"图表名称":{from:"left", subList:[{key:"数据key", value:"数据值", unit:"单位" }, {key:"数据key", value:"数据值", unit:"单位" } ]} } }
*/
export function doubleYBarCharPackage(data, rightNameList, inLeftYUnit, inRightYUnit, xUnit = "") {
let leftAndRightDistinctMap = {};//比对两种图表名称有没有冲突
let dataInfo = {};
let leftUnitDistinctMap = {};
let rightUnitDistinctMap = {};
function checkOnceData(subFunCheckingList, dataType) {
subFunCheckingList.forEach(info => {
let name = info.name;
let data = info.data;
checkingError({name, data}, errorEnum.必要参数);
if (leftAndRightDistinctMap[name]) throw new BizError(`在 doubleYBarCharPackage 中leftYData 和 rightYData 重复出现了 ${name}`);
leftAndRightDistinctMap[name] = 1;
let subList = [];
let distinctMap = {};
data.forEach(subInfo => {
let key = subInfo.key;
let value = subInfo.value;
checkingError({name, key}, errorEnum.数据key是否为空);
checkingError({name, value}, errorEnum.数据value是否为数值);
checkingError({name, distinctMap, key}, errorEnum.barChartx轴的key重复出现);
distinctMap[key] = 1;
let {dataNum, dataUnit} = separateDataAndUint(value);
if (dataUnit) dataType == "left" ? leftUnitDistinctMap[dataUnit] = 1 : rightUnitDistinctMap[dataUnit] = 1;
subList.push({key, value:dataNum, unit:dataUnit || ""});
});
dataInfo[name] = {from:dataType, subList};
});
}
let leftYData = [];
let rightYData = [];
data.forEach(info => {
let {name} = info;
if (rightNameList.indexOf(name) > -1 ) rightYData.push(info);
else leftYData.push(info);
});
checkOnceData(leftYData, "left");
checkOnceData(rightYData, "right");
let leftUnitList = Object.keys(leftUnitDistinctMap);
let leftUnitCount = leftUnitList.length;
let rightUnitList = Object.keys(rightUnitDistinctMap);
let rightUnitCount = rightUnitList.length;
if (leftUnitCount > 1) throw new BizError(`在 onceYBarChartPackage 中 双y轴的柱状图中 leftData数据中出现了多个单位:${JSON.stringify(leftUnitList)}`);
if (rightUnitCount > 1) throw new BizError(`在 onceYBarChartPackage 中 双y轴的柱状图中 rightData数据中出现多个单位:${JSON.stringify(rightUnitList)}`);
let leftYUnit = leftUnitList[0] || inLeftYUnit;
let rightYUnit = rightUnitList[0] || inRightYUnit;
for (let key in dataInfo) {
let {from } = dataInfo[key];
dataInfo[key].subList.forEach(info => {
if (from == "left") info.unit = leftYUnit;
else info.unit = rightYUnit;
});
}
return {xUnit, leftYUnit, rightYUnit, dataInfo };
}
/**
* tablePackage 获得 getTableOut 需要的数据
* @param titleList ["","","",""]
* @param data [[a,b,c],[a,b,c],[a,b,c],[a,b,c]]
* @returns {titleList:[], dataList:[{a,b,c},{a,b,c},{a,b,c}] }
*/
export function tablePackage(titleList, data) {
var aForZkeyList = [];
for(var i = 65; i < 91; i++){
aForZkeyList.push(String.fromCharCode(i));
}
//验证长度
let dataMaxLenght = 0;
let dataList = [];
data.forEach(subDataList => {
let onceData = {};
subDataList.forEach((info, index) => {
let key = aForZkeyList[index];
onceData[key] = info || "";
});
dataMaxLenght = Math.max(dataMaxLenght, subDataList.length);
dataList.push(onceData);
});
if (titleList.length < dataMaxLenght) throw new BizError( `在 tablePackage 中 titleList长度比单个data最大长度小 titleList长度 ${titleList.length} 单个数据个数 ${dataMaxLenght}"`);
return {titleList, dataList};
}
/**
* keyValuePackage 将返回 getKeyValueOut 所需要的数据格式
* @param dataList [{key, value}]
* @returns [{key:"", value:"", unit:""}]
*/
export function keyValuePackage(dataList) {
let data = [];
dataList.forEach(info => {
let key = info.key;
let value = info.value;
checkingError({value, key}, errorEnum.数据key是否为空);
let {dataNum, dataUnit} = separateDataAndUint(value);
let analysisValue;
let analysisUnit;
if (isNaN(dataNum) || dataUnit == value){
analysisValue = value;
analysisUnit = "";
} else {
analysisValue = dataNum;
analysisUnit = dataUnit;
}
data.push({key, value:analysisValue, unit:analysisUnit });
});
return data;
}
/**
* objectListPackage 将返回 getObjectListOut 所需要的数据格式
* @param dataList [{key...}]
* @returns [{key...}]
*/
export function objectListPackage(dataList) {
let data = [];
dataList.forEach(info => {
let addInfo = {};
for (let key in info) {
checkingError({key, value:info[key]}, errorEnum.值为undefinednull);
addInfo[key] == info;
}
data.push(addInfo);
});
return data;
}
/**
* rankPackage 将返回 getRankOut 需要的数据
* @param orderIsDesc 默认 true desc(降序,从大到小)
* @param data [{key, value, details}]
* @param max 最大值
* @param unit 单位
* @returns {unit, max, dataInfo:[{key, value, details, unit}, {}, {}, {}] }
*/
export function rankPackage(data, orderIsDesc = true, unit?, max?) {
let dataInfo = [];
let valueIsString = false;
let dataUnitDistinctMap = {};
data.forEach( info => {
let key = info.key;
let value = info.value;
let details = info.details || "";
let onceUnit = "";
checkingError({key}, errorEnum.数据key是否为空);
if ((value == undefined || value == null) || `${value}`.search(/^(-)?\d+(\.\d+)?/) == -1 ) {
valueIsString = true;
} else {
let {dataNum, dataUnit} = separateDataAndUint(value);
if (dataUnit) {
dataUnitDistinctMap[dataUnit] = 1;
onceUnit = dataUnit;
}
value = dataNum;
}
dataInfo.push({key, value, details, unit:onceUnit});
});
let dataUnitList = Object.keys(dataUnitDistinctMap);
if (dataUnitList.length > 1) throw new BizError(`在 rankPackage 中 数据中的value解析出来不统一的单位:${JSON.stringify(dataUnitList)}`);
if (dataUnitList.length && unit && unit != dataUnitList.length) throw new BizError(`在 rankPackage 中 入参单位${unit} 与 数据中解析出来的单位 ${dataUnitList[0]} 不一致`);
let dataUnit = dataUnitList[0] || unit;
//统一单位
dataInfo.forEach(info => {info.unit = dataUnit});
if (!valueIsString) {
dataInfo.sort( (a, b) => {
return orderIsDesc ? b.value - a.value : a.value - b.value;
});
}
return {unit:dataUnit, max:max || 0, dataInfo};
}
/**
* radarChartPackage 将会返回 getRadarChartOut 需要的数据
* @param data [{key, value, max}]
* @returns [{key, value, max, unit}]
*/
export function radarChartPackage(data) {
let dataList = [];
data.forEach(info => {
let key = info.key;
let value = info.value;
let max = info.max;
checkingError({key}, errorEnum.数据key是否为空);
checkingError({name:key, value}, errorEnum.数据value是否为数值);
let {dataNum, dataUnit} = separateDataAndUint(value);
dataList.push({key, value:dataNum, unit:dataUnit, max});
});
return data;
}
/**
* mapPackage 返回 getMapOut 所需要的数据
* @param data [{key:数据名称, x:x坐标, y:坐标, longitude:经度, latitude:纬度, value:值, details:补充}]
* @returns [{name:数据名称, x:x坐标, y:坐标, coordinate:[经度, 纬度], unit:单位, value:值, details:"补充"}]
*/
export function mapPackage(data, isCoordinate=true, isXY=false) {
let dataList = [];
data.forEach((info, index) => {
checkingError({key:info.key}, errorEnum.数据key是否为空);
let longitude = info.longitude;
let latitude = info.latitude;
let x = info.x;
let y = info.y;
let addInfo:any = {key:info.key, details:info.details || ""};
checkingError({x, y, longitude, latitude, index}, errorEnum.地图坐标判空);
if (isCoordinate) {
longitude = isUndefinedOrNull(longitude) ? 0 : longitude;
latitude = isUndefinedOrNull(latitude) ? 0 : latitude;
let coordinate = [longitude, latitude];
addInfo.coordinate = coordinate;
}
if (isXY) {
x = isUndefinedOrNull(x) ? 0 : x;
y = isUndefinedOrNull(y) ? 0 : y;
addInfo.x = x;
addInfo.y = y;
}
let value;
let unit = "";
if (info.value && `${info.value}`.search(/^(-)?\d+(\.\d+)?/) > -1) {
let {dataNum, dataUnit} = separateDataAndUint(info.value);
value = dataNum;
unit = dataUnit;
} else if (info.value && `${info.value}`.search(/^(-)?\d+(\.\d+)?/) == -1) {
value = info.value;
} else value = "";
addInfo.value = value;
addInfo.unit = unit;
dataList.push(addInfo);
});
return dataList;
}
/**
* scatterFigurePackage 返回 getScatterFigureOutData 需要的格式
* @param data [{x, y, name}, {x, y, name}, {x, y, name}, {x, y, name}]
* @returns [{x, y, name}, {x, y, name}, {x, y, name}, {x, y, name}]
*/
export function scatterFigurePackage(data) {
let dataList = [];
data.forEach((info, index) => {
let x = info.x;
let y = info.y;
checkingError({x, y, index}, errorEnum.散点图判空);
dataList.push({x, y, name:info.name || ""});
});
return dataList;
}
enum errorEnum {
必要参数 = 1,
数据key是否为空,
数据value是否为数值,
类型为string,
barChartx轴的key重复出现,
值为undefinednull,
地图坐标判空,
散点图判空
};
function checkingError(param, errorEnumType) {
let str = ``;
let isError = false;
switch(errorEnumType) {
case errorEnum.类型为string:
if ( typeof param.str != "string") {
isError = true;
str += `下标为${param.index}的数据 不为string,当前为${param.str}`;
}
break;
case errorEnum.必要参数:
let paramNullErrorStr = '必要参数: ';
for (let key in param) {
if (!param[key]) {
isError = true;
paramNullErrorStr += `${key}为空 `;
}
}
str += paramNullErrorStr;
break;
case errorEnum.数据key是否为空 :
if (!param.key) {
isError = true;
str += `${param.name}中有key缺失数据`;
}
break;
case errorEnum.数据value是否为数值:
if (`${param.value}`.search(/^(-)?\d+(\.\d+)?/) == -1) {
isError = true;
str += `${param.name}中 key为${param.key} 的数据为字符串`;
}
break;
case errorEnum.barChartx轴的key重复出现:
if (param.distinctMap[param.key]) {
isError = true;
str += `${param.name}中 key为${param.key} 在数据中重复出现`;
}
break;
case errorEnum.值为undefinednull:
if ( isUndefinedOrNull(param.value) ) {
isError = true;
str += `${param.key}的值 为 undefined 或 null`;
}
break;
case errorEnum.地图坐标判空:
if (isUndefinedOrNull(param.x) && isUndefinedOrNull(param.y) && isUndefinedOrNull(param.longitude) && isUndefinedOrNull(param.latitude)) {
isError = true;
str += `第${param.index+1}个数据中坐标异常 所有表示坐标的属性都为空`;
}
if ( (isUndefinedOrNull(param.x) || isUndefinedOrNull(param.y)) && isUndefinedOrNull(param.longitude) || isUndefinedOrNull(param.latitude) ) {
isError = true;
str += `第${param.index+1}个数据中坐标异常 xy坐标缺失的同时经纬度也缺失`;
}
break;
case errorEnum.散点图判空:
if (isUndefinedOrNull(param.x) || isUndefinedOrNull(param.y)) {
isError = true;
str += `第${param.index+1}个数据中坐标异常 x为${param.x} y为${param.y}`;
}
break;
}
if (isError) {
throw new BizError(str);
}
}
function isUndefinedOrNull(paramater) {
return paramater == undefined || paramater == null;
}
\ No newline at end of file
/**
* changeObjectToList 将对象形式的数据转换为keyvalue的数组 对象中的键名称将作为key 传入mapping时 使用对应的change作为key的值
* @param data 数据{key1:value1, key2:value2, key3:value3...}
* @param reflect 对应关系 [{key:"key1",change:"名称1"},{key:"key2", change:"名称2"},{key:"key3", change:"名称3"}]
* @returns [{key:"名称1", value:value1}, {key:"名称2", value:value2}, {key:key3, value:value3}]
*/
export function changeObjectToList(data, reflect?) {
let keyList = [];
if (!reflect || !reflect.length) {
for (let key in data) {
keyList.push({key, change:key});
}
}
let dataList = [];
keyList.forEach(info => {
let {key, change} = info;
let value = data[key];
if (value) dataList.push({ key:change, value:`${value}`});
});
return dataList;
}
/**
* changeObjectKey 按mapping的对应关系修改 data中的key 如果对应关系中找不到,则会使用原来的key
* @param data {key1:value1, key2:value2, key3:value3...}
* @param reflect {"key1":"名称1", "key2":"名称2", "key3":"名称3"}
* @returns {"名称1":value1, "名称2":value2, "名称3":value3}
*/
export function changeObjectKey(data, reflect) {
let result = {};
for (let key in data) {
let changeKey = reflect[key] || key;
result[changeKey] = `${data[key]}`;
}
return result;
}
/**
* changeListObjectToListByReflect 将data中的object的key替换成 reflect对应的值
* @param data [{key1:value1, key2:value2...}, {key1:value1, key2:value2...}, {key1:value1, key2:value2...}]
* @param reflect 映射 不传就不会替换 {"key1":"名称1", "key2":"名称2", "key3":"名称3"}
* @returns [{"名称1":value1, "名称2":value2...}, {"名称1":value1, "名称2":value2...}, {"名称1":value1, "名称2":value2...}]
*/
export function changeListObjectToListByReflect(data, reflect?) {
let dataList = [];
if (!reflect) return dataList;
data.forEach(item => {
let changeInfo = {};
for (let key in item) {
let newKey = reflect[key] || key;
changeInfo[newKey] = `${item[key]}`;
}
dataList.push(changeInfo);
});
return dataList;
}
/**
* getDesignativByReflect 获取data中指定的的key
* @param data [{key1:value1, key2:value2, key3:value3...}, {key1:value1, key2:value2, key3:value3...}, {key1:value1, key2:value2, key3:value3...}] 或者 {key1:value1, key2:value2, key3:value3...}
* @param reflect List 映射 必须参数 ["key1", "key2"] 为key的名称
* @returns [{key1:value1, key2:value2, ...}, {key1:value1, key2:value2, ...}, {key1:value1, key2:value2, ...}]
*/
export function getDesignativByReflect(data, reflect) {
if (typeof data != "object") return data;
let type = Array.isArray(data) ? "array" : "object";
if ((type == "array" && !reflect.length) || (type == "object" && !Object.keys(reflect) ) ) return data;
let reflectMap = {};
reflect.forEach(keyName => {reflectMap[keyName] = 1});
if (type=="array") {
let dataList = [];
data.forEach(item => {
let once = {};
for (let key in item) {
if (!reflectMap[key]) continue;
once[key] = item[key];
}
dataList.push(once);
});
return dataList;
} else {
let dataInfo = {};
for(let key in reflectMap) {
if (data[key]) dataInfo[key] = data[key];
}
return dataInfo;
}
}
/**
* designativListKeyAddUnit为集合中指定的key添加单位
* @param data [{key1:value1, key2:value2, key3:value3...}, {key1:value1, key2:value2, key3:value3...}, {key1:value1, key2:value2, key3:value3...}]
* @param reflect {key1:"%", key2:"个"}
* @returns [{key1:"value1%", ke2:"value2个", keys:"value3"}]
*/
export function designativListKeyAddUnit(data, reflect) {
let dataList = [];
data.forEach(item => {
let onceData = {};
for (let key in item) {
let unit = reflect[key] || '';
onceData[key] = `${item[key]}${unit}`
}
dataList.push(onceData);
});
return dataList;
}
\ No newline at end of file
import { separateDataAndUint, unifiedMaxAndMinValueAndStep } from "./tool";
//数据出口封装 只做封装 少量的数据校验
/**
* getStringOut 获取文字列表返回结果
* @param title 数据标题
* @param data 数据体 格式:["txt...", "str..."]
* @returns {title, dataList:[string...]}
*/
export function getStringOut(title, data) {
let dataList = [];
data.forEach( (str) => {
dataList.push(str);
});
return { title, dataList};
}
/**
* getOnceYBarChartOut 获取单y轴柱状图
* @param title 数据标题
* @param data 数据体 格式: {xUnit:x轴单位, yUnit:y单位, dataInfo:{"图表名称":[{key:"数据key", value:"数据值", unit:"单位" }, {key:"数据key", value:"数据值", unit:"单位" } ] } }
* @returns {title:标题, xUnit:x轴单位, yUnit:y轴单位, yMinValue:最小值, yMaxValue:最大值, yStepValue:间隔,
* chartList:[{thisChartTitle:数据名称, total:总数, unit:单位, dataList:[{name:y轴名称, value:值, unit:单位}] } ]}
* 入参data里面的dataInfo中的unit可以为空 会读取yUnit 所以入参优先度 yUnit > unit 默认值都是空字符串
*/
export function getOnceYBarChartOut(title, data, stepCount?) {
let chartList = [];
let {xUnit, yUnit, dataInfo} = data;
let thisYUnit = yUnit ||"";
let min = new Date().valueOf();
let max = 0;
for (let dataName in dataInfo) {
let onceChartList = dataInfo[dataName];
let dataList = [];
let total = 0;
onceChartList.forEach(item => {
let {key, value, unit} = item;
min = Math.min(value, min);
max = Math.max(value, max);
total += parseInt(value);
dataList.push({name:key, value, unit: unit || thisYUnit});
});
chartList.push({thisChartTitle:dataName, total, unit:thisYUnit, dataList});
}
let {maxNumber, minNumber, stepNumber} = unifiedMaxAndMinValueAndStep(max, min, stepCount);
return {title, xUnit, yUnit:thisYUnit, yMinValue:minNumber, yMaxValue:maxNumber, yStepValue:stepNumber, chartList};
}
/**
* getDoubleYBarChartOut 获取双y轴柱状图
* @param title 数据标题
* @param data 数据体 格式:{xUnit:x轴单位, leftYUnit:左边y单位, rightYUnit:右边y单位 dataInfo:{"图表名称":{from:"left", subList:[{key:"数据key", value:"数据值", unit:"单位" }, {key:"数据key", value:"数据值", unit:"单位" } ]} } }
* @returns {title:标题, xUnit:x轴单位, leftYUnit:左边单位, rightYUnit:右边单位, leftYMinValue:左边最小值, leftYMaxValue:左边最大值, leftYStepValue:左边间隔,
* rightYMinValue:右边最小值, rightYMaxValue:右边最大值, rightYStepValue:右边间隔,
* dataList:[{subTitle:数据名称, total:总数, unit:单位, subDataList:[{name:y轴名称, value:值, unit:单位}] }] }
* 入参data里面的dataInfo中的unit可以为空 会读取yUnit 所以入参优先度 yUnit > unit 默认值都是空字符串
*/
export function getDoubleYBarChartOut(title, data, stepCountInfo?) {
stepCountInfo = stepCountInfo || {left:5, right:5};
let dataList = [];
let {xUnit, leftYUnit, rightYUnit, dataInfo} = data;
let thisLeftYUnit = leftYUnit || "";
let thisRightYUnit = rightYUnit || "";
let leftMin = new Date().valueOf();
let leftMax = 0;
let rightMin = new Date().valueOf();
let rightMax = 0;
for (let dataName in dataInfo) {
let {subList, from} = dataInfo[dataName];
let subDataList = [];
let total = 0;
let thisDataUnit = from == "left" ? thisLeftYUnit : thisRightYUnit;
subList.forEach(item => {
let {key, value, unit} = item;
if (from == "left") {
leftMin = Math.min(value, leftMin);
leftMax = Math.max(value, leftMax);
} else {
rightMin = Math.min(value, rightMin);
rightMax = Math.max(value, rightMax);
}
total += value;
subDataList.push({name:key, value, unit:unit || thisDataUnit});
});
dataList.push({subTitle:dataName, total, unit:thisDataUnit, subDataList});
}
let leftInfo = unifiedMaxAndMinValueAndStep(leftMax, leftMin,stepCountInfo.left);
let rightInfo = unifiedMaxAndMinValueAndStep(rightMax, rightMin,stepCountInfo.right);
return {title, xUnit, leftYUnit:thisLeftYUnit, rightYUnit:thisRightYUnit, leftYMinValue:leftInfo.minNumber, leftYMaxValue:leftInfo.maxNumber, leftYStepValue:leftInfo.stepNumber,
rightYMinValue:rightInfo.minNumber, rightYMaxValue:rightInfo.maxNumber, rightYStepValue:rightInfo.stepNumber, dataList}
}
/**
* getTableOut 获取列表返回
* @param title 数据标题
* @param data 数据体 格式:{titleList:[], dataList:[{a,b,c},{a,b,c},{a,b,c}] }
* @returns {title:数据标题, total:数据总条数, titleList:[表头...], valueList:[[a,b,c,d...],[a,b,c,d...]] }
* 解出来的对象的key是需要有顺序的,所以进这里之前要把值a-z排好序,按显示要求排序,
*/
export function getTableOut(title, data) {
let {titleList, dataList} = data;
let valueList = [];
dataList.forEach(info => {
let subList = [];
for (let key in info) {
subList.push(info[key]);
}
valueList.push(subList);
});
return { title, total:dataList.length, titleList, valueList };
}
/**
* getKeyValueOut 获取键值的返回结果
* @param title 数据标题
* @param data 数据体 [{key:"", value:"", unit:""}]
* @returns {title:数据标题, dataList:[], total:数据值总数, count:数据总条数 }
*/
export function getKeyValueOut(title, data) {
let dataList = [];
let total = 0;
data.forEach(info => {
let {key, value, unit} = info;
let typeChangeValue;
if (!isNaN(value)) {
typeChangeValue = parseFloat(value);
total+= typeChangeValue;
} else typeChangeValue = value;
dataList.push({name:key, value: Math.round(typeChangeValue * 100) /100, unit});
});
return {title, total: Math.round(total * 100) /100, count:dataList.length, dataList};
}
/**
* getObjectListOut 获取对象数组结果
* @param title 数据标题
* @param data 数据体 [{value:"", value:"", unit:""}]
* @returns {title:数据标题, dataList:[{name:"", value:"", key1:"", key2:""}] }
*/
export function getObjectListOut(title, data) {
//todo 没有特殊逻辑
return {title, dataList:data};
}
/**
* getRankOut 获取排名结果
* @param title 数据标题
* @param data 数据体 {unit, max, dataInfo:[{key, value, details}, {}, {}, {}] }
* @returns {title:数据标题, max, unit dataList:[{name, value, unit, rankNumber}] }
*/
export function getRankOut(title, data) {
let {unit, max, dataInfo} = data;
let dataList = [];
dataInfo.forEach((info, index) => {
let {key, value} = info;
let rankNumber = index + 1;
dataList.push({name:key, value, details:info.details, rankNumber});
});
return { title, unit, max, dataList };
}
/**
* getRadarChartOut 获取雷达图
* @param title 数据标题
* @param data 数据体 [{key, value, max, unit}]
* @returns {title:数据标题, dataList:[{name:"指标名称", max:"最大值", value:"当前值", unit:"单位"}]}
*/
export function getRadarChartOut(title, data) {
let dataList = [];
data.forEach(info => {
dataList.push({
name:info.key,
value:info.value,
max:info.max,
unit:info.unit
});
});
return {title, dataList};
}
/**
* getMapOut 地图数据
* @param title 数据标题
* @param data 数据体 [{name:数据名称, x:x坐标, y:坐标, coordinate:[经度, 纬度], unit:单位, value:值, details:"补充"}]
* @returns {title:数据标题, dataList:[{name:数据名称, x:x坐标, y:坐标, coordinate:[经度, 纬度], unit:单位, value:值, details:"补充"} ] }
*/
export function getMapOut(title, data) {
//todo 无特殊逻辑
return {title, dataList:data};
}
/**
* getScatterFigureOutData 获取撒点图的返回结果
* @param title 标题
* @param data 数据 格式 [{x, y, name}, {x, y, name}, {x, y, name}, {x, y, name}]
* @returns { title:标题, xMax:x轴最大值, xMin:x最小值, yMax:y最大值, yMin:y最小值, dataList:[{name:点的名称, value:[x坐标, y坐标]} ] };
*/
export function getScatterFigureOutData(title, data) {
let dataList = [];
let xMaxNumber = 0;
let xMinNumber = new Date().valueOf();
let yMaxNumber = 0;
let yMinNumber = new Date().valueOf();
data.forEach(item => {
let { x, y, name } = item;
let xCoordinateInfo = separateDataAndUint(x);
let yCoordinateInfo = separateDataAndUint(y);
const XNumber = xCoordinateInfo.dataNum;
const YNumber = yCoordinateInfo.dataNum;
yMaxNumber = Math.max(YNumber, yMaxNumber);
yMinNumber = Math.min(YNumber, yMinNumber);
xMaxNumber = Math.max(XNumber, xMaxNumber);
xMinNumber = Math.min(XNumber, xMinNumber);
let value = [XNumber, YNumber];
dataList.push({ value, name:name || "" });
});
let xMaxMinInfo = unifiedMaxAndMinValueAndStep(xMaxNumber, xMinNumber);
let yMaxMinInfo = unifiedMaxAndMinValueAndStep(yMaxNumber, yMinNumber);
return { title, xMax:xMaxMinInfo.maxNumber, xMin:xMaxMinInfo.minNumber, yMax:yMaxMinInfo.maxNumber, yMin:yMaxMinInfo.minNumber, dataList };
}
import { BizError } from "../util/bizError";
import pyfl from 'pyfl';
//disintegrate 分解二维数据源数据
/**
* planarArrForObjectList 解析二维数组
* @param planarArr 二维数组 例子:[[title1, title2, title3, title4],[value1, value2, value3, value4],[value5, value6, value7, value8]]
* @param titleIndex 标题集合所在第一层数组的下标
* @param titleList 自定义标题列表 不传则会取每个title的中文首字母作为key
* @returns {"dataList":[{title1:value1, title2:value2, title3:value3, title4:value4}, {title1:value5, title2:value6, title3:value7, title4:value8}], titleList:[]}
*/
export function planarArrForObjectList(planarArr, titleIndex = 0, titleList = []) {
let dataTitleList = [];
let dataMaxLength = 0;
for (let i = titleIndex; i< planarArr.length; i++) {
let subList = planarArr[i];
if (i == titleIndex) {
dataTitleList = subList;
continue;
}
dataMaxLength = Math.max(subList.length, dataMaxLength);
}
let useTitleList = !titleList.length ? changeChineseTitleIntoEnglish(dataTitleList) : titleList;
if (dataMaxLength == 2 && !titleList.length) useTitleList = ["key", "value"];
if (dataTitleList.length < dataMaxLength ) throw new BizError(`解析时数据异常 数据长度:${dataMaxLength} 大于 标题长度${dataTitleList}`);
if (titleList.length && titleList.length < dataMaxLength) throw new BizError(`解析时数据异常 传入标题长度${titleList.length} 数据最大长度${dataMaxLength}`);
let dataList = [];
for (let i = (titleIndex + 1); i< planarArr.length; i++) {
let subList = planarArr[i];
let addInfo:any = {};
subList.forEach((item, index) => {
let key = useTitleList[index];
let value = item;
addInfo[key] = value;
});
dataList.push(addInfo);
}
return {dataList, titleList:useTitleList };
}
function changeChineseTitleIntoEnglish(titles) {
let result = [];
titles.forEach(chineseStr => {
result.push(pyfl(chineseStr).toLowerCase());
});
return result;
}
/**
* planarArrDeconstruct 解构二维数组
* 第一列是名称
* @param planarArr 二维数组 例:[[name, 1月, 2月, 3月],[数据1, 1月数据, 2月数据,3月数据 ],[数据2, 1月数据, 2月数据,3月数据]]
* @param titleIndex 标题集合所在第一层数组的下标
* @returns [{"name":"", data:[{key:"1月", value:"1月数据"}, {key:"2月", value:"2月数据"} ]}];
*/
export function planarArrDeconstruct(planarArr, titleIndex = 0) {
let dataInfo = []
let titleList = [];
for (let i = titleIndex; i < planarArr.length; i++) {
let subList = planarArr[i];
if (titleIndex == i){
titleList = subList;
} else {
let thisDataName = "";
let thisDataList = [];
subList.forEach((item, index) => {
if (!index) {
thisDataName = item;
return;
}
let key = titleList[index];
thisDataList.push({key, value:item});
});
dataInfo.push({name:thisDataName, data:thisDataList});
}
}
return dataInfo;
}
/**
* planarArrDecollateForIndex 拆解二维数组
* @param planarArr 二维数组
* @param decollateIndex 拆解开始的下标
* @returns {headerList:decollateIndex下标之前的集合(包括decollateIndex), bodyList:decollateIndex下标之后的集合(不包括decollateIndex)}
*/
export function planarArrDecollateForIndex(planarArr, decollateIndex = 0) {
let headerList = planarArr.slice(decollateIndex, decollateIndex + 1);
let bodyList = planarArr.slice(decollateIndex + 1, planarArr.length);
return {headerList, bodyList};
}
//excel 和 接口都可以使用的格式化数据的方法
/**
* objBecomeOfList 对象变成数组 value不限制类型
* @param obj 对象 {"key1":"value1", "key2":"value2"}
* @param keyName 指定key的名称 默认 name
* @param valueName 指定value的名称 默认 data
* @returns [{name:"key1", "data":"value1"}, ...]
*/
export function objBecomeOfList(obj, keyName="name", valueName="data") {
let result = [];
for (let key in obj) {
let once:any = {};
once[keyName] = key;
once[valueName] = obj[key];
result.push(once);
}
return result;
}
/**
* objChangeKey obj改变key
* @param obj {"key1":"value1", "key2":"value2"}
* @param checkKeyInfo {"key1":"eKey1", "key2":"eKey2"}
* @returns
*/
export function objChangeKey(obj, checkKeyInfo) {
let result = {};
for (let key in obj) {
let newKey = checkKeyInfo[key] || key;
result[newKey] = obj[key];
}
return result;
}
/**
* objListChangeKey objList 改变key
* @param objList
* @param checkKeyInfo
* @returns
*/
export function objListChangeKey(objList, checkKeyInfo) {
return
}
\ No newline at end of file
/**
* separateDataAndUint 截取字符串中的单位
* @param str 待处理字符串
* @returns {dataNumber:数据, dataUnit:单位}
*/
export function separateDataAndUint(str) {
str = `${str}`;
if (!str) return {dataNum:0, dataUnit:""};
let dataNum = parseFloat(str.replace(/[\u4E00-\u9FA5a-zA-Z]+/,""));
let dataUnit = str.replace(/^(-)?\d+(\.\d+)?/, "");
return {dataNum, dataUnit};
}
/**
* unifiedMaxAndMinValueAndStep 求最大最小值以及间隙
* @param max 最大
* @param min 最小
* @param count 分多少份 默认5
* @returns {maxNumber:向上留值最大, minNumber:向下留值最小, stepNumber:间隔};
*/
export function unifiedMaxAndMinValueAndStep(max, min, count=5) {
let maxNumber = Math.ceil(max);
let minNumber = Math.floor(min);
function getNumberInLength(length) {
let lengthCount = 1;
for (let i = 1; i < length; i++) {
lengthCount = lengthCount * 10;
}
return lengthCount;
}
let maxNumberLength = getNumberInLength(`${maxNumber}`.length);
let minNumberLength = getNumberInLength(`${minNumber}`.length);
if (maxNumber <= 10 && maxNumber > 0) maxNumber = 10;
else maxNumber = Math.ceil(maxNumber / maxNumberLength) * maxNumberLength;
minNumber = Math.floor(minNumber / minNumberLength) * minNumberLength;
let stepNumber = Math.ceil((maxNumber - minNumber) / count);
return {maxNumber, minNumber, stepNumber};
}
import { systemConfig } from "../config/serverConfig";
//导入sequelize模块
const Sequelize = require('sequelize');
var mysqlDB;
export async function initMysqlDB() {
mysqlDB = new Sequelize(systemConfig.mysqldb.dataBase,systemConfig.mysqldb.user,systemConfig.mysqldb.pwd,{
host:systemConfig.mysqldb.host,
port:systemConfig.mysqldb.port,
dialect:'mysql', //数据库类型
pool:{ //数据库连接池
max:20, //最大连接对象的个数
min:5, //最小连接对象的个数
idle:1000 //最长等待时间,单位为毫秒
},
timezone: '+08:00', //东八时区
dialectOptions: {
dateStrings: true,
typeCast: true
},
});
}
export { mysqlDB };
\ No newline at end of file
import { initConfig, systemConfig} from "./config/serverConfig";
import * as mysqlDB from "./db/mysqlInit";
import { initMysqlModel } from "./model/sqlModelBind";
import { httpServer } from "./net/http_server";
async function lanuch() {
/**初始化配置解析 */
await initConfig();
/**初始化数据库 */
// await mongoDB.initDB();
// await initModel();
/**初始化sql */
await mysqlDB.initMysqlDB();
await initMysqlModel();
/**创建http服务 */
httpServer.createServer(systemConfig.port);
// await smsTask();
console.log('This indicates that the server is started successfully.');
}
lanuch();
import { bizlive } from "tencentcloud-sdk-nodejs";
import { ERRORCODEENUM } from "../config/errorEnum";
/**
* 中间件 错误返回
* @param err
* @param req
* @param res
* @param next
*/
export function httpErrorHandler(err, req, res, next) {
console.log("in httpErrorHandler");
console.log(err);
//todo 自定义错误编码
if (err) {
if ( ERRORCODEENUM[err.message] ) {
res.success({success:false, msg:err.message, code:ERRORCODEENUM[err.message]});
next();
}
else {
res.success({success:false, msg:err.message, code:500});
next();
}
}
}
\ No newline at end of file
import { ERRORENUM } from "../config/errorEnum";
import { systemConfig } from "../config/serverConfig";
import { EccTableConfig } from "../config/mongoTableConfig";
import { BizError } from "../util/bizError";
import { mysqlModelMap } from "../model/sqlModelBind";
/**
* 中间件 校验连接对象token
* @param req
* @param res
* @param next
* @returns
*/
export async function checkMongoSign(req, res, next) {
if (!req.headers) req.headers = {};
let sign = req.headers.sign;
let table = req.headers.table;
if (sign != systemConfig.sign) return next( new BizError(ERRORENUM.身份验证失败, `传入的sign值为:${sign}`) );
if (!table) return next( new BizError(ERRORENUM.缺少必要参数_表名, `传入的table值为:${table}`) );
if (!EccTableConfig[table]) return next( new BizError(ERRORENUM.不存在表, `传入的table值为:${table}`) );
next();
}
/**
* 中间件 校验连接对象token
* @param req
* @param res
* @param next
* @returns
*/
export async function checkMySqlSign(req, res, next) {
if (!req.headers) req.headers = {};
let sign = req.headers.sign;
let table = req.headers.table;
if (sign != systemConfig.sign) return next( new BizError(ERRORENUM.身份验证失败, `传入的sign值为:${sign}`) );
if (!table) return next( new BizError(ERRORENUM.缺少必要参数_表名, `传入的table值为:${table}`) );
if (!mysqlModelMap[table]) return next( new BizError(ERRORENUM.不存在表, `传入的table值为:${table}`) );
req.tableModel = mysqlModelMap[table];
next();
}
\ No newline at end of file
export function watch(req, res, next) {
res.success = success.bind({res:res, req:req});
return next();
}
/**
* 中间件正确返回方法
* @param data
*/
function success(data) {
let resultPack;
if (data ) {
if ( data.success === undefined || data.success === true ) {
resultPack = {data, success:true, code:200};
}
else {
resultPack = data;
}
}else {
resultPack = {code:500, success:false, msg:'result is null'};
}
this.res.send(resultPack);
}
/**
* mysql 数据层
*/
import { TablesConfig } from "../config/mysqlTableConfig";
import { mysqlDB } from "../db/mysqlInit";
let mysqlModelMap = {};
export async function initMysqlModel() {
/**初始化表 */
for (let i =0; i < TablesConfig.length; i++) {
let { tableName, schema } = TablesConfig[i];
let schemaConf = {
freezeTableName:true, //true表示使用给定的表名,false表示模型名后加s作为表名
timestamps:false //true表示给模型加上时间戳属性(createAt updateAt),false表示不带时间戳属性
};
let model = mysqlDB.define( tableName, schema, schemaConf);
mysqlModelMap[tableName] = await model.sync({}).then();
// try {
// await model.sync({ force: false });
// mysqlModelMap[tableName] = model;
// } catch (error) {
// console.error(`同步表 ${tableName} 失败:`, error);
// }
}
/**初始化表关联 */
for (let i =0; i < TablesConfig.length; i++) {
let { tableName, association } = TablesConfig[i];
association.forEach( (item:any) => {
if (item) {
let {type, check, foreignKey} = item;
if (type == "hasOne") {
mysqlModelMap[check].hasOne(mysqlModelMap[tableName]);
} else if (type == "hasMany") {
mysqlModelMap[tableName].hasMany(mysqlModelMap[check], {foreignKey});
}
mysqlModelMap[check].belongsTo(mysqlModelMap[tableName], {foreignKey});
// else if (type === "belongsTo") {
// mysqlModelMap[tableName].belongsTo(mysqlModelMap[check], { foreignKey });
// }
console.log("---->", mysqlModelMap[tableName].getTableName());
console.log("====>", mysqlModelMap[check].getTableName());
}
});
}
}
export { mysqlModelMap };
\ No newline at end of file
import express = require('express');
import bodyParser = require('body-parser');
import routers = require('../routers/router');
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 historyFallback from 'express-history-api-fallback'; // 正确导入默认导出的函数
export class httpServer {
static createServer(port: number) {
var httpServer = express();
httpServer.all('*', (req, res, next) => {
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('Access-Control-Allow-Headers', 'Content-Type,request-origin,userid,token');
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
res.header('Access-Control-Allow-Credentials', 'true');
res.header("X-Powered-By", ' 3.2.1');
next();
});
httpServer.use(express.static('public'));
httpServer.use(express.static('img'));
httpServer.use(compression());
httpServer.use(watch);
httpServer.use(bodyParser.json({ limit: "500kb" }));
routers.setRouter(httpServer);
httpServer.use(httpErrorHandler);
const root = path.join(__dirname, "../../public");
httpServer.use(express.static(root))
// 使用 fallback 函数
// httpServer.use(fallback('index.html', { root }));
httpServer.use(historyFallback('index.html', { root }));
console.log('web listen on port:' + port);
httpServer.listen(port);
console.log('server listen on port:' + port);
return httpServer;
}
}
\ No newline at end of file
import asyncHandler from 'express-async-handler';
import * as adminBiz from '../biz/admin';
// 霍兰德测试接口
export function setRouter(httpServer){
httpServer.post('/admin/login', asyncHandler(login));
httpServer.post('/admin/userlist', asyncHandler(getUserList));
httpServer.post('/admin/details', asyncHandler(getUserInfoById));
httpServer.post('/admin/output', asyncHandler(outPutData));
};
async function login(req, res) {
let {username, password} = req.body;
let result = await adminBiz.login(username, password);
res.success(result);
}
async function getUserList(req, res) {
let {phone, createStartTime, createEndTime, current} = req.body;
let result = await adminBiz.getUserList(phone, createStartTime, createEndTime, current);
res.success(result);
}
async function getUserInfoById(req, res) {
let {infoid, testType} = req.body;
let result = await adminBiz.getUserInfoById(infoid, testType);
res.success(result);
}
async function outPutData(req, res) {
let {card, createStartTime, createEndTime, area} = req.body;
let result = await adminBiz.outPutData(card, createStartTime, createEndTime, area);
res.success(result);
}
import asyncHandler from 'express-async-handler';
import * as huolandeBiz from '../biz/huolande';
// 霍兰德测试接口
export function setRouter(httpServer){
httpServer.post('/question/getarea', asyncHandler(getArea));
httpServer.post('/question/addusers', asyncHandler(addUsers));
httpServer.post('/question/question', asyncHandler(getQuestion));
httpServer.post('/question/addusersinfo', asyncHandler(addUsersInfo));
httpServer.post('/huolande/finalscore', asyncHandler(getFinalScore));
httpServer.post('/chuangye/finalscore', asyncHandler(getChuangYeScore));
};
async function addUsers(req, res) {
let {testType, name, card, phone} = req.body;
let result = await huolandeBiz.addUsers(testType, name, phone, card);
res.success(result);
}
async function getArea(req, res) {
let result = await huolandeBiz.getArea();
res.success(result);
}
async function getQuestion(req, res) {
let { testType, chapter, isTest, isPrevious } = req.body;
let result = await huolandeBiz.getQuestion(testType, chapter, isTest, isPrevious);
res.success(result);
}
async function addUsersInfo(req, res) {
let {infoid, chapter, option, testType, isTest} = req.body;
let result = await huolandeBiz.addUsersInfo(infoid, chapter, option, testType, isTest);
res.success(result);
}
async function getFinalScore(req, res) {
let {infoid, isTest} = req.body;
let result = await huolandeBiz.getFinalScore(infoid, isTest);
res.success(result);
}
async function getChuangYeScore(req, res) {
let {infoid, isTest} = req.body;
let result = await huolandeBiz.getChuangYeScore(infoid, isTest);
res.success(result);
}
/**
* 总路由入口
*/
import * as huolandeRouter from './huolande';
import * as adminRouter from './admin';
import * as verticalScreenRouter from './verticalScreen';
export function setRouter(httpServer){
huolandeRouter.setRouter(httpServer);
adminRouter.setRouter(httpServer);
verticalScreenRouter.setRouter(httpServer);
}
/**
* 竖屏
*/
import asyncHandler from 'express-async-handler';
import * as titleRouters from '../biz/title';
import * as employmentRouters from '../biz/employment';
import * as popupRouters from '../biz/popup';
export function setRouter(httpServer){
/**竖屏 */
httpServer.get('/verticalscreen/title', asyncHandler(titleRouters.getVerticalScreenTitle));
httpServer.get('/verticalscreen/list', asyncHandler(employmentRouters.getVerticalScreen));
httpServer.get('/verticalscreen/policy', asyncHandler(employmentRouters.getVerticalPolicy));
httpServer.get('/verticalscreen/detailed', asyncHandler(employmentRouters.getVerticalJobDetailed));
httpServer.post('/verticalscreen/title', asyncHandler(titleRouters.getVerticalScreenTitle));
httpServer.post('/verticalscreen/list', asyncHandler(employmentRouters.getVerticalScreen));
httpServer.post('/verticalscreen/policy', asyncHandler(employmentRouters.getVerticalPolicy));
httpServer.post('/verticalscreen/detailed', asyncHandler(employmentRouters.getVerticalJobDetailed));
/**大屏 */
httpServer.get('/largescreen/title', asyncHandler(titleRouters.getLargeScreenTitle));
httpServer.get('/largescreen/qwlist', asyncHandler(employmentRouters.getQWLargeScreen));
httpServer.get('/largescreen/pxlist', asyncHandler(employmentRouters.getPXLargeScreen));
httpServer.get('/largescreen/pxdetailed', asyncHandler(employmentRouters.getPXJobDetailed));
httpServer.post('/largescreen/title', asyncHandler(titleRouters.getLargeScreenTitle));
httpServer.post('/largescreen/qwlist', asyncHandler(employmentRouters.getQWLargeScreen));
httpServer.post('/largescreen/pxlist', asyncHandler(employmentRouters.getPXLargeScreen));
httpServer.post('/largescreen/pxdetailed', asyncHandler(employmentRouters.getPXJobDetailed));
}
import { ERRORENUM } from "../config/errorEnum";
import { BizError } from "../util/bizError";
/**
* 校验value是否符合传入的枚举
* @param name 被掉用名称 用于输出异常日志
* @param key 目标字段 用于输出异常日志
* @param enumConf 目标枚举
* @param value 目标值
* 无返回 有异常直接报错
*/
export function eccEnumValue(name:string, key:string, enumConf, value:any) {
let eccSuccess = true;
if ( typeof value == 'number' ) {
if (!enumConf[value] ) eccSuccess = false;
} else if (Array.isArray(value)) {
value.forEach(item => {
if ( !enumConf[item] ) eccSuccess = false;
});
}
if (!eccSuccess) throw new BizError(ERRORENUM.文件不存在, `${name} 下的 ${key} 字段值为 ${value} 不满足枚举范围`);
}
/**
* 将枚举值转换成对应的枚举名(key)
* @param enumConf 目标枚举
* @param value 目标值
* @returns string 返回字符串 如果传入多个枚举值,就拼接字符串
*/
export function changeEnumValue(enumConf, value:any) {
if (!value) return '';
if ( typeof value == 'number' ) {
let str = enumConf[value];
/**特化处理 */
if(/_dou/.test(str)) str = str.replace(/_dou/gm, ",");
if(/_zyh/.test(str)) str = str.replace(/_zyh/gm, "“");
if(/_yyh/.test(str)) str = str.replace(/_yyh/gm, "”");
if(/_dun/.test(str)) str = str.replace(/_dun/gm, "、");
if(/_ju/.test(str)) str = str.replace(/_ju/gm, "。");
return str
} else if (typeof value == 'string') {
try {//兼容数据库 '[1,2,3]'
value = JSON.parse(value);
}catch(err) {
return enumConf[parseInt(value)];
}
}
let str = "";
value.forEach((item, index) => {
let subStr = enumConf[item];
/**特化处理 */
if(/_dou/.test(subStr)) subStr = subStr.replace(/_dou/gm, ",");
if(/_zyh/.test(subStr)) subStr = subStr.replace(/_zyh/gm, "“");
if(/_yyh/.test(subStr)) subStr = subStr.replace(/_yyh/gm, "”");
if(/_dun/.test(subStr)) subStr = subStr.replace(/_dun/gm, "、");
if(/_ju/.test(subStr)) subStr = subStr.replace(/_ju/gm, "。");
str += subStr;
if (index == value.length-1) str+="";
else str += ","
});
return str;
}
\ No newline at end of file
import { ERRORENUM } from "../config/errorEnum";
import { BizError } from "../util/bizError";
/**
* 根据conf配置校验请求参数
* @param conf 配置
* @param param 表单
* @param skipKeys []不必填的字段
*/
export function eccReqParamater(conf:object, param, skipKeys?) {
skipKeys = skipKeys || [];
let skipMap = {};
skipKeys.forEach(keyName => {
skipMap[keyName] = 1;
});
/**校验多余字段 */
for (let key in param) {
if (!conf[key]) throw new BizError(ERRORENUM.参数错误, `多余${key}字段`);
}
/**校验必填和缺失字段 */
for (let key in conf) {
let confType = conf[key];
let value = param[key];
let valueType = typeof value;
if ( value == null || value == undefined ) {
if (!skipMap[key]) throw new BizError(ERRORENUM.参数错误, `缺失${key}字段`);
} else {
let isError = false;
let errorStr = "";
switch(confType) {
case 'Number':
if ( confType.toLowerCase() != valueType ) isError = true;
else {
if ((""+param[key]).indexOf('.') > -1) {
param[key] = parseInt(`${param[key] *100}`)/100;
}
}
break;
case 'String':
case 'Boolean':
case 'Object':
if ( confType.toLowerCase() != valueType ) isError = true;
break;
case '[Number]':
if ( !Array.isArray(param[key]) ) isError = true;
for (let i =0; i < param[key].length; i++) {
let item = param[key][i];
if ( typeof item != 'number' ) {
isError = true;
errorStr = `${key}应是number型数组其中下标${i}${typeof item}`;
}
}
break;
case '[Object]':
if ( !Array.isArray(param[key]) ) isError = true;
for (let i =0; i < param[key].length; i++) {
let item = param[key][i];
if ( typeof item != 'object' ) {
isError = true;
errorStr = `${key}应是object型数组其中下标${i}${typeof item}`;
}
}
break;
case '[String]':
if ( !Array.isArray(param[key]) ) isError = true;
for (let i =0; i < param[key].length; i++) {
let item = param[key][i];
if ( typeof item != 'string' ) {
isError = true;
errorStr = `${key}应是String型数组其中下标${i}${typeof item}`;
}
}
break;
// case 'Address':
// /**地址类型 基本数据类型为数组字符串但是要判断层级关系 */
// if ( !Array.isArray(param[key]) ) {
// isError = true;
// errorStr = `${key}应是数组形`;
// }
// if ( param[key].length != 4) {
// isError = true;
// errorStr = `${key}超过特定长度4 目前长度 ${param[key].length}`;
// }
// for (let i =0; i < param[key].length; i++) {
// let item = param[key][i];
// if ( typeof item != 'string' ) {
// isError = true;
// errorStr = `${key}应是string型数组其中下标${i}是${typeof item}`;
// }
// }
// /** 不符合规则的 */
// let nullIndex = -1;
// for (let i = 0; i < param[key].length; i++) {
// if (nullIndex != -1) {//出现过空 第一次出现后的位置 都不能有值
// if (param[key]) {
// //做一个特化
// throw new BizError(ERRORENUM.地址数据不完整, `${key} 下标 ${nullIndex} 为空 `);
// }
// }
// if (nullIndex == -1 && !param[key][i]) {
// /**按顺序第一次赋值 */
// nullIndex = i;
// }
// }
// break;
}
errorStr = isError && errorStr == "" ? `${key}应该是${confType}型 而不是${valueType}`: errorStr;
if (isError) throw new BizError(ERRORENUM.参数错误, errorStr);
}
}
return param;
}
\ No newline at end of file
import moment = require("moment");
import { ERRORENUM } from "../config/errorEnum";
import { BizError } from "../util/bizError";
import { FILETYPE } from "../config/enum";
const md5 = require("md5");
export function getUserToken(loginId:string) {
return md5(`${loginId}_${Math.ceil(Math.random()*1000)}${new Date().valueOf()}`);
}
export function getMySqlMs(time?) {
time = time || new Date().valueOf();
// time += (8*3600*1000);
return moment(time).format("YYYY-MM-DD HH:mm:ss");
}
export function getClientMs(time) {
if (!time) return new Date().valueOf();
return new Date(time).valueOf();
}
export function getPartyMemberId(param) {
return md5(`${param}-${new Date().valueOf()}-${Math.ceil(Math.random() * 10000)}`);
}
export function getDefPwd(phone:string) {
return md5(`${phone.slice(5, 11)}`);
}
export function getFileType(fileName) {
let fileType = 0;
fileName.forEach(info => {
let repList = info.split(".");
let type = repList[repList.length-1];
if (!type) throw new BizError(ERRORENUM.文件不存在, `文件名 ${info}`);
let typeNum = 0;
switch(type) {
case 'pdf': typeNum = FILETYPE.pdf; break;
case 'doc':
case 'docx': typeNum = FILETYPE.word; break;
case 'jpg':
case 'png': typeNum = FILETYPE.图片; break;
};
if (typeNum) {
if (!fileType) fileType = typeNum;
else if (fileType != typeNum) fileType = FILETYPE.多类型;
}
});
return fileType;
}
const xlsx = require('node-xlsx');
const path = require('path');
/**
* onceSheetBecomeOfblockData 将excel文件的指定sheet解析成数据块数据
* @param fileName 文件名称
* @param sheetName 表名称
* @returns [ {blockData:数据块(二维数组), blockTitle:"数据标题"}]
*/
export function onceSheetBecomeOfblockData(fileName, sheetName) {
let {sheetMap} = getExcel( path.join(__dirname.substring(0,__dirname.indexOf("out")), "res", fileName ));
// return sheetMap;
let thisBlockData = getBlockData(sheetMap[sheetName]);
return thisBlockData;
}
/**
* 将指定文件夹里的excel文件的指定sheet解析成数据块数据
* @param fileName
* @param sheetName
* @param url
* @returns
*/
export function onceSheetBecomeOfblockDataToUrl(fileName, sheetName, url) {
let {sheetMap} = getExcel( path.join(__dirname.substring(0,__dirname.indexOf("out")), `res${url}`, fileName ));
let thisBlockData = getBlockData(sheetMap[sheetName]);
return thisBlockData;
}
/**
* excelBecomeOfBlockData 将excel所有的sheet解析成数据块
* @param fileName 文件名称
* @returns {"sheetName1":[ {blockData:数据块(二维数组), blockTitle:"数据标题"}], ...}
*/
export function excelBecomeOfBlockData(fileName) {
let {sheetMap} = getExcel( path.join(__dirname.substring(0,__dirname.indexOf("out")), "res", fileName ));
let result = {};
for (let sheetName in sheetMap) {
result[sheetName] = getBlockData(sheetMap[sheetName]);
}
return result;
}
/**
* planaryArrayBecomeOfBlockData 将符合excel规则的sheet二维数组转为 数据块
* @param dataList excel解出来的数据
* @returns thisBlockData 返回数据块集合 格式:blockList = [ {blockData:数据块(二维数组), blockTitle:"数据标题"}]
*/
export function planaryArrayBecomeOfBlockData(planaryArray) {
return getBlockData(planaryArray);;
}
//===
/**
* 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
/**
* 异常类
* 需要和log4js共同使用
*/
import { getBizMsg } from "../config/errorEnum";
import { logError } from "./log";
export class BizError extends Error {
statusCode(statusCode: any) {
throw new Error('Method not implemented.');
}
constructor(...msgs) {
let reqErrorMsg = '';
let logErrorMsg = '';
for (let i = 0; i <msgs.length; i++) {
if (!i) {
let msg = getBizMsg(msgs[i]);
reqErrorMsg = msg;
logErrorMsg = msg;
} else {
logErrorMsg += ` | ${msgs[i]} `;
}
}
logError(logErrorMsg);
super(reqErrorMsg);
}
}
/**
* 日志类
* 包括错误日志 普通日志
* 日志存放在根目录的logs内
*/
let log4js = require('log4js');
let path = require('path');
//log路径
export const systemLogPath = {
errorLogFile:"error",
errorLogDir:"error",
handleLogFile:"handle",
handleLogDir:"handle"
}
//日志根目录
// let baseLogPath = path.resolve(__dirname.substring(0, __dirname.indexOf("out")), 'logs');
let baseLogPath = path.resolve('./', 'logs');
let errFile = path.resolve(baseLogPath, systemLogPath.errorLogDir, systemLogPath.errorLogFile);
let handFile =path.resolve(baseLogPath, systemLogPath.handleLogDir, systemLogPath.handleLogFile);
let config = {
appenders:
{
"rule-console": {"type": "console"},
"errorLogger": {
"type": "dateFile", // 日志类型
"filename": errFile, // 输出文件名
"pattern": "yyyy-MM-dd.log", // 后缀
"alwaysIncludePattern": true, // 上面两个参数是否合并
"encoding": "utf-8", // 编码格式
"maxLogSize": 1000, // 最大存储内容
"numBackups": 3, // 当文件内容超过文件存储空间时,备份文件的数量
"path": `/${systemLogPath.errorLogDir}`
},
"handleLogger": {
"type": "dateFile",
"filename": handFile,
"pattern": "yyyy-MM-dd.log",
"alwaysIncludePattern": true,
"encoding": "utf-8",
"maxLogSize": 1000,
"numBackups": 3,
"path": `/${systemLogPath.handleLogDir}`
}
},
categories: {
"default": {"appenders": ["rule-console"], "level": "all"}, //这个配置一定要有
"errorLogger": {"appenders": ["errorLogger"], "level": "error"},
"handleLogger": {"appenders": ["handleLogger"], "level": "all"}
},
"baseLogPath": path.resolve(baseLogPath, systemLogPath.handleLogDir, systemLogPath.handleLogFile)
};
log4js.configure(config); //加载配置文件
//调用预先定义的日志名称
let errorLogger = log4js.getLogger("errorLogger");
let handleLogger = log4js.getLogger("handleLogger");
let consoleLogger = log4js.getLogger("rule-console");
//错误日志
export function logError(...errStrs) {
let str = "";
errStrs.forEach(item => {
str += item + " | ";
});
errorLogger.error(`errorInfo => ${str}`);
}
//普通日志
export function logHandle(msgStr:string) {
handleLogger.info(`logInfo => ${msgStr}`);
}
//输出日志
export function logConsole(logStr:string) {
consoleLogger.info(`logInfo => ${logStr}`);
}
/**
* 解析xml
*/
var xml2js = require("xml2js");
/**
*
* @param str 需要解析的xml文本
* @returns 解析好的对象
*/
export function analysisXml(str) {
return new Promise( (resolve, reject) => {
xml2js.parseString(str, (err, result) => {
if (err) return reject(err);
return resolve(result);
});
});
}
\ No newline at end of file
/**
* 零碎的通用工具
*/
import moment = require("moment");
/**
* 匹配新旧对象变化
* 将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;
}
/**
* 根据conf截取data中的数据
* @param conf
* @param data
* @returns
*/
export function extractData(conf, data, isAdmin) {
let result = {};
for (let key in conf) {
let confInfo = conf[key];
if (confInfo.changeDate) {
if (isAdmin) result[key] = data[key] ? moment(data[key]).format("YYYY-MM-DD") : '-';
else result[key] = data[key] || 0;
} else if (confInfo.isAdd && isAdmin) {
let addStr = "";
data[key].forEach(str => {
addStr += str;
});
result[key] = addStr;
}
else {
result[key] = data[key];
if (typeof result[key] == 'string' && !result[key]) result[key] = '';
}
}
return result;
}
/**
* 校验数据对象是否有空
* @param data
* @param sensitive 敏感校验 true时 0 和 ""会校验失败 false时 校验成功
* @returns true/false true = 有空值 false=无空值
*/
export function checkDataHaveNull(data:object, sensitive:boolean) {
if (Array.isArray(data)) return data.length == 0;
if (Object.keys(data).length == 0) return true;
let success = false;
for (let key in data) {
if (data[key] == null || data[key] == undefined) success = true;
if (sensitive) {
if (data[key] === 0 || data[key] === "" ) success = true;
}
}
return success;
}
\ No newline at end of file
/**
* 请求工具
*/
import * as request from 'request';
import { BizError } from './bizError';
/**
* 请求接口(get)
* @param url 路由
* @param query 请求参数
* @param headers 请求头
* @returns
*/
export function get(url:string, query?, headers?) {
if (!url || (url.search(/http:/) && url.search(/https:/)) ) throw new BizError(!url ? "请求地址为空" : "请求地址错误");
return new Promise((resolve, reject)=>{
let paramater:any = { url, json:true };
if (query) paramater.qs = query;
if (headers) paramater.headers = headers;
request.get(paramater, function (err, r, body) {
if (err) return reject(err);
if (r && r.statusCode != 200) return reject(new Error('httpError:'+r.statusCode));
resolve(body);
});
})
}
export function post(url, body, headers) {
if (!url || (url.search(/http:/) && url.search(/https:/)) ) throw new BizError(!url ? "请求地址为空" : "请求地址错误");
let header = {"content-type": "application/json"};
return new Promise((resolve, reject)=>{
request({
url: url,
method: "POST",
json: true,
headers: Object.assign(header, headers),
body: body
}, function(error, response, body) {
if (!error && response.statusCode == 200) {
resolve(body);
}
else {
// reject(error)
}
});
})
}
export function postForm(url, body, headers) {
if (!url || (url.search(/http:/) && url.search(/https:/)) ) throw new BizError(!url ? "请求地址为空" : "请求地址错误");
return new Promise((resolve, reject)=>{
request({
url: url,
method: "POST",
json: true,
form:body
}, function(error, response, res) {
if (!error) {
resolve(res);
}
else {
reject(error)
}
});
})
}
{
"compilerOptions": {
"module": "commonjs",
"target": "ES2017",
"sourceMap": true,
"rootDir":"./src",
"outDir":"./out",
"esModuleInterop": true,
// "strict": true,
},
"exclude": [
"node_modules",
]
}
// {
// "compilerOptions": {
// "target": "ES6",
// "module": "commonjs",
// "esModuleInterop": true,
// "outDir": "./dist",
// "strict": true
// },
// "include": ["src/**/*"]
// }
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