Commit fd9cf3c5 by 王昆

gsb

parent fc6d0fc7
const system = require("../../system")
const settings = require("../../../config/settings");
const uuidv4 = require('uuid/v4');
const axios = require("axios");
class innerApi {
constructor() {
this.redisClient = system.getObject("util.redisClient");
this.redisLock = system.getObject("util.redisLock");
this.userSve = system.getObject("service.userSve");
this.usereaccountSve = system.getObject("service.usereaccountSve");
this.idcardClient = system.getObject("util.idcardClient");
this.esettleSve = system.getObject("service.esettleSve");
this.dkcontractSve = system.getObject("service.dkcontractSve");
this.etemplatebusiSve = system.getObject("service.etemplatebusiSve");
this.bankthreelogSve = system.getObject("service.bankthreelogSve");
}
async valid(obj, req) {
console.log("inner api valid", obj);
if (obj.error == 1) {
throw new Error("valid-error");
}
// if (!obj.mchtId) {
// throw new Error("mchtId-empty");
// }
}
/**
* 银行卡四要素验证
* @param obj
* @param req
* @returns {Promise<{msg: string, data: *, status: number}>}
*/
async bankFour(obj, req) {
let idName, idNo, bankNo, mobile, val, key;
try {
await this.valid(obj, req);
idName = this.trim(obj.idName);
idNo = this.trim(obj.idNo);
bankNo = this.trim(obj.bankNo);
mobile = this.trim(obj.mobile);
val = uuidv4();
key = `bpo_app_1_${idNo}`;
// 加锁
await this.redisLock.lockNoWait(key, val, 20);
// 封装参数
let appId = "bpo_app_1_";
let unionId = key;
let userInfo = {
unionId: unionId,
appId: appId,
appKey: appId,
userName: idName,
userIdNo: idNo,
userBankNo: bankNo,
userMobile: mobile,
utype: 0,
};
// 1. 四要素认证
let authRes = await this.bankthreelogSve.bankFour(userInfo);
if (authRes.status != 0 || !authRes.data || !authRes.data.pass) {
return system.getErrResult2("身份认证失败,请检查姓名、身份证、银行卡号、银行预留手机号是否正确");
}
// 2. user和user_eaccount逻辑
let userObj = await this.userSve.userAndEaccount4InnerApi(userInfo);
// 3. 创建e签宝账号
let esignRes = await this.usereaccountSve.createEsignAccount({
accountId: userObj.account.id,
prev: `bpo_app_1_${userObj.account.user_id}_`,
isGrantAuto: true
});
if (!esignRes) {
return system.getErrResult2("创建签约账户失败, 请重试");
}
return system.getResult2({
accountId: userObj.account.id,
idName: idName,
idNo: idNo,
bankNo: bankNo,
mobile: mobile,
});
} catch (e) {
console.log("innerApi-bankFour error", e.stack);
return this.errorTip(e.name);
} finally {
if (key && val) {
// 解锁
await this.redisLock.unLock(key, val);
}
}
}
/**
* 人脸识别
* @param obj
* @param req
* @returns {Promise<void>}
*/
async appFaceAuth(obj, req) {
try {
let accountId = this.trim(obj.accountId);
let account = await this.usereaccountSve.findById(accountId);
if (!account) {
return system.getErrResult2("账户不存在");
}
if (!obj.notifyUrl) {
return system.getErrResult2("请传入notifyUrl[识别结果通知地址]");
}
let authRes = await axios({
method: 'post',
url: settings.signApi().personaAuthlFace,
data: {
accountId: account.eaccountid,
callbackUrl: obj.callbackUrl || "https://bpohhr.gongsibao.com/blank",
notifyUrl: obj.notifyUrl || "https://bpohhr.gongsibao.com/api/econtractApi/transferNotify",
// sysNotifyUrl: "https://bpohhr.gongsibao.com/api/econtractApi/transferNotify",
sysNotifyUrl: "https://bpohhr.gongsibao.com/api/innerApi/faceAuthNotify",
},
});
authRes = authRes.data;
if (authRes.status == 0) {
return system.getResult2(authRes.data);
}
authRes.status = -1;
return authRes;
} catch (e) {
console.log(e);
return system.getErrResult2("操作异常" + e.stack);
}
}
async faceAuthNotify(obj, req) {
console.log("faceNotify---begin-------------", obj);
if (!obj || !obj.flowId) {
return;
}
let authRes = await axios({
method: 'post',
url: settings.signApi().personalAuthCallBack,
data: obj,
});
if (authRes && authRes.data && authRes.data.status === 0) {
let acc = authRes.data.data;
if (!acc) {
return system.getErrResult2("数据错误");
}
let eaccount = await this.usereaccountSve.findOne({eaccountid: acc.account_id});
eaccount.face_auth_img = acc.face_img;
await eaccount.save();
}
console.log("faceNotify---result-------------", authRes);
return 1;
}
/**
* 静默签
* @param obj
* @param req
* @returns {Promise<{msg: string, data: *, status: number}>}
*/
async appAutoSign(obj, req) {
let mchtId, accountId, val, key;
try {
await this.valid(obj, req);
accountId = this.trim(obj.accountId);
mchtId = this.trim(obj.mchtId);
key = `${mchtId}_${accountId}`;
val = uuidv4();
if (!accountId) {
return system.getErrResult2("缺少accountId");
}
if (!mchtId) {
return system.getErrResult2("缺少商户id");
}
// 1.获取签约模板id,张娇保证一个商户只有一个模板id
let etemplateBusi = await this.etemplatebusiSve.findOne({busi_id: mchtId});
if (!etemplateBusi || !etemplateBusi.template_id) {
return system.getErrResult2("配置信息错误,请联系薪必果人员进行配置");
}
// 2. 签约
await this.redisLock.lock(key, val, 20);
// 3. 签约
return await this.dkcontractSve.appAutoSign({
ecid: etemplateBusi.template_id,
usereaccountId: accountId,
forceFace: false
});
} catch (e) {
console.log("innerApi-autoSign error", e.stack);
return this.errorTip(e.name);
} finally {
if (key && val) {
// 解锁
await this.redisLock.unLock(key, val);
}
}
}
async signInfo(obj, req) {
let contract = await this.dkcontractSve.findById(obj.contractId) || {};
return system.getResult2({
contractId: this.trim(contract.id),
name: this.trim(contract.name),
fileurl: this.trim(contract.fileurl),
eflowstatus: this.trim(contract.eflowstatus),
});
}
errorTip(name) {
if (name == 'valid-error') {
return system.getErrResult2("权限认证失败");
} else if (name == "mchtId-empty") {
return system.getErrResult2("商户id为空");
}
return system.getErrResult2(name);
}
trim(o) {
if (!o) {
return "";
}
return o.toString().trim();
}
}
module.exports = innerApi;
\ No newline at end of file
......@@ -66,6 +66,7 @@ module.exports = (db, DataTypes) => {
type:DataTypes.BOOLEAN,
defaultValue: false
},
face_auth_img: DataTypes.STRING, // 人脸识别图
}, {
paranoid: true, //假的删除
underscored: true,
......
......@@ -758,6 +758,100 @@ class DKcontractService extends ServiceBase {
});
}
/**
* 内部app签约
* @param params
* @returns {Promise<number>}
*/
async appAutoSign(params) {
let ecid = params.ecid;
let usereaccountId = params.usereaccountId;
let eaccount = await this.usereaccountDao.findById(usereaccountId);
if (!eaccount || !eaccount.eaccountid) {
return system.getErrResult2("账户不存在");
}
if (params.forceFace && !eaccount.face_auth_img) {
return system.getErrResult2("请先进行人脸识别");
}
let todays = moment().format("YYYY-MM-DD") + " 00:00:00";
let contractId = await this.dao.findSignedContractId({idno: eaccount.personsSign, ecid: ecid, today : todays}) || 0;
if (contractId) {
return system.getResult2({contractId: contractId}, {}, "用户已签约");
}
// ecid dketemplate
let etemplate = await this.dktemplateSve.findById(ecid);
// dkecompany
let dkcompany = await this.dkcompanyDao.findById(etemplate.dkcompany_id);
// 设置静默签署授权 5.2.5
if (!eaccount.isGrantAuto) {
var grantAuto = await this.utilesignbaoSve.grantAuthorization({grantAccountId: eaccount.eaccountid}, "dkcontractSve");
if (grantAuto.code != 1) {
return system.getErrResult2("静默签署设置失败");
}
eaccount.isGrantAuto = true;
await eaccount.save();
}
let dkecontract = {
name: dkcompany.name,
dktemplate_id: ecid,
user_id: eaccount.user_id,
usereaccount_id: eaccount.id,
dkcompany_id: dkcompany.id,
edocid: "",
eflowid: "",
esignUrl: "",
eflowstatus: "1",
}
dkecontract = await this.create(dkecontract);
var dkaggreement = await this.dkaggreementDao.findById(etemplate.dkaggreement_id);
var contractParams = {
templateId: dkaggreement.templateid, //模板id,由创建模板接口调用返回的templateId 必填
name: dkcompany.name, //合同模板名称 必填
simpleFormFields: {
nameA: dkcompany.name, //甲方 必填
addressA: dkcompany.addr, // 甲方地址
phoneA: dkcompany.phone, // 甲方电话
nameB: eaccount.userName, //乙方姓名 必填
phoneB: eaccount.mobile, //乙方电话 必填
nameC: eaccount.userName, // 已方姓名
phoneC: eaccount.mobile, // 乙方电话
idcardC: eaccount.personsSign, // 乙方身份证
banknoC: eaccount.bankno, // 乙方银行卡号
signdate: moment().format("YYYY/MM/DD"), // 签约日期
}
};
var ebaoAccountId = eaccount.eaccountid; //签署人账户id-- 必填
var thirdOrderNo = "dk_" + dkecontract.id; //第三方流水号,通知回调使用---选填
var eBaoRedirectBossUrl = "";
var sealId = dkcompany.sealId;
let tt = await this.utilesignbaoSve.userAutoSignContractNoTemplate(contractParams, ebaoAccountId, thirdOrderNo, eBaoRedirectBossUrl, "econtractSve", sealId);
console.log("-============= result ===========================", tt);
if (tt && tt.data && tt.code == 1) {
dkecontract.eflowid = tt.data.flowId;
dkecontract.edocid = tt.data.docId;
dkecontract.eflowstatus = '2',
dkecontract.esignUrl = tt.data.signUrl;
let signTime = new Date();
dkecontract.completed_at = signTime;
dkecontract.begin_at = signTime;
let end_at = new Date();
end_at.setFullYear(end_at.getFullYear() + 1);
dkecontract.end_at = end_at;
await dkecontract.save();
}
this.redisClient.rpushBCD({id: dkecontract.id, sve: "dk"});
return system.getResult2({contractId: dkecontract.id}, {}, "success");
}
async findSingleSignedUser(params) {
let sql = [];
sql.push("SELECT t1.id,t1.begin_at as beginDate,t1.end_at as endDate,");
......
......@@ -529,6 +529,38 @@ class UserService extends ServiceBase {
async getMyIds(userId) {
return await this.dao.getMyIds(userId);
}
/**
* 不要修改此方法,如需使用请新加方法
* @param params
* @returns {Promise<{user: *, account: *}>}
*/
async userAndEaccount4InnerApi(params) {
// 处理p_user, 不存则添加
let user = await this.dao.findOne({unionId: params.unionId});
if (!user) {
user = await this.dao.create(params);
}
// 处理p_user_eaccount, 不存在则添加
let account = await this.usereaccountDao.findOne({user_id: user.id, personsSign: params.userIdNo});
if (account) {
account.userName = params.userName;
account.bankno = params.userBankNo;
account.mobile = params.userMobile;
let a = await account.save();
console.log(a);
} else {
account = {};
account.user_id = user.id;
account.userName = params.userName;
account.mobile = params.userMobile;
account.bankno = params.userBankNo;
account.personsSign = params.userIdNo;
account = await this.usereaccountDao.create(account);
}
return {user: user, account: account};
}
}
module.exports = UserService;
// var task=new UserService();
......
const system=require("../../system");
const ServiceBase=require("../sve.base");
const system = require("../../system");
const settings = require("../../../config/settings");
const ServiceBase = require("../sve.base");
const xlsx = require('node-xlsx');
const fs = require("fs");
const axios = require("axios");
class UsereaccountService extends ServiceBase{
constructor(){
super(ServiceBase.getDaoName(UsereaccountService));
this.restClient = system.getObject("util.restClient");
this.idcardClient = system.getObject("util.idcardClient");
class UsereaccountService extends ServiceBase {
constructor() {
super(ServiceBase.getDaoName(UsereaccountService));
this.restClient = system.getObject("util.restClient");
this.idcardClient = system.getObject("util.idcardClient");
this.utilesignbaoSve = system.getObject("service.utilesignbaoSve");
}
async findAll(obj){
async findAll(obj) {
obj = obj || {};
var result = await this.dao.model.findAll(
{where:obj}
{where: obj}
);
return result;
}
......@@ -25,12 +29,12 @@ class UsereaccountService extends ServiceBase{
//解析Excel中,批量导入签约人员信息
async parseItems(userId, ossurl) {
var result = {
code : 0,
msg:"",
list : [],
code: 0,
msg: "",
list: [],
};
var isValid = true;
var isValid = true;
var regexNumber = /^[0-9]*$/;
var dataList = [];
......@@ -44,13 +48,13 @@ class UsereaccountService extends ServiceBase{
// });
fs.unlinkSync(filePath);
if(!sheets || sheets.length == 0) {
if (!sheets || sheets.length == 0) {
result.msg = "签约人员excel为空";
return result;
}
var sheet = sheets[0];
if(!sheet || !sheet.data || sheet.data.length == 0) {
if (!sheet || !sheet.data || sheet.data.length == 0) {
result.msg = "签约人员无内容行";
return result;
}
......@@ -60,7 +64,7 @@ class UsereaccountService extends ServiceBase{
var erridcardLines = [];
for (var idx in rows) {
if(idx == 0) {
if (idx == 0) {
continue;
}
......@@ -68,10 +72,10 @@ class UsereaccountService extends ServiceBase{
var rowNum = Number(idx) + 1;
var cellLength = cells.length;
if(cellLength == 0) {
if (cellLength == 0) {
continue;
}
if(cellLength < 4) {
if (cellLength < 4) {
result.msg = "excel第" + rowNum + "行,请填写姓名、身份证、银行卡号";
return result;
}
......@@ -81,38 +85,38 @@ class UsereaccountService extends ServiceBase{
data.id_card = this.trim(cells[1]).toUpperCase();
data.phone = this.trim(cells[2]) || "";
data.bank_no = this.trim(cells[3]);
data.rowNum = rowNum;
//验证不为空
if(!data.name) {
if (!data.name) {
result.msg = "excel第" + rowNum + "行,请填写姓名";
return result;
}
if(!data.id_card) {
if (!data.id_card) {
result.msg = "excel第" + rowNum + "行,请填写身份证";
return result;
}
if(!data.bank_no) {
if (!data.bank_no) {
result.msg = "excel第" + rowNum + "行,请填写银行卡号";
return result;
}
//验证是否有效
// if(!await this.idcardClient.checkIDCard(data.id_card)) {
// erridcardLines.push(rowNum);
// data.errormsg = "身份证号码验证失败";
// }
if(data.phone) {
if(!regexNumber.test(data.phone) || data.phone.substring(0, 1) != 1 || data.phone.length != 11) {
if (data.phone) {
if (!regexNumber.test(data.phone) || data.phone.substring(0, 1) != 1 || data.phone.length != 11) {
result.msg = "excel第" + rowNum + "行,手机号格式错误";
return result;
}
}
if(!regexNumber.test(data.bank_no)) {
if (!regexNumber.test(data.bank_no)) {
result.msg = "excel第" + rowNum + "行,银行卡号格式错误,请填写纯数字";
return result;
}
......@@ -120,19 +124,19 @@ class UsereaccountService extends ServiceBase{
datalist.push(data);
}
if(datalist.length == 0) {
if (datalist.length == 0) {
result.msg = "请填写数据";
return result;
}
if(erridcardLines.length > 0) {
if (erridcardLines.length > 0) {
result.msg = "excel第【" + erridcardLines.join("、") + "】行,身份证号格式错误!";
return result;
}
result.code = 1;
result.list = datalist;
result.list = datalist;
return result;
} catch (error) {
......@@ -144,7 +148,7 @@ class UsereaccountService extends ServiceBase{
async getSignAccounts(etemplateIds, idNoList, idNameList) {
var sql = [];
sql.push("SELECT ");
sql.push("t2.userName, t2.personsSign");
sql.push("FROM c_econtract t1");
......@@ -168,7 +172,7 @@ class UsereaccountService extends ServiceBase{
let sql = "SELECT t1.`personsSign` FROM p_user_eaccount t1 INNER JOIN p_user t2 ON t1.`user_id` = t2.`id` WHERE t2.`userId3rd` = :userId3rd";
let list = await this.dao.customQuery(sql, {userId3rd: userId3rd,});
let rs = [];
for(let item of list) {
for (let item of list) {
rs.push(item.personsSign);
}
return rs;
......@@ -193,5 +197,50 @@ class UsereaccountService extends ServiceBase{
return list || [];
}
async createEsignAccount(params) {
let accountId = this.trim(params.accountId);
let prev = params.prev || "esign";
let account = await this.dao.findById(accountId);
if (!account) {
console.log("createEsignAccount---findById---error", params);
return 0;
}
if (!account.eaccountid) {
// 创建e签宝account 5.2.1
let accountParams = {
idName: account.userName,
idNo: account.personsSign,
mobile: account.mobile
}
let esignAccount = await axios({
method: 'post',
url: settings.signApi().createAccountNoFee,
data: accountParams,
});
esignAccount = esignAccount.data;
if (esignAccount && esignAccount.status == 0 && esignAccount.data) {
account.eaccountid = esignAccount.data.accountId;
account.isGrantAuto = true;
await account.save();
} else {
console.log("createEsignAccount---utilesignbaoSve.createAccountId---error", accountParams);
return 0;
}
}
// if (params.isGrantAuto && !account.isGrantAuto) {
// let grantAuto = await this.utilesignbaoSve.grantAuthorization({grantAccountId: account.eaccountid}, "usereaccountSve");
// if (grantAuto.code != 1) {
// console.log("createEsignAccount---utilesignbaoSve.grantAuthorization---error", account.eaccountid);
// return 0;
// }
// account.isGrantAuto = true;
// await account.save();
// }
return 1;
}
}
module.exports=UsereaccountService;
module.exports = UsereaccountService;
......@@ -1371,6 +1371,8 @@ class UtilESignBaoService {
url: reqUrl,
data: params,
headers: {
// 'X-Tsign-Open-App-Id': '7438811652',
// 'X-Tsign-Open-App-Secret': '8a81096c06e0753ddf59154fcc98ecef'
'X-Tsign-Open-App-Id': '5111588557',
'X-Tsign-Open-App-Secret': '1595787e8d5b7d19f7b6798f16f41fc2'
},
......
......@@ -55,6 +55,27 @@ class RedisLock {
})();
}
async lockNoWait(key, val, expire) {
const start = Date.now();
const self = this;
return (async function intranetLock() {
try {
const result = await self.client.set(key, val, self.expiryMode, expire || self.lockLeaseTime, self.setMode);
// 上锁成功
if (result === 'OK') {
console.log(`${key} ${val} 上锁成功`);
return true;
}
console.log(`${key} ${val} 上锁失败`);
return false;
} catch (err) {
throw new Error(err);
}
})();
}
/**
* 释放锁
* @param {*} key
......
......@@ -277,6 +277,9 @@ module.exports = function (app) {
});
app.get('/blank', function (req, res) {
res.render("blank", {});
});
app.get('/bpoproxy', function (req, res) {
res.render("bpoproxy", {});
});
......
......@@ -35,7 +35,7 @@ var settings = {
let domain = '';
if (this.env == "dev") {
domain = "http://39.107.234.14:3603";
// domain = "http://127.0.0.1:3603";
} else {
domain = "https://qianbiguo-api.gongsibao.com";
}
......@@ -47,11 +47,18 @@ var settings = {
//发起签署
"autoSign" : `${domain}/api/sign/signApi/autoSign`,
//创建企业模板印章
// 创建企业模板印章
"organize" : `${domain}/sign/seal/create/organize`,
//创建公司图片印章
// 创建公司图片印章
"organizeimage" : `${domain}/sign/seal/create/organize/image`,
// 人脸识别
"createAccountNoFee" : `${domain}/api/inner/innerauthApi/createAccountNoFee`,
// 人脸识别
"personaAuthlFace" : `${domain}/api/inner/innerauthApi/personaAuthlFace`,
// 人脸识别
"personalAuthCallBack" : `${domain}/api/inner/innerauthApi/personalAuthCallBack`,
};
},
......
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<title id="needh5">请稍后...</title>
<link rel="stylesheet" href="/css/ele/chalk.css">
<link rel="stylesheet" href="/css/main.css">
<link rel="stylesheet" href="/css/fontawesome/css/font-awesome.min.css">
<link rel="stylesheet" href="/css/autocomplete.css">
<script src="/js/vue/vue.min.js"></script>
<script src="/js/ele/index.js"></script>
<style>
div.el-message-box{
width:80%
}
</style>
</head>
<body style="overflow: auto;">
<div id="app" style="visibility:hidden;position: absolute;">
</div>
<script src="/js/vue/jquery.min.js"></script>
<script src="/js/vue/axios.min.js"></script>
<script src="/js/blank.js"></script>
</body>
</html>
var app = new Vue({
el: "#app",
data: function () {
return {
a: "a"
}
},
created: function () {
},
mounted: function () {
},
methods: {
postReq(path, data) {
return axios.post(path, data).then(function (r) {
return r.data ? r.data : null;
})
},
btnclick:function(pfm,code){
},
},
});
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment