import {
|
// getManager,
|
EntityManager,
|
MoreThan,
|
MoreThanOrEqual,
|
In,
|
LessThan,
|
LessThanOrEqual,
|
Not,
|
IsNull,
|
Between,
|
Raw,
|
Like,
|
getConnection
|
} from "typeorm";
|
import * as sql from "mssql";
|
import { SysParamValue } from "../entity/sys/core/sysParamValue";
|
import { SysUserLog } from "../entity/sys/core/sysUserLog";
|
|
import { isObject } from "util";
|
import BaseService from "./baseService";
|
import moment = require("moment");
|
import * as ip from "ip";
|
|
/**
|
* 通用方法
|
*/
|
export default class CommonService extends BaseService {
|
//#region 属性
|
/**
|
* 主数据,读写
|
*/
|
public get dbWrite(): EntityManager {
|
let dbName = this.body.isLoadHisotry ? "mssql-his" : "default";
|
let conn = getConnection(dbName);
|
if (!conn.isConnected) {
|
let db = this.app.mongodb;
|
let collection = db.collection("dbConnection");
|
collection.insertOne({
|
type: dbName,
|
msg: `dbWrite ${dbName}数据库重连,` + ip.address(),
|
createDate: new Date()
|
});
|
conn.connect();
|
}
|
let manager = conn.manager;
|
return manager;
|
}
|
|
/**
|
* 主数据,只读
|
*/
|
public get dbRead(): EntityManager {
|
let dbName = this.body.isLoadHisotry ? "mssql-his" : "mssql-read";
|
let conn = getConnection(dbName);
|
if (!conn.isConnected) {
|
let db = this.app.mongodb;
|
let collection = db.collection("dbConnection");
|
collection.insertOne({
|
type: dbName,
|
msg: `dbWrite ${dbName}数据库重连,` + ip.address(),
|
createDate: new Date()
|
});
|
conn.connect();
|
}
|
let manager = conn.manager;
|
return manager;
|
}
|
//#endregion
|
|
//#region 校验数据库连接是否正确
|
public async checkDbConnection() {
|
let conn = getConnection("default");
|
let ipValue = ip.address();
|
if (!conn.isConnected) {
|
let db = this.app.mongodb;
|
let collection = db.collection("dbConnection");
|
await collection.insertOne({
|
type: "default",
|
msg: "checkDbConnection default数据库重连," + ipValue
|
});
|
await conn.connect();
|
}
|
|
conn = getConnection("mssql-read");
|
if (!conn.isConnected) {
|
let db = this.app.mongodb;
|
let collection = db.collection("dbConnection");
|
await collection.insertOne({
|
type: "default",
|
msg: "checkDbConnection mssql-read数据库重连," + ipValue
|
});
|
await conn.connect();
|
}
|
}
|
//#endregion
|
|
//#region 校验数据库连接是否正确
|
public async errorLog(type, msg) {
|
let db = this.app.mongodb;
|
let collection = db.collection("errorLog");
|
await collection.insertOne({
|
type: type,
|
ip: ip.address(),
|
msg: msg,
|
createDate: new Date()
|
});
|
}
|
//#endregion
|
|
//#region getTreeDataAll
|
|
/**
|
* 获得完整树结构数据
|
* @param loadInfo - 加载参数
|
* @param level - 递归深度
|
*/
|
public async getTreeDataAll(loadInfo, level) {
|
let treeList = await this.getTreeData(loadInfo);
|
if (level > 10) return treeList; //大于10级返回,防止死循环
|
|
for (let item of treeList) {
|
if (typeof item === "object" && item && item["hasChild"] === 1) {
|
//获得子集
|
loadInfo.where[loadInfo.parentName] = item[loadInfo.keyName];
|
var subList = await this.getTreeDataAll(loadInfo, level + 1);
|
item["children"] = subList;
|
}
|
}
|
|
return treeList;
|
}
|
//#endregion
|
|
//#region getTreeData
|
/**
|
* 获得一级树结构数据
|
* @param loadInfo - 加载参数
|
*/
|
public async getTreeData(loadInfo) {
|
let entityClassName = (loadInfo.tableView || loadInfo.tableName).replace(/_/g, "");
|
let _entityClassName = this.ctx.helper.caseStyle(entityClassName);
|
let where = loadInfo.where;
|
let orderBy = loadInfo.orderBy;
|
let entityPath = `../entity/${loadInfo.folder}/` + _entityClassName;
|
|
let module = await import(entityPath);
|
let entity = module[entityClassName];
|
|
let extendColumns = [loadInfo.parentName, loadInfo.keyName + " AS value", loadInfo.nodeName + " AS label", loadInfo.keyName, loadInfo.nodeName];
|
if (loadInfo.extendColumns) {
|
extendColumns = extendColumns.concat(loadInfo.extendColumns.split(","));
|
}
|
let hasChild = `(case when exists(Select 1 from ${loadInfo.tableName} sub Where m.${loadInfo.keyName}=sub.${loadInfo.parentName}) then 1 else 0 end)`;
|
|
let rep = this.dbRead.getRepository(entity);
|
// let dataList = await rep.find({
|
// select: extendColumns,
|
// addSelect: hasChild,
|
// where: where,
|
// order: orderBy
|
// });
|
|
let builder = rep.createQueryBuilder("m");
|
let dataList = await builder.select(extendColumns).addSelect(hasChild, "hasChild").where(where).orderBy(orderBy).getRawMany();
|
|
return dataList;
|
}
|
//#endregion
|
|
//#region getCodeRegular
|
/**
|
* 获得单据编码
|
* @param menu_Id - 菜单ID
|
* @param userProduct_Id - 账套ID
|
*/
|
public async getCodeRegular(menu_Id: number, userProduct_Id?: number) {
|
let { ctx } = this;
|
let code = "";
|
let userInfo = await ctx.helper.userInfo();
|
if (!userProduct_Id) {
|
userProduct_Id = userInfo.userProduct_Id;
|
}
|
const connection: any = await this.dbWrite.connection;
|
let request = new sql.Request(connection.driver.master);
|
request.input("Menu_Id", menu_Id);
|
request.input("userProduct_Id", userProduct_Id);
|
request.output("code", sql.NVarChar(50));
|
let result = await request.execute("sp_GetCodeRegularEx");
|
code = result.output.code;
|
let str = "SO";
|
|
if (menu_Id == 500) {
|
const date = new Date();
|
let Month = date.getMonth() + 1 > 9 ? date.getMonth() + 1 : "0" + (date.getMonth() + 1);
|
let day = date.getDate() > 9 ? date.getDate() : "0" + date.getDate();
|
let hours = date.getHours() > 9 ? date.getHours() : "0" + date.getHours();
|
let Minutes = date.getMinutes() > 9 ? date.getMinutes() : "0" + date.getMinutes();
|
code = str + date.getFullYear() + Month + day + hours + Minutes + date.getMilliseconds();
|
}
|
return code;
|
}
|
//#endregion
|
//#region getConfigBool
|
/**
|
* 获得指定名称的系统参数值
|
* @param loadInfo - 加载参数
|
*/
|
public async getConfigBool(key: string) {
|
let val = await this.getConfig(key, (await this.userInfo).userProduct_Id);
|
return val == "1";
|
}
|
//#endregion
|
|
//#region getConfig
|
/// <summary>
|
/// 获得指定名称的系统参数值
|
/// </summary>
|
/// <param name="keyCode">关键词</param>
|
/// <returns></returns>
|
public async getConfig(keyCode: string, userProduct_Id?: number) {
|
let userInfo = await this.ctx.helper.userInfo();
|
|
if (userInfo && !userProduct_Id) {
|
userProduct_Id = userInfo.userProduct_Id;
|
}
|
|
let dataInfo = await this.dbRead.findOne(SysParamValue, {
|
value02: keyCode,
|
userProduct_Id: userProduct_Id,
|
type_Id: 585
|
});
|
let value = dataInfo ? dataInfo.value03 : "";
|
|
//获取默认设置
|
if (!value) {
|
let where = "type_Id=585 And isnull(userProduct_Id, 0)=0 And value02 =:keyCode";
|
dataInfo = await this.dbRead
|
.createQueryBuilder(SysParamValue, "t")
|
.where(where, {
|
keyCode: keyCode
|
})
|
.getOne();
|
value = dataInfo ? dataInfo.value03 : "";
|
}
|
|
return value;
|
}
|
|
//#endregion
|
|
//#region saaSAuthList
|
/**
|
* 当前用户SaaS权限集合
|
*/
|
public async saaSAuthList(): Promise<Array<any>> {
|
let { ctx, app } = this;
|
let userRedis = app.redis.clients.get("userInfo");
|
|
let saaSAuthList = null;
|
var guid = ctx.header.guid;
|
var accessTokenKey = "SaaSAuth_" + guid;
|
if (guid) {
|
saaSAuthList = await userRedis.get(accessTokenKey);
|
}
|
//如果缓存没有,在去访问日志里获取
|
if (!saaSAuthList && guid) {
|
var logInfo = await this.dbRead.findOne(SysUserLog, {
|
where: {
|
gUID: guid
|
},
|
order: {
|
log_Id: "DESC"
|
}
|
});
|
if (logInfo) {
|
saaSAuthList = logInfo.saaSAuth;
|
await userRedis.set(accessTokenKey, logInfo.saaSAuth);
|
await userRedis.expire(accessTokenKey, 60 * 60 * 24 * 7);
|
}
|
}
|
|
if (saaSAuthList) {
|
saaSAuthList = JSON.parse(saaSAuthList);
|
}
|
|
return saaSAuthList;
|
}
|
|
//#endregion
|
|
//#region isSaaSAuth
|
/// <summary>
|
/// SaaS模块权限
|
/// </summary>
|
/// <returns></returns>
|
public async isSaaSAuth(moduleName: string): Promise<boolean> {
|
let _saaSAuthList = await this.saaSAuthList();
|
if (_saaSAuthList != null) {
|
var authInfo = _saaSAuthList.find(w => w.moduleName == moduleName);
|
if (authInfo != null && authInfo.isSupport == 1) {
|
return true;
|
}
|
}
|
return false;
|
}
|
//#endregion
|
|
//#region getAuthNum
|
/// <summary>
|
/// SaaS模块支持数量
|
/// </summary>
|
/// <returns></returns>
|
public async getAuthNum(moduleName: string): Promise<number> {
|
let _saaSAuthList = await this.saaSAuthList();
|
if (_saaSAuthList != null) {
|
var authInfo = _saaSAuthList.find(w => w.moduleName == moduleName);
|
if (authInfo != null && authInfo.isSupport == 1) {
|
return authInfo.moduleNumber;
|
}
|
}
|
return 0;
|
}
|
//#endregion
|
|
//#region getGUID
|
// 自定义函数, 获得GUID值
|
public getGUID(): string {
|
function GUID(this: any) {
|
this.date = new Date(); /* 判断是否初始化过,如果初始化过以下代码,则以下代码将不再执行,实际中只执行一次 */
|
if (typeof this.newGUID != "function") {
|
/* 生成GUID码 */
|
GUID.prototype.newGUID = function () {
|
this.date = new Date();
|
var guidStr = "";
|
var sexadecimalDate = this.hexadecimal(this.getGUIDDate(), 16);
|
var sexadecimalTime = this.hexadecimal(this.getGUIDTime(), 16);
|
for (var i = 0; i < 9; i++) {
|
guidStr += Math.floor(Math.random() * 16).toString(16);
|
}
|
guidStr += sexadecimalDate;
|
guidStr += sexadecimalTime;
|
while (guidStr.length < 32) {
|
guidStr += Math.floor(Math.random() * 16).toString(16);
|
}
|
return this.formatGUID(guidStr);
|
};
|
/* * 功能:获取当前日期的GUID格式,即8位数的日期:19700101 * 返回值:返回GUID日期格式的字条串 */
|
GUID.prototype.getGUIDDate = function () {
|
return this.date.getFullYear() + this.addZero(this.date.getMonth() + 1) + this.addZero(this.date.getDay());
|
};
|
/* * 功能:获取当前时间的GUID格式,即8位数的时间,包括毫秒,毫秒为2位数:12300933 * 返回值:返回GUID日期格式的字条串 */
|
GUID.prototype.getGUIDTime = function () {
|
return (
|
this.addZero(this.date.getHours()) +
|
this.addZero(this.date.getMinutes()) +
|
this.addZero(this.date.getSeconds()) +
|
this.addZero(parseInt((this.date.getMilliseconds() / 10).toString()))
|
);
|
};
|
/* * 功能: 为一位数的正整数前面添加0,如果是可以转成非NaN数字的字符串也可以实现 * 参数: 参数表示准备再前面添加0的数字或可以转换成数字的字符串 * 返回值: 如果符合条件,返回添加0后的字条串类型,否则返回自身的字符串 */
|
GUID.prototype.addZero = function (num) {
|
if (Number(num).toString() != "NaN" && num >= 0 && num < 10) {
|
return "0" + Math.floor(num);
|
} else {
|
return num.toString();
|
}
|
};
|
/* * 功能:将y进制的数值,转换为x进制的数值 * 参数:第1个参数表示欲转换的数值;第2个参数表示欲转换的进制;第3个参数可选,表示当前的进制数,如不写则为10 * 返回值:返回转换后的字符串 */
|
GUID.prototype.hexadecimal = function (num, x, y) {
|
if (y != undefined) {
|
return parseInt(num.toString(), y).toString(x);
|
} else {
|
return parseInt(num.toString()).toString(x);
|
}
|
};
|
/* * 功能:格式化32位的字符串为GUID模式的字符串 * 参数:第1个参数表示32位的字符串 * 返回值:标准GUID格式的字符串 */
|
GUID.prototype.formatGUID = function (guidStr) {
|
var str1 = guidStr.slice(0, 8) + "-",
|
str2 = guidStr.slice(8, 12) + "-",
|
str3 = guidStr.slice(12, 16) + "-",
|
str4 = guidStr.slice(16, 20) + "-",
|
str5 = guidStr.slice(20);
|
return str1 + str2 + str3 + str4 + str5;
|
};
|
}
|
}
|
|
var guid = new GUID();
|
return guid.newGUID();
|
}
|
|
//#endregion
|
|
//#region getWhere
|
public async getWhere() {
|
let { ctx } = this;
|
let body = ctx.request.body;
|
let clientWhere = this.body.where;
|
// 加载权限
|
let where = (await ctx.service.auth.getAutWhere()) || {};
|
|
// 固定查询条件
|
if (body.fixedWhere) {
|
let _where = this.parseWhere(body.fixedWhere);
|
where = Object.assign(where, _where);
|
}
|
|
let _where = this.parseWhere(clientWhere);
|
where = Object.assign(where, _where);
|
|
if (!Object.keys(where).length && !body.noUserProduct_Id) {
|
where[body.idField] = Raw(() => "1<>1");
|
}
|
|
return where;
|
}
|
//#endregion
|
|
//#region 生成typeorm查询条件 parseWhere
|
/**
|
* 生成typeorm查询条件
|
* @param rawWhere 原始查询条件
|
*/
|
public parseWhere(rawWhere: Object) {
|
let { ctx } = this;
|
let body = ctx.request.body;
|
let where = {};
|
try {
|
if (typeof rawWhere === "string") {
|
rawWhere = JSON.parse(rawWhere);
|
}
|
if (Array.isArray(rawWhere)) {
|
rawWhere.forEach(item => {
|
if (item.prop === "__quickSearch__") {
|
let quickWhere = "";
|
// 快速查询处理
|
item.where.forEach(row => {
|
if (item.operator === "like") {
|
let value = row.value;
|
if (Array.isArray(value)) value = value.join(",");
|
value = value.replace(/'|"|,|select|update|delete|drop/gim, "");
|
if (quickWhere) quickWhere += " OR ";
|
quickWhere += row.prop + " like '%" + value + "%'";
|
} else {
|
if (Array.isArray(row.value)) {
|
let value = row.value.map(v => v.replace(/'|"|,|select|update|delete|drop/gim, ""));
|
if (quickWhere) quickWhere += " OR ";
|
quickWhere += row.prop + " in('" + value.join("','") + "')";
|
} else {
|
let value = row.value.replace(/'|"|,|select|update|delete|drop/gim, "");
|
if (quickWhere) quickWhere += " OR ";
|
quickWhere += row.prop + "='" + value + "'";
|
}
|
}
|
});
|
if (quickWhere) {
|
where[body.idField] = Raw(() => `(${quickWhere})`);
|
}
|
} else {
|
// 通用查询
|
if (Array.isArray(item.value)) {
|
if (["date", "datetime"].indexOf(item.dataType) >= 0) {
|
let _endDate = moment(item.value[1]).format("YYYY-MM-DD") + " 23:59:59";
|
// let endDate = moment(_endDate).toDate();
|
where[item.prop] = Between(item.value[0], _endDate);
|
} else {
|
where[item.prop] = In(item.value);
|
}
|
} else {
|
if (item.operator == ">=") {
|
where[item.prop] = MoreThanOrEqual(item.value);
|
} else if (item.operator == "<=") {
|
where[item.prop] = LessThanOrEqual(item.value);
|
} else if (item.operator == "<>") {
|
where[item.prop] = Not(item.value);
|
} else if (item.operator == "null") {
|
where[item.prop] = IsNull();
|
} else if (item.operator == "raw") {
|
where[item.prop] = Raw(() => `(${item.value})`);
|
} else if (item.operator == "like") {
|
where[item.prop] = Like(`%${item.value}%`);
|
} else {
|
if (item.fromValue !== null && item.fromValue !== undefined && (item.toValue === null || item.toValue === undefined)) {
|
where[item.prop] = MoreThanOrEqual(item.fromValue);
|
} else if (item.fromValue !== null && item.fromValue !== undefined && item.toValue !== null && item.toValue !== undefined) {
|
where[item.prop] = Between(item.fromValue, item.toValue);
|
} else {
|
where[item.prop] = item.value;
|
}
|
}
|
}
|
}
|
});
|
} else {
|
Object.keys(rawWhere).forEach(key => {
|
let item = rawWhere[key];
|
if (Array.isArray(item)) {
|
where[key] = In(item);
|
} else if (isObject(item)) {
|
if (item.operator == ">") {
|
where[key] = MoreThan(item.value);
|
} else if (item.operator == ">=") {
|
where[key] = MoreThanOrEqual(item.value);
|
} else if (item.operator == "<") {
|
where[key] = LessThan(item.value);
|
} else if (item.operator == "<=") {
|
where[key] = LessThanOrEqual(item.value);
|
} else if (item.operator == "!=") {
|
where[key] = Not(item.value);
|
} else if (item.operator == "=") {
|
where[key] = item.value;
|
} else if (item.operator == "raw") {
|
where[key] = Raw(() => item.value);
|
} else if (item.operator == "like") {
|
where[key] = Like(`%` + item.value + `%`);
|
} else if (item.operator == "in") {
|
where[key] = In(item.value);
|
} else if (item.operator == "not") {
|
if (item.value === null) {
|
where[key] = Not(IsNull());
|
} else {
|
where[key] = Not(item.value);
|
}
|
} else if (item.operator == "multi") {
|
let quickWhere = "";
|
// 组合模块式
|
item.where.forEach(row => {
|
if (row.operator === "like") {
|
let value = row.value;
|
if (Array.isArray(value)) value = value.join(",");
|
value = value.replace(/'|"|,|select|update|delete|drop/gim, "");
|
if (quickWhere) quickWhere += " OR ";
|
quickWhere += row.prop + " like '%" + value + "%'";
|
} else if (row.operator === "in") {
|
let value = row.value.map(v => v.replace(/'|"|,|select|update|delete|drop/gim, ""));
|
if (quickWhere) quickWhere += " OR ";
|
quickWhere += row.prop + " in('" + value.join("','") + "')";
|
} else {
|
let value = row.value.replace(/'|"|,|select|update|delete|drop/gim, "");
|
if (quickWhere) quickWhere += " OR ";
|
quickWhere += row.prop + "='" + value + "'";
|
}
|
});
|
if (quickWhere) {
|
where[key] = Raw(() => `(${quickWhere})`);
|
}
|
} else {
|
if (item === null) {
|
where[key] = IsNull();
|
} else {
|
where[key] = item;
|
}
|
}
|
} else {
|
where[key] = rawWhere[key];
|
}
|
});
|
}
|
} catch (error) {
|
console.log("解析查询条件错误:", rawWhere);
|
}
|
return where;
|
}
|
|
//#endregion
|
}
|