Commit 9cb6ccca by 蒋勇

d

parent 567e162e
......@@ -9,438 +9,6 @@ class AccessAuthAPI extends APIBase {
this.authUtils = system.getObject("util.businessManager.authUtils");
this.userSve = system.getObject("service.auth.userSve");
}
/*查询注册用户的信息sys*/
async queryRegUser(pobj, query, req) {
var appid = req.app.id;
var userList = await this.userSve.queryUsersByAppId(appid);
return system.getResult(userList);
}
/**
* 发送短信
* @param {*} pobj {mobile为要发送的手机号,tmplCode为发送短信编码,需在阿里开通,signName为短信头描述信息}
* @param {*} query
* @param {*} req
*/
async fetchVCode(pobj, query, req) {
var appkey = req.app.appkey;
var mobile = pobj.mobile;
var tmplCode = pobj.tmplCode;
var signName = pobj.signName;
//var msg=pobj.msg;
if (!mobile) {
return system.getResult(null, "电话号码不能为空.");
}
// if(!msg){
// return system.getResult(null,"发送的内容不能为空.");
// }
if (!tmplCode) {
return system.getResult(null, "模版编码不能为空.");
}
if (!signName) {
return system.getResult(null, "短信签名不能为空.");
}
if (tmplCode && tmplCode.indexOf("SMS_") < 0) {
return system.getResult(null, "模版编码有误");
}
var tmpReslut = await this.cacheManager["VCodeCache"].getCache(appkey + "_" + mobile);
if (tmpReslut) {
return system.getResult(system.redoFail, "操作过于频繁,请勿重复获取");
}
var vcodeResult = await this.cacheManager["VCodeCache"].cache(appkey + "_" + mobile, tmplCode, 120, signName);
return system.getResult(vcodeResult);
}
/**
* 发送短信
* @param {*} pobj {mobile为要发送的手机号,tmplCode为发送短信编码,需在阿里开通,signName为短信头描述信息}
* @param {*} query
* @param {*} req
*/
async fetchDefaultVCode(pobj, query, req) {
var appkey = req.app.appkey;
var mobile = pobj.mobile;
if (!mobile) {
return system.getResult(null, "电话号码不能为空.");
}
var tmpReslut = await this.cacheManager["VCodeCache"].getCache(appkey + "_" + mobile);
if (tmpReslut) {
return system.getResult(system.redoFail, "操作过于频繁,请勿重复获取");
}
var vcodeResult = this.cacheManager["VCodeCache"].cache(appkey + "_" + mobile, null, 120);
return system.getResult(vcodeResult);
}
async authAccessKey(pobj, query, req) {
var acckapp = await this.cacheManager["ApiAccessKeyCache"].cache(pobj.checkAccessKey);
if (!acckapp) {
return system.getResultFail(system.tokenFail, "访问token失效,请重新获取");
}
return system.getResultSuccess({ isaccess: true, app: acckapp });
}
async getAccessKey(pobj, query, req) {
var appkey = query.appkey;
var secret = query.secret;
if (!appkey) {
appkey = pobj.appkey;
secret = pobj.secret;
}
var appData = await this.authUtils.getTokenInfo(appkey, secret);
if (appData.status != 0) {
return appData;
}
//构造oath
var oathstr = settings.homePage() + "?appKey=" + appData.data.appkey + "#/login";
var oathreg = settings.homePage() + "?appKey=" + appData.data.appkey + "#/register";
appData.data.oauthlogin = oathstr;
appData.data.oauthreg = oathreg;
var rtnData = {};
rtnData.accessKey = appData.data.accessKey;
delete appData.data["accessKey"];
rtnData.app = appData.data;
return system.getResultSuccess(rtnData);
}
async apiAccessCount(p, q, r) {
var tradeObj = {
srcappkey: p.srcappkey,
tradeType: "consume",
op: p.op,
params: p.params,
clientIp: p.clientIp,
agent: p.agent,
destappkey: p.destappkey
}
var t = await this.apitradeSvr.create(tradeObj);
return system.getResultSuccess(t);
}
async register(pobj, qobj, req) {
if (!pobj.userName) {
return system.getResult(null, "用户名不能为空");
}
if (!pobj.mobile) {
return system.getResult(null, "手机号不能为空");
}
if (!pobj.password) {
return system.getResult(null, "密码不能为空");
}
var param = {
app_id: req.app.id,
userName: pobj.userName,
mobile: pobj.mobile,
password: pobj.password
}
var ruser = await this.userSve.register(param);
if (!ruser) {
return system.getResultFail(system.existUserRegFail, "已经存在此用户,注册失败");
}//status=2000
var opencode = super.getUUID();
var authUrl = req.app.authUrl + "?opencode=" + opencode;
await this.cacheManager["OpenCodeCache"].cache(opencode, ruser, 30);
return system.getResultSuccess({ auth_url: authUrl, opencode: opencode, open_user_id: ruser.id, account_id: ruser.account_id });
}
async modifyPassword(pobj, qobj, req) {
if (!pobj.account_id) {
return system.getResult(null, "用户名不能为空");
}
if (!pobj.password) {
return system.getResult(null, "密码不能为空");
}
var param = {
account_id: pobj.account_id,
password: pobj.password,
}
await this.userSve.modifyPassword(param);
return system.getResultSuccess();
}
async login(pobj, qobj, req) {
if (!pobj.userName) {
return system.getResult(null, "用户名不能为空");
}
if (!pobj.password) {
return system.getResult(null, "密码不能为空");
}
var param = {
app_id: req.app.id,
userName: pobj.userName,
password: pobj.password
}
var ruser = await this.userSve.getUserByUserNamePwdForApi(param);
if (!ruser) {
return system.getResultFail(system.userLoginFail, "用户名或密码错误");
}//status=2010
var opencode = super.getUUID();
var authUrl = req.app.authUrl + "?opencode=" + opencode;
await this.cacheManager["OpenCodeCache"].cache(opencode, ruser, 120);
return system.getResultSuccess({ auth_url: authUrl, opencode: opencode });
}
async loginByMobileWithoutReg(pobj, qobj, req) {
if (!pobj.mobile) {
return system.getResult(null, "电话不能为空");
}
var param = {
app_id: req.app.id,
mobile: pobj.mobile,
}
var ruser = await this.userSve.getUserByUserMobile(param);
if (!ruser) {
return system.getResult(null, "查无此用户");
}
var opencode = super.getUUID();
var authUrl = req.app.authUrl + "?opencode=" + opencode;
await this.cacheManager["OpenCodeCache"].cache(opencode, ruser, 120);
return system.getResultSuccess({ auth_url: authUrl, opencode: opencode });
}
//根据openid查询是否与用户绑定
async checkWxBind(p, q, req) {
var openid = p.openid;
if (!openid) {
return system.getResult(null, "openid不能为空");
}
var param = {
app_id: req.app.id,
openid: openid,
}
var ruser = await this.userSve.checkWxBind(param);
if (!ruser) {
return system.getResult(null, "用户未绑定微信");
}
return system.getResult(ruser);
}
//根据openid登录
async loginByOpenId(p, q, req) {
var openid = p.openid;
if (!openid) {
return system.getResult(null, "openid不能为空");
}
var param = {
app_id: req.app.id,
openid: openid,
}
var ruser = await this.userSve.checkWxBind(param);
if (!ruser) {
return system.getResult(null, "用户未绑定微信");
}
var opencode = super.getUUID();
var authUrl = req.app.authUrl + "?opencode=" + opencode;
await this.cacheManager["OpenCodeCache"].cache(opencode, ruser, 120);
return system.getResultSuccess({ auth_url: authUrl, opencode: opencode });
}
//wxbind
async wxBind(pobj, qobj, req) {
var appkey = req.app.appkey;
if (!pobj.mobile) {
return system.getResult(null, "电话号码不能未空.");
}
if (!pobj.vcode) {
return system.getResult(null, "验证码不能未空.");
}
if (!pobj.openid) {
return system.getResult(null, "openid不能未空.");
}
var cacheCode = await this.cacheManager["VCodeCache"].cache(appkey + "_" + pobj.mobile, null);
if (!cacheCode || pobj.vcode != cacheCode.vcode) {
return system.getResult(system.verifyVCodeFail, "验证码校验不成功,请重新获取验证码验证.");
}
var param = {
app_id: req.app.id,
mobile: pobj.mobile,
openid: pobj.openid
}
var ruser = await this.userSve.wxBind(param);
if (!ruser) {
param = {
app_id: req.app.id,
userName: pobj.mobile,
nickName: pobj.mobile,
mobile: pobj.mobile,
password: pobj.mobile,
wxopenid: pobj.openid
}
ruser = await this.userSve.register(param);
}
var opencode = super.getUUID();
var authUrl = req.app.authUrl + "?opencode=" + opencode;
await this.cacheManager["OpenCodeCache"].cache(opencode, ruser, 120);
return system.getResultSuccess({ auth_url: authUrl, opencode: opencode });
}
//wxbind
async wxBindWithoutVCode(pobj, qobj, req) {
var appkey = req.app.appkey;
if (!pobj.mobile) {
return system.getResult(null, "电话号码不能未空.");
}
if (!pobj.openid) {
return system.getResult(null, "openid不能未空.");
}
var param = {
app_id: req.app.id,
mobile: pobj.mobile,
openid: pobj.openid
}
var ruser = await this.userSve.wxBind(param);
if (!ruser) {
param = {
app_id: req.app.id,
userName: pobj.mobile,
nickName: pobj.mobile,
mobile: pobj.mobile,
password: pobj.mobile,
wxopenid: pobj.openid
}
ruser = await this.userSve.register(param);
}
var opencode = super.getUUID();
var authUrl = req.app.authUrl + "?opencode=" + opencode;
await this.cacheManager["OpenCodeCache"].cache(opencode, ruser, 120);
return system.getResultSuccess({ auth_url: authUrl, opencode: opencode });
}
async loginByMobileWithReg(pobj, qobj, req) {
if (!pobj.mobile) {
return system.getResult(null, "电话不能为空");
}
var param = {
app_id: req.app.id,
mobile: pobj.mobile,
}
var ruser = await this.userSve.getUserByUserMobile(param);
if (!ruser) {
param = {
app_id: req.app.id,
userName: pobj.mobile,
nickName: pobj.mobile,
mobile: pobj.mobile,
password: pobj.mobile
}
ruser = await this.userSve.register(param);
}
var opencode = super.getUUID();
var authUrl = req.app.authUrl + "?opencode=" + opencode;
await this.cacheManager["OpenCodeCache"].cache(opencode, ruser, 120);
return system.getResultSuccess({ auth_url: authUrl, opencode: opencode });
}
async loginByMd5Password(pobj, qobj, req) {
if (!pobj.userName) {
return system.getResult(null, "用户名不能为空");
}
if (!pobj.password) {
return system.getResult(null, "密码不能为空");
}
var param = {
app_id: req.app.id,
userName: pobj.userName,
password: pobj.password,
isNavto: true
}
var ruser = await this.userSve.getUserByUserNamePwd(param);
var opencode = super.getUUID();
var authUrl = req.app.authUrl + "?opencode=" + opencode;
await this.cacheManager["OpenCodeCache"].cache(opencode, ruser, 30);
return system.getResultSuccess({ auth_url: authUrl, opencode: opencode });
}
/**
* 按照手机号和验证码修改密码
*/
async modiPasswordByMobile(pobj, qobj, req) {
var appid = req.app.id;
var appkey = req.app.appkey;
if (!pobj.mobile) {
return system.getResult(null, "电话号码不能未空.");
}
if (!pobj.vcode) {
return system.getResult(null, "验证码不能未空.");
}
if (!pobj.newPwd) {
return system.getResult(null, "新密码不能未空.");
}
var cacheCode = await this.cacheManager["VCodeCache"].cache(appkey + "_" + pobj.mobile, null);
if (!cacheCode || pobj.vcode != cacheCode.vcode) {
return system.getResultFail(-1, "验证码校验不成功,请重新获取验证码验证.", system.verifyVCodeFail);
}
//按照appid和电话查询出要修改的用户
var ruser = await this.userSve.modiPasswordByMobile(appid, pobj.mobile, pobj.newPwd);
return system.getResult(ruser);
}
/**
* 按照账号和appid修改密码
*/
async modiPasswordByUserName(pobj, qobj, req) {
var appid = req.app.id;
if (!pobj.userName) {
return system.getResult(null, "账号不能未空.");
}
if (!pobj.newPwd) {
return system.getResult(null, "新密码不能未空.");
}
// if (!pobj.oldPwd) {
// return system.getResult(null, "旧密码不能未空.");
// }
var ruser = await this.userSve.modiPasswordByUserName(appid, pobj.userName, pobj.newPwd, pobj.oldPwd);
return system.getResult(ruser);
}
/**
* 如果验证成功而账户不存在就创建一个账号
* @param {*} pobj
* @param {*} qobj
* @param {*} req
*/
async loginByVCode(pobj, qobj, req) {
var appkey = req.app.appkey;
if (!pobj.mobile) {
return system.getResult(null, "电话号码不能未空.");
}
if (!pobj.vcode) {
return system.getResult(null, "验证码不能未空.");
}
var cacheCode = await this.cacheManager["VCodeCache"].cache(appkey + "_" + pobj.mobile, null);
if (!cacheCode || pobj.vcode != cacheCode.vcode) {
return system.getResult(system.verifyVCodeFail, "验证码校验不成功,请重新获取验证码验证.");
}
var param = {
app_id: req.app.id,
mobile: pobj.mobile,
}
var ruser = await this.userSve.getUserByUserMobile(param);
if (!ruser) {
param = {
app_id: req.app.id,
userName: pobj.mobile,
nickName: pobj.mobile,
mobile: pobj.mobile,
password: pobj.password || pobj.mobile
}
ruser = await this.userSve.register(param);
}
var opencode = super.getUUID();
var authUrl = req.app.authUrl + "?opencode=" + opencode;
await this.cacheManager["OpenCodeCache"].cache(opencode, ruser, 120);
return system.getResultSuccess({ auth_url: authUrl, opencode: opencode });
}
/**
* 非平台应用回调处理函数中需要把
* req.code提取出来,并调用下方函数,返回对应的openuser,给
* 非平台应用
* @param {*} pobj
* @param {*} query
* @param {*} req
*/
async authByCode(pobj, query, req) {
if (!pobj.opencode) {
return system.getResult(null, "opencode参数不能为空");
}
var cacheuser = await this.userSve.authByCode(pobj.opencode);
if (!cacheuser) {
return system.getResult(system.verifyOpencodeFail, "opencode存储的值已经失效,请重新获取用户的opencode.");
}
return system.getResultSuccess(cacheuser);
}
classDesc() {
return {
groupName: "auth",
......@@ -458,7 +26,6 @@ class AccessAuthAPI extends APIBase {
}
methodDescs() {
return [
{
methodDesc: "生成访问token,访问地址:http://......../api/auth/accessAuth/getAccessKey,访问token需要放置到后续API方法调用的请求头中",
methodName: "getAccessKey",
......@@ -479,343 +46,10 @@ class AccessAuthAPI extends APIBase {
rtnTypeDesc: "返回JSON对象字符串",
rtnType: "json object {accessKey: xxxxxx, app: {xxx:xxx}},注意app,是当前app信息,详细见后面示例"
},
{
methodDesc: "注册方法,访问地址:http://......../api/auth/accessAuth/register",
methodName: "register",
paramdescs: [
{
paramDesc: "用户名",
paramName: "userName",
paramType: "string",
defaultValue: "",
},
{
paramDesc: "密码",
paramName: "password",
paramType: "string",
defaultValue: "",
},
{
paramDesc: "电话",
paramName: "mobile",
paramType: "string",
defaultValue: "",
}
],
rtnTypeDesc: "返回JSON对象字符串",
rtnType: "json object{ auth_url: xxxxx/auth?opencode=xxxxx }),详细见后面示例"
},
{
methodDesc: "登录方法,访问地址:http://......../api/auth/accessAuth/login",
methodName: "login",
paramdescs: [
{
paramDesc: "用户名",
paramName: "userName",
paramType: "string",
defaultValue: "",
},
{
paramDesc: "密码",
paramName: "password",
paramType: "string",
defaultValue: "",
}
],
rtnTypeDesc: "返回JSON对象字符串",
rtnType: "json object{ auth_url: xxxxx/auth?opencode=xxxxx }),详细见后面示例"
},
{
methodDesc: "获取手机验证,访问地址:http://......../api/auth/accessAuth/fetchVCode,访问token需要放置到后续API方法调用的请求头中",
methodName: "fetchVCode",
paramdescs: [
{
paramDesc: "手机号码",
paramName: "mobile",
paramType: "string",
defaultValue: "",
},
{
paramDesc: "模版CODE",
paramName: "tmplCode",
paramType: "string",
defaultValue: "",
},
{
paramDesc: "签名",
paramName: "signName",
paramType: "string",
defaultValue: "",
},
],
rtnTypeDesc: "返回JSON对象字符串,会在平台缓存60秒",
rtnType: "json object{status:0,data:{ vcode: xxxxxx}},详细见后面示例"
},
{
methodDesc: "验证码登录,访问地址:http://......../api/auth/accessAuth/loginByVCode,访问token需要放置到后续API方法调用的请求头中",
methodName: "loginByVCode",
paramdescs: [
{
paramDesc: "手机号码",
paramName: "mobile",
paramType: "string",
defaultValue: "",
},
{
paramDesc: "获取到的验证码",
paramName: "vcode",
paramType: "string",
defaultValue: "",
},
],
rtnTypeDesc: "返回JSON对象字符串",
rtnType: "json object{auth_url: xxxxx/auth?opencode=xxxxx }),详细见后面示例"
},
{
methodDesc: "验证码登录,访问地址:http://......../api/auth/accessAuth/loginByMobileWithReg,访问token需要放置到后续API方法调用的请求头中",
methodName: "loginByVCode",
paramdescs: [
{
paramDesc: "手机号码",
paramName: "mobile",
paramType: "string",
defaultValue: "",
},
],
rtnTypeDesc: "返回JSON对象字符串",
rtnType: "json object{auth_url: xxxxx/auth?opencode=xxxxx }),详细见后面示例"
},
{
methodDesc: "验证码登录,访问地址:http://......../api/auth/accessAuth/loginByMobileWithoutReg,访问token需要放置到后续API方法调用的请求头中",
methodName: "loginByVCode",
paramdescs: [
{
paramDesc: "手机号码",
paramName: "mobile",
paramType: "string",
defaultValue: "",
},
],
rtnTypeDesc: "返回JSON对象字符串",
rtnType: "json object{auth_url: xxxxx/auth?opencode=xxxxx }),详细见后面示例"
},
{
methodDesc: "按照opencode获取用户信息,访问地址:http://......../api/auth/accessAuth/authByCode,访问token需要放置到后续API方法调用的请求头中",
methodName: "authByCode",
paramdescs: [
{
paramDesc: "开放code,用于换取用户信息",
paramName: "opencode",
paramType: "string",
defaultValue: "",
}
],
rtnTypeDesc: "返回JSON对象字符串",
rtnType: "json object{status:0,data:{}}),详细见后面示例"
},
{
methodDesc: "按照手机号、验证码修改密码,访问地址:http://......../api/auth/accessAuth/modiPasswordByMobile,访问token需要放置到后续API方法调用的请求头中",
methodName: "modiPasswordByMobile",
paramdescs: [
{
paramDesc: "手机号",
paramName: "mobile",
paramType: "string",
defaultValue: "",
},
{
paramDesc: "验证码",
paramName: "vcode",
paramType: "string",
defaultValue: "",
},
{
paramDesc: "新密码",
paramName: "newPwd",
paramType: "string",
defaultValue: "",
}
],
rtnTypeDesc: "返回修改后的用户",
rtnType: "json object{status:-1,data:2030),验证码错误,成功:{status:0,...}"
},
{
methodDesc: "按照微信openid检查是否绑定,访问地址:http://......../api/auth/accessAuth/checkWxBind,访问token需要放置到后续API方法调用的请求头中",
methodName: "checkWxBind",
paramdescs: [
{
paramDesc: "微信openid",
paramName: "openid",
paramType: "string",
defaultValue: "",
}
],
rtnTypeDesc: "返回绑定后的用户",
rtnType: "成功:{status:0,data:{}),未绑定:{status:-1}"
},
{
methodDesc: "按照手机号、验证码,微信ID,绑定账号,访问地址:http://......../api/auth/accessAuth/wxBind,访问token需要放置到后续API方法调用的请求头中",
methodName: "wxBind",
paramdescs: [
{
paramDesc: "手机号",
paramName: "mobile",
paramType: "string",
defaultValue: "",
},
{
paramDesc: "验证码",
paramName: "vcode",
paramType: "string",
defaultValue: "",
},
{
paramDesc: "微信openid",
paramName: "openid",
paramType: "string",
defaultValue: "",
}
],
rtnTypeDesc: "返回绑定后的获取用户的code",
rtnType: "成功:{status:0,data:{auth_url: xxxxx/auth?opencode=xxxxx,opencode:yyyy})"
},
{
methodDesc: "按照微信ID进行登录,访问地址:http://......../api/auth/accessAuth/loginByOpenId,访问token需要放置到后续API方法调用的请求头中",
methodName: "loginByOpenId",
paramdescs: [
{
paramDesc: "微信openid",
paramName: "openid",
paramType: "string",
defaultValue: "",
}
],
rtnTypeDesc: "返回绑定后的获取用户的code",
rtnType: "成功:{status:0,data:{auth_url: xxxxx/auth?opencode=xxxxx,opencode:yyyy})"
},
{
methodDesc: "按照手机号、验证码修改密码,访问地址:http://......../api/auth/accessAuth/modiPasswordByUserName,访问token需要放置到后续API方法调用的请求头中",
methodName: "modiPasswordByUserName",
paramdescs: [
{
paramDesc: "账户名",
paramName: "userName",
paramType: "string",
defaultValue: "",
},
{
paramDesc: "新密码",
paramName: "newPwd",
paramType: "string",
defaultValue: "",
},
{
paramDesc: "旧密码,可不传,不传时,供新建账号设置密码",
paramName: "oldPwd",
paramType: "string",
defaultValue: "",
}
],
rtnTypeDesc: "返回修改后的用户",
rtnType: "json object{status:0,data:{}}),详细见后面示例"
},
{
methodDesc: "查询应用注册用户,访问地址:http://......../api/auth/accessAuth/queryRegUser,访问token需要放置到后续API方法调用的请求头中",
methodName: "queryRegUser",
paramdescs: [
{
}
],
rtnTypeDesc: "返回应用的注册用户",
rtnType: "json object{status:0,data:[])"
},
];
}
exam() {
return `
<pre>
1.获取访问Token (建议在本地缓存<3600S)
curl -k -H 'Content-type: application/json' -d '{appkey:xxxxx,secret:xxxx}' http://open.gongsibao.com/api/auth/accessAuth/getAccessKey
返回:
{
status:0,
data:{
{
accessKey:xxxxxxx,
app:{xxxx:xxxx,xxx:......}
}
}
}
2.用户注册(注意请求头,设置1中获取的访问token)
curl -k -H 'Content-type: application/json' -H 'AccessKey:{ak}' -d '{userName:xxxxx,password:xxxx,mobile:xxxxx}' http://open.gongsibao.com/api/auth/accessAuth/register
返回:
{
status:0,
data: {
auth_url: "/auth?opencode=xxxxxx"
}
}
注意:接入程序后台需要处理/auth?opencode=xxx,按照opencode去开放平台获取openuser,然后在自己的应用内
完成注册,并建立会话。
3.用户登录(注意请求头,设置1中获取的访问token)
curl -k -H 'Content-type: application/json' -H 'AccessKey:{ak}' -d '{userName:xxxxx,password:xxxx}' http://open.gongsibao.com/api/auth/accessAuth/login
返回:
{
status:0,
data: {
auth_url: "/auth?opencode=xxxxxx"
}
}
注意:接入程序后台需要处理/auth?opencode=xxx,按照opencode去开放平台获取openuser,然后在自己的应用内
完成登录,并建立会话。
4、获取手机验证码(注意请求头,设置1中获取的访问token)
curl -k -H 'Content-type: application/json' -H 'AccessKey:{ak}' -d '{mobile:xxxxx,tmplCode:"",signName:""}' http://open.gongsibao.com/api/auth/accessAuth/login
返回:
{
status:0,
data:{
vcode: "xxxxxx"
}
}
5、手机验证码登录(注意请求头,设置1中获取的访问token)
curl -k -H 'Content-type: application/json' -H 'AccessKey:{ak}' -d '{mobile:xxxxx,vcode:xxxxxx}' http://open.gongsibao.com/api/auth/accessAuth/loginByVCode
返回:
{
status:0,
data: {
auth_url: "/auth?opencode=xxxxxx"
}
}
6、换取开放用户信息(注意请求头,设置1中获取的访问token)
curl -k -H 'Content-type: application/json' -H 'AccessKey:{ak}' -d '{opencode:xxxxx}' http://open.gongsibao.com/api/auth/accessAuth/authByCode
返回:
{
status:0,
data: {
}
}
</pre>
<h3>开放平台单点注册/登录流程图</h3>
<img src="data:image/png;base64,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ImL9P/4RI/atieVLFsU2/bdrracAAACEqA50Mi25/AsApGjpnyPTfnNXDN330IagHhGxRdeusc+BR8S0SXfFMV//doteD4D2x8QggNYlqgOdiuVfAGht5ZZ7KfZYpWutP3DvbfH5E7+z0fb9jjg67rzuYlEdoANL+XlhUhBA6xPVAQCglRR7wzZ/26astX7dfY8V3W//w/8z9j/8PyscIW1dJrN3k/tkszPLHt/cx/OvkTKepsYEANDeiepAp1DpLMBNPQYA8n92bOqMwkrPQcdVGKebiuCV7pvNzmy0X2E0L3Z8U+csFt6feebFGDJkcGQyzfvNwDffXBJr1qyLD31ox2adp1JvvLEo1q37ewwcuNNmvW613HPPlBgyZNfYbbeB1R4KALRJojpAFF9rXcQAADbFunV/j0svvSUiIrLZbGSz2fjIR3aOL37xPzbpfKXieLloXvhYJTG+pWeZL126Io477tx44YV7N/n4lStXxwc/+P64447fx1/+8kr84hcXbLTfihUr44ILfh4PPTQzunfvFp/97AFx3nknRteuzf/f3l/+8ncxb96bcd113232udqDW26ZFCeddJSoDgAldKn2AAA2h5RZgGYFAgAtYdmyt2PMmDtiwIAd4kMfen8MGrRTbL99v00+X242eb5Kgnqpc+Q/Vnh84Uep6zS1T0TE1KlPxCGHpC0bU8xdd90f99wz5b1rZiJb4j/TamsviSVLVsTkyVfHuHEXx5QpM+KKK365ydfNl8m8+wZJc9XXr4nnn385li17u2HbqlWrY+XK+li1anU8++xLsXr1mkbHrF+/Pl544dWYO/dvjba/+eaSiIiYN29h/PWvc2PDhg2NHn/xxVfjlVfmbzSG119fGLNnvxbr169vtP2dd1bFn/88O9auXRddumQaPd/6+jXx7LMvxaJFyzbtiQNAB2OmOgAAQAtavvyd2G67beOkk45qsXMWi+TF5OJ2uRBebKmXcucvF8xT1lqfMmVGHHHEJyMi4rrrxsfNN/8munTpEv369Ymbb74gamp2iJ///N5YvHh5nHfeSRERcf31v4pFi5bFQQftFZdeekt0794t1q37e/Ts2SPWrl0X//Vf58azz74cfftuFePGXRwDB+4UO+9cE2ec8aXYbrttIyLiq1/9TEyZMiMiIp588q8xatQVsXz5O7Hjju+Lm246LwYN+kD8+c+z48wzfxL19e+G7HPPPSGGDz8w6uvXxDe+cXE899zL8YEPbB8DB+7YsHTNihUr44wzropZs+bEmjXrYuTIY+K0046NZcvejnvvnfbe65JtiNI771wTw4Z9PO6443dx0UU3xcEH7xWPPz4rjjxy/7jkktPi2mvHxx//+FSsW/eP6N+/bzz00MyYNOkn8YlPfCReeOHVGDHinBgyZNdYsGBxbLttnxg37uLo2rVr7LLL0XHKKZ+PefPejLlz/xbbb98vJk36Sbz99so4/PBvRf/+fWPlytXRt+9Wce+9l0d9/ZoYPvyM6NNny9h22z4xc+ZfYuLEK2O33QbGlCkz4utf/5/41Kf2jYULl8TChUsaxv/rX0+L8867Ifbff2jMmPF8fP3rn40zzvhyye83AHQGojoAAEALWrFiZWy9de+4776HYtasV2L33QfF0UcfUvF64uXCeKFc3K5kvfNy66jn4nsly8aUMm3aE/HjH4+KRYuWxW23/TamTr0htt22T5x99jVxySU3xw03nBNLliyPhQuXNByzbNnbsWjR8jj44L3ic587MHbeuSbOOuur8ZOf3BnTpj0RM2bcFh/84PvjhBN+EHV198Wll34zLr30mw3Hr1v397jnninxhS8Miw0bNsQxx5wdt976P3HIIXvHNdfcFd/5zpi4997L45hjzo6rrx4dw4cfGLNnvxb77HN8vPTSfXHHHb+PxYuXxzPPjIvVq9fGvvueEPvtNyQiIs4++5ro379vzJhxW6xatTo+8Ymvx5Ahu8bgwR+KhQuXRCYTDd/rTCYTO+zQP1aurI9Ro66IGTNujcGDPxSrVq2OAQOOjK997cjo2nWLeO65OTFnzsTo3r1bXH75bXHZZbfExIlj4vTTr4xRo0bEySe/exPiI474Vtx338Nx7LGHxRZbdInddx8UV1xxeqxatTr69j04li17O37607tjjz12iRtvPC8iIk4++Ycxa9acmDTpkRgwYIe4886LIyLikkt+ERdddFPceefFcd5518eYMd+J4447Iurr10RNzWcim82+9+bCJfHYY7fE/2fvzsPzKsv8gX+TNN0X6EZbWiiFsldACgjIWhSUXUAGRcQRqDIgqzPwcxRQVEA2nXG0gCMo4IKACiKLgMpSwCKLFGkLshVKW7rTjbTN749OYhreJCdpQpr087muXs17lue5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ALB+69LeBQAAAHRGy5Ytz8EHn5n//M/P51//9bA89NDT+fKXv5tDD90r3bp1bdZYDbU2KRUyNxWql5WNrV3JvS6F1PVrKXXNNcc0dI31t9c/DwCgNVipDgAA0AZ+//tHM2BAv5x88pGpqKjIvvvunL/85SfNDtSTNLlqu7Ggvf5q9rrjNBSsX331zdl000MybNhBOeKIczJr1twkyauvzsihh56VrbY6Kttsc3S++MVvZ8mSZUmS2bPn5eMf/1I23fSQfOhDJ+bJJ/++xpg33HBntt32mGyxxRHZZZcT8txzL65RX/1AvNQ119/X2Ir2Uu9TY/Uff/xX82//dmkOP/zs7LXXSRk79jN54onnmqz/1VdnpEePPfO///ubHH742dl++2Nz/PFfzapVq5IkQ4YcmD/+8cnacc4884qcdtplSZIf/eg32XrrozJ69JHZeuujct11v25yviQZOfLQXHrpDRk+/OOt+q8fAIBihOoAAABt4KmnpmSLLUbkhBO+Vhs033//E602ftH2L/VD51Ln1XXvvY/lO9/5aR555EeZPv2uDBy4QW0IfPzxX80222yWKVNuzVNP3ZS///2VfPvbP06SXHDBhHTtWpmXX/5tHnjgh7nnnsdqx3zooady1llX5je/uSIvvvjrnH/+iTnwwNNTVbWiZFuXotfW3AecNlZ/ly4VufXWB3L99RfmoYeuy8knH5ETTrigyfq7dq3MsmXLM2/eovzmN1fmySd/mnvvfSwPPtj46vglS5Zl/Phv5a67vptp027Pffd9P7/+9R+zbNnyRudLkm7duuahh57Kiy/enqOPHtfoPABA6xOqAwAAtIF58xbm3nsfyxe+cFReeeWOnH32p3PEEefmrbfeXqtx67Y0KbWSu0irk8Z6lN966wM54oh9M3z4RikvL89//deXc911/5nZs+fl4YefzjnnfDpJ0r17t5xyypG5446HkiR/+MMT+dSnDkp5eXl69uyez372kNoxb7jhzhx++D4ZPXqTJMknPrF/KirK89BDTzVYX6k669db6gGnNX/XP7ap+pPkiCP2yYYb9k2SHHnkfpky5dXMmPF2o/WXla0+97jjDkyyOvDefPPhee21t0peW41u3SozcOAGmTDhtkyd+mpGjBiSO++8Ot27d2vy/SorS446av90796t0TkAgLYhVAcAAGgDG2zQJ3vu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"/> `
;
return ``
}
}
module.exports = AccessAuthAPI;
// var req={app:{appkey:"wx76a324c5d201d1a4"}};
// var p={mobile:"13381139519",tmplCode:"SMS_173946419","signName":"ibossx"};
// var x=new AccessAuthAPI();
// var ff=x.fetchVCode(p,null,req);
// ff.then((v)=>{
// console.log(v);
// })
\ No newline at end of file
......@@ -7,6 +7,10 @@ class CtlBase {
this.service = system.getObject("service." + gname + "." + sname);
this.cacheManager = system.getObject("db.common.cacheManager");
}
static getServiceName(ClassObj) {
return ClassObj["name"].substring(0, ClassObj["name"].lastIndexOf("Ctl")).toLowerCase() + "Sve";
}
async setContextParams(pobj, qobj, req) {
}
......
const system = require("../../system");
const settings = require("../../../config/settings");
const uiconfig = system.getUiConfig2(settings.wxconfig.appId);
const appconfig = system.getSysConfig();
function exp(db, DataTypes) {
var base = {
//继承的表引用用户信息user_id
......@@ -16,10 +16,10 @@ function exp(db, DataTypes) {
},
auditStatus: {//审核状态"dsh": "待审核", "btg": "不通过", "tg": "通过"
type: DataTypes.ENUM,
values: Object.keys(uiconfig.config.pdict.audit_status),
values: Object.keys(appconfig.pdict.audit_status),
set: function (val) {
this.setDataValue("auditStatus", val);
this.setDataValue("auditStatusName", uiconfig.config.pdict.audit_status[val]);
this.setDataValue("auditStatusName", appconfig.pdict.audit_status[val]);
},
defaultValue:"dsh",
},
......@@ -29,7 +29,7 @@ function exp(db, DataTypes) {
values: Object.keys(uiconfig.config.pdict.source_type),
set: function (val) {
this.setDataValue("sourceType", val);
this.setDataValue("sourceTypeName", uiconfig.config.pdict.source_type[val]);
this.setDataValue("sourceTypeName", appconfig.pdict.source_type[val]);
}
},
sourceOrderNo: DataTypes.STRING(100),//来源单号
......
const system=require("../../../system");
const Dao=require("../../dao.base");
class AccountDao extends Dao{
constructor(){
super(Dao.getModelName(AccountDao));
}
async findOrCreate(ac,t){
var account= await this.model.findOne({where:{unionId:ac.unionId}},{transaction:t});
if(account){
return account;
}else{
account=await this.model.create(ac,{transaction:t});
return account;
}
}
async findOneByOnlyCode(onlycode){
return this.model.findOne({"where":{"onlyCode":onlycode}});
}
}
module.exports=AccountDao;
const system=require("../../../system");
const Dao=require("../../dao.base");
class AccountLogDao extends Dao{
constructor(){
super(Dao.getModelName(AccountLogDao));
}
}
module.exports=AccountLogDao;
const system=require("../../../system");
const Dao=require("../../dao.base");
class PAccountDao extends Dao{
constructor(){
super(Dao.getModelName(PAccountDao));
}
async findPAccount(t){
return this.model.findOne({},{transaction:t});
}
}
module.exports=PAccountDao;
......@@ -3,7 +3,6 @@ const Dao=require("../../dao.base");
class UserDao extends Dao{
constructor(){
super(Dao.getModelName(UserDao));
this.appDao=system.getObject("db.common.appDao");
}
async getAuths(userid){
var self=this;
......
const system=require("../../../system");
const Dao=require("../../dao.base");
class UsereaccountDao extends Dao{
constructor(){
super(Dao.getModelName(UsereaccountDao));
}
}
module.exports=UsereaccountDao;
const system=require("../../../system");
const Dao=require("../../dao.base");
class ApiTradeDao extends Dao{
constructor(){
super(Dao.getModelName(ApiTradeDao));
}
// extraWhere(obj,w){
// if(obj.codepath && obj.codepath!=""){
// if(obj.codepath.indexOf("mytraderecord")>0){//说明是普通用户的交易查询
// w["user_id"]=obj.uid;
// }
// }
// return w;
// }
async create(tradeobj,t){
var trade=await super.create(tradeobj,t)
return trade;
}
}
module.exports=ApiTradeDao;
const system=require("../../../system");
const Dao=require("../../dao.base");
class ArticleDao extends Dao{
constructor(){
super(Dao.getModelName(ArticleDao));
}
extraModelFilter(){
return {"key":"include","value":[{model:this.db.models.newschannel,attributes:["id","title"]},]};
}
orderBy(){
//return {"key":"include","value":{model:this.db.models.app}};
return [["orderNo","ASC"]];
}
}
module.exports=ArticleDao;
const system=require("../../../system");
const Dao=require("../../dao.base");
class ChannelDao extends Dao{
constructor(){
super(Dao.getModelName(ChannelDao));
}
extraModelFilter(){
//return {"key":"include","value":[{model:this.db.models.app,},{model:this.db.models.role,as:"Roles",attributes:["id","name"],joinTableAttributes:['created_at']}]};
return {"key":"include","value":[{model:this.db.models.role,as:"Roles",attributes:["id","name"]}]};
}
async preUpdate(u){
if(u.roles.length>0){
var roles=await this.db.models.role.findAll({where:{id:{[this.db.Op.in]:u.roles}}});
console.log("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
console.log(roles);
u.roles=roles
}
return u;
}
async update(obj){
var obj2=await this.preUpdate(obj);
console.log("update....................");
console.log(obj2);
await this.model.update(obj2,{where:{id:obj2.id}});
var channel=await this.model.findOne({where:{id:obj2.id}});
channel.setRoles(obj2.roles);
return channel;
}
}
module.exports=ChannelDao;
const system=require("../../../system");
const Dao=require("../../dao.base");
class LoopplayDao extends Dao{
constructor(){
super(Dao.getModelName(LoopplayDao));
}
// channelCode: ""
// extraModelFilter(){
// return {"key":"include","value":[{model:this.db.models.newschannel,attributes:["id","title"]},]};
// }
extraWhere(obj, w){
let channelCode = obj.channelCode || '';
if(channelCode == "index") {
w["channelCode"] = '';
} else if(channelCode) {
w["channelCode"] = channelCode;
}
// if(pageType == 1) {
// w["status"] = {[this.db.Op.in]: ['1']};
// } else if (pageType == 2) {
// w["status"] = {[this.db.Op.in]: ['2']};
// } else if (pageType == 3) {
// w["status"] = {[this.db.Op.in]: ['4','8','16']};
// }
return w;
}
orderBy(){
//return {"key":"include","value":{model:this.db.models.app}};
return [["orderNo","ASC"]];
}
}
module.exports=LoopplayDao;
const system=require("../../../system");
const Dao=require("../../dao.base");
class NewschannelDao extends Dao{
constructor(){
super(Dao.getModelName(NewschannelDao));
}
async findAgreenment(queryobj,qobj,req){
var result =await this.model.findAll({
where:{id:1},
include:{
model:this.db.models.article,
limit:1,
offset:0
},
});
console.log("---------------------------------------------------------------zhangjiao");
console.log(result);
return result;
}
orderBy(){
//return {"key":"include","value":{model:this.db.models.app}};
return [["orderNo","ASC"]];
}
async findPrev5(queryobj,qobj){
console.log(qobj);
return this.model.findAll({
where:{isPubed:1},
include:{
model:this.db.models.article,
limit:5,
offset:0
},
limit:6,
offset:0,
});
}
}
module.exports=NewschannelDao;
const system=require("../../../system");
const Dao=require("../../dao.base");
class SloganpictureDao extends Dao{
constructor(){
super(Dao.getModelName(SloganpictureDao));
}
// extraModelFilter(){
// return {"key":"include","value":[{model:this.db.models.newschannel,attributes:["id","title"]},]};
// }
orderBy(){
//return {"key":"include","value":{model:this.db.models.app}};
return [["orderNo","ASC"]];
}
}
module.exports=SloganpictureDao;
const system=require("../../../system");
const fs=require("fs");
const settings=require("../../../../config/settings");
var glob = require("glob");
class APIDocManager{
constructor(){
this.doc={};
this.buildAPIDocMap();
}
async buildAPIDocMap(){
var self=this;
//订阅任务频道
var apiPath=settings.basepath+"/app/base/api/impl";
var rs = glob.sync(apiPath + "/**/*.js");
if(rs){
for(let r of rs){
// var ps=r.split("/");
// var nl=ps.length;
// var pkname=ps[nl-2];
// var fname=ps[nl-1].split(".")[0];
// var obj=system.getObject("api."+pkname+"."+fname);
var ClassObj=require(r);
var obj=new ClassObj();
var gk=obj.apiDoc.group+"|"+obj.apiDoc.groupDesc
if(!this.doc[gk]){
this.doc[gk]=[];
this.doc[gk].push(obj.apiDoc);
}else{
this.doc[gk].push(obj.apiDoc);
}
}
}
}
}
module.exports=APIDocManager;
const system=require("../../../system");
const Dao=require("../../dao.base");
class ApiTradeDao extends Dao{
constructor(){
super(Dao.getModelName(ApiTradeDao));
}
// extraWhere(obj,w){
// if(obj.codepath && obj.codepath!=""){
// if(obj.codepath.indexOf("mytraderecord")>0){//说明是普通用户的交易查询
// w["user_id"]=obj.uid;
// }
// }
// return w;
// }
async create(tradeobj,t){
var trade=await super.create(tradeobj,t)
return trade;
}
}
module.exports=ApiTradeDao;
const system = require("../../../system");
const Dao = require("../../dao.base");
class AppDao extends Dao {
constructor() {
super(Dao.getModelName(AppDao));
}
async findOneById(id, t) {
var sqlWhere = {
where: { id: id },
attributes: ["id", "appkey", "secret", "domainName"], raw: true
};
if (t) {
sqlWhere.transaction = t;
}
var app = await this.model.findOne(sqlWhere);
return app;
}
async findOne(appKey, secret, t) {
var tmpAttributes = [`id`,
`appkey`,
`name`,
`domainName`,
`homePage`,
`docUrl`,
`authUrl`,
`logoUrl`,
`bkimageUrl`,
`showimgUrl`,
`detailimgUrl`,
`description`,
`isEnabled`,
`isPublish`,
`isCommon`,
`appType`,
`uiconfigUrl`,
`opCacheUrl`,
`notifyCacheCountUrl`];
if (t) {
var app = await this.model.findOne({ where: { appkey: appKey, secret: secret }, attributes: tmpAttributes, raw: true }, { transaction: t });
return app;
} else {
var app = await this.model.findOne({ where: { appkey: appKey, secret: secret }, attributes: tmpAttributes, raw: true });
return app;
}
}
async findOne2(appKey, t) {
var tmpAttributes = [`id`,
`appkey`,
`name`,
`domainName`,
`homePage`,
`docUrl`,
`authUrl`,
`logoUrl`,
`bkimageUrl`,
`showimgUrl`,
`detailimgUrl`,
`description`,
`isEnabled`,
`isPublish`,
`isCommon`,
`isSaas`,
`appType`,
`uiconfigUrl`,
`opCacheUrl`,
`notifyCacheCountUrl`];
if (t) {
var app = await this.model.findOne({ where: { appkey: appKey }, attributes: tmpAttributes, raw: true }, { transaction: t });
return app;
} else {
var app = await this.model.findOne({ where: { appkey: appKey }, attributes: tmpAttributes, raw: true });
return app;
}
}
async findAndCountAll(qobj, t) {
if(qobj.codepath.indexOf("comapps")>=0){
var rtn={};
var comp=await this.db.models.company.findOne({where:{companykey:qobj.search.companykey}});
var apps=await comp.getApps();
rtn.results={rows:apps,count:apps.length};
rtn.aggresult={};
return rtn;
}else{
return super.findAndCountAll(qobj, t);
}
}
extraWhere(obj, w, qc, linkAttrs) {
if (obj.codepath && obj.codepath != "") {
if (obj.codepath.indexOf("pmgmyapps") > 0) {//说明是应用管理员的查询
w["creator_id"] = obj.userid;
}
}
if (linkAttrs.length > 0) {
var search = obj.search;
var lnkKey = linkAttrs[0];
var strq = "$" + lnkKey.replace("~", ".") + "$";
w[strq] = { [this.db.Op.like]: "%" + search[lnkKey] + "%" };
}
return w;
}
}
module.exports = AppDao;
const system = require("../../../system");
const Dao = require("../../dao.base");
class CompanyDao extends Dao {
constructor() {
super(Dao.getModelName(CompanyDao));
}
extraWhere(obj, w, qc, linkAttrs) {
return w;
}
// extraModelFilter(pobj){
// return {"key":"include",
// "value":[{
// model:this.db.models.user,
// as:"Users",
// through:{
// where:{id:pobj.uid}
// }
// },
// ]};
// }
}
module.exports = CompanyDao;
......@@ -18,8 +18,6 @@ class DbFactory{
async initModels(){
var self=this;
var modelpath=path.normalize(path.join(__dirname, '../..'))+"/models/";
console.log("modelpath=====================================================");
console.log(modelpath);
var models=glob.sync(modelpath+"/**/*.js");
console.log(models.length);
models.forEach(function(m){
......@@ -29,58 +27,14 @@ class DbFactory{
console.log("init models....");
}
async initRelations(){
/**
一个账户对应多个登陆用户
一个账户对应一个commany
一个APP对应多个登陆用户
一个APP有多个角色
登陆用户和角色多对多
**/
/*建立账户和用户之间的关系*/
//account--不属于任何一个app,是统一用户
//用户登录时首先按照用户名和密码检查account是否存在,如果不存在则提示账号或密码不对,如果
//存在则按照按照accountid和应用key,查看user,后台实现对应user登录
//管理员添加用户,需要同时增加开放平台用户及其所属租户创建的公司
this.db.models.user.belongsTo(this.db.models.account,{constraints: false,});
this.db.models.account.hasMany(this.db.models.user,{constraints: false,});
this.db.models.user.belongsTo(this.db.models.company,{as:"owner",constraints: false,});//人员直属公司
this.db.models.user.belongsTo(this.db.models.user,{as:"tanentor",constraints: false,});//指定用户所属租户
this.db.models.app.belongsTo(this.db.models.user,{as:"creator",constraints: false,});//指定用户所属租户
this.db.models.user.belongsTo(this.db.models.app,{constraints: false,});
this.db.models.role.belongsTo(this.db.models.app,{constraints: false,});
this.db.models.role.belongsTo(this.db.models.company,{constraints: false,});
this.db.models.auth.belongsTo(this.db.models.app,{constraints: false,});
this.db.models.auth.belongsTo(this.db.models.company,{constraints: false,});
this.db.models.dataauth.belongsTo(this.db.models.app,{constraints: false,});
this.db.models.dataauth.belongsTo(this.db.models.user,{constraints: false,});
/*建立用户和角色之间的关系*/
this.db.models.user.belongsToMany(this.db.models.role, {as:"Roles",through: 'p_userrole',constraints: false,});
this.db.models.role.belongsToMany(this.db.models.user, {as:"Users",through: 'p_userrole',constraints: false,});
this.db.models.pconfig.belongsTo(this.db.models.app,{constraints: false,});
this.db.models.pconfig.belongsTo(this.db.models.company,{constraints: false,});
/*建立应用和租户公司之间的关系*/
this.db.models.company.belongsToMany(this.db.models.app, {through: this.db.models.companyapp,constraints: false,});
this.db.models.app.belongsToMany(this.db.models.company, {through: this.db.models.companyapp,constraints: false,});
/*建立用户和租户之间的关系*/
this.db.models.user.belongsToMany(this.db.models.company, {through: this.db.models.usercompany,constraints: false,});
this.db.models.company.belongsToMany(this.db.models.user, {through: this.db.models.usercompany,constraints: false,});
/*组织机构*/
this.db.models.org.belongsTo(this.db.models.org,{constraints: false,});
this.db.models.org.hasMany(this.db.models.org,{constraints: false,});
this.db.models.org.belongsTo(this.db.models.company,{constraints: false,});
this.db.models.org.belongsTo(this.db.models.app,{constraints: false,});
//组织机构和角色是多对多关系
this.db.models.org.belongsToMany(this.db.models.role,{through: this.db.models.orgrole,constraints: false,});
......@@ -88,7 +42,6 @@ class DbFactory{
//组织机构和用户是多对多关系
this.db.models.user.belongsTo(this.db.models.org,{constraints: false,});
}
//async getCon(){,用于使用替换table模型内字段数据使用
getCon(){
......@@ -116,12 +69,6 @@ class DbFactory{
}
return this.db;
}
getConhb(){
var that=this;
if(settings.env=="dev"){
}
return this.dbhb;
}
}
module.exports=DbFactory;
// const dbf=new DbFactory();
......
const system=require("../../../system");
const Dao=require("../../dao.base");
class MetaDao{
constructor(){
//super(Dao.getModelName(AppDao));
}
}
module.exports=MetaDao;
const system=require("../../../system");
const Dao=require("../../dao.base");
class OplogDao extends Dao{
constructor(){
super(Dao.getModelName(OplogDao));
}
}
module.exports=OplogDao;
const system=require("../../../system");
const Dao=require("../../dao.base");
class PConfigDao extends Dao{
constructor(){
super(Dao.getModelName(PConfigDao));
}
async findByConfigType(type,t){
return this.model.findOne({where:{configType:type}},{transaction:t});
}
extraWhere(obj,w,qc,linkAttrs){
// if(obj.codepath && obj.codepath!=""){
// // if(obj.codepath.indexOf("userarch")>0){//说明是应用管理员的查询
// // console.log(obj);
// // w["app_id"]=obj.appid;
// // }
// }
w["app_id"]=obj.appid;
w["company_id"]=obj.tocompanyid;
return w;
}
}
module.exports=PConfigDao;
const system=require("../../../system");
const Dao=require("../../dao.base");
class TaskDao extends Dao{
constructor(){
super(Dao.getModelName(TaskDao));
}
extraWhere(qobj,qw,qc){
qc.raw=true;
return qw;
}
async delete(task,qobj,t){
return task.destroy({where:qobj,transaction:t});
}
}
module.exports=TaskDao;
const system=require("../../../system");
const fs=require("fs");
const settings=require("../../../../config/settings");
var cron = require('node-cron');
class TaskManager{
constructor(){
this.taskDic={};
this.redisClient=system.getObject("util.redisClient");
this.buildTaskMap();
}
async buildTaskMap(){
var self=this;
//订阅任务频道
await this.redisClient.subscribeTask("task",this);
var taskPath=settings.basepath+"/app/base/db/task/";
const files=fs.readdirSync(taskPath);
if(files){
files.forEach(function(r){
var classObj=require(taskPath+"/"+r);
self[classObj.name]=new classObj();
});
}
}
async addTask(taskClassName,exp){
(async (tn,ep)=>{
if(!this.taskDic[tn]){
this.taskDic[tn]=cron.schedule(ep,()=>{
this[tn].doTask();
});
}
})(taskClassName,exp);
}
async deleteTask(taskClassName){
if(this.taskDic[taskClassName]){
this.taskDic[taskClassName].destroy();
delete this.taskDic[taskClassName];
}
}
async clearlist(){
var x=await this.redisClient.clearlist("tasklist");
return x;
}
async publish(channel,msg){
var x=await this.redisClient.publish(channel,msg);
return x;
}
async newTask(taskstr){
return this.redisClient.rpush("tasklist",taskstr);
}
}
module.exports=TaskManager;
// var cm= new CacheManager();
// cm["InitGiftCache"].cacheGlobalVal("hello").then(function(){
// cm["InitGiftCache"].cacheGlobalVal().then(x=>{
// console.log(x);
// });
// });
const system=require("../../../system");
const Dao=require("../../dao.base");
class TradeDao extends Dao{
constructor(){
super(Dao.getModelName(TradeDao));
this.pAccountDao=system.getObject("db.pAccountDao");
this.accountDao=system.getObject("db.accountDao");
this.appDao=system.getObject("db.appDao");
}
extraWhere(obj,w){
if(obj.codepath && obj.codepath!=""){
//ptraderecord----财务人员中的平台帐户、平台运营中的交易记录两项,查询的为全部的信息,不加条件,recommendFee:推荐分润----显示负数
if(obj.codepath.indexOf("mytraderecord")>=0|| obj.codepath.indexOf("ucmytrades")>=0){
//个人用户的交易记录:bizs/wx76a324c5d201d1a4/mytrades.js
//orderPersonFee:订单个人分润、recommendFee:推荐分润----显示正数、cashWithdrawal: 现金提现、fill:充值宝币、gift:赠送宝币、consume: 消费宝币
w["account_id"]=obj.account_id;
w[this.db.Op.and]={[this.db.Op.or]:[{tradeType: 'orderPersonFee'}, {tradeType: 'recommendFee'},
{tradeType: 'cashWithdrawal'},{tradeType: 'gift'},
{tradeType: 'consume'},{tradeType: 'fill'}]};
}
if(obj.codepath.indexOf("petrades")>=0){
//官费记录:bizs/wx76a324c5d201d1a4/petrades.js
// subPublicExpense:上缴官费、returnPublicExpense:官费退回
w[this.db.Op.and]={[this.db.Op.or]:[{tradeType: 'subPublicExpense'},{tradeType: 'returnPublicExpense'}]};
}
if(obj.codepath.indexOf("fintraderecord")>=0){
//财务人员中的交易记录:bizs/wx76a324c5d201d1a4/fintrades.js
//orderTrade: 订单交易、cashWithdrawal: 现金提现、subPublicExpense:上缴官费、returnPublicExpense:官费退回、fill: 充值宝币
w[this.db.Op.and]={[this.db.Op.or]:[{tradeType: 'fill'}, {tradeType: 'orderTrade'},
{tradeType: 'cashWithdrawal'},{tradeType: 'subPublicExpense'},
{tradeType: 'returnPublicExpense'}]};
}
}
return w;
}
//to do cache accountid
// async findAccountBalanceByUserId(aid){
// var tone= await this.model.findOne({
// where:{user_id:uid},
// include:[{"model":this.db.models.account,}]
// });
// var tmp={};
// var ac=await tone.getAccount();
// tmp.baoBalance=ac.baoBalance;
// tmp.renBalance=ac.renBalance;
// return tmp;
// }
async create(user,account,tradeobj,t){
console.log("tradeDao—————————————————————————————————————新用户测试创建---------user");
console.log(user);
var app = await this.appDao.findById(user.app_id);
console.log("tradeDao——————————————————————————————————————新用户测试------app");
console.log(app);
console.log("tradeDao——————————————————————————————————————新用户测试----------------account");
console.log(account);
var trade=null;
if(app && app.appid=="wx76a324c5d201d1a4"){
var tradeToSave=await this.model.build(tradeobj);
tradeToSave.tradeType="gift";
trade=await tradeToSave.save({transaction:t});
await trade.setUser(user,{transaction:t});
await trade.setAccount(account,{transaction:t});
//账户的交易处理
if(tradeToSave.tradeType=="gift" || tradeToSave.tradeType=="fill"){
// account.baoBalance+=tradeToSave.baoAmount;
// account.renBalance+=tradeToSave.renAmount;
account.baoBalance=Number(account.baoBalance)+Number(tradeToSave.baoAmount);
if(tradeToSave.tradeType!="fill"){
account.renBalance=Number(account.renBalance)+Number(tradeToSave.renAmount);
}
}else{
// account.baoBalance-=tradeToSave.baoAmount;
account.baoBalance=Number(account.baoBalance)-Number(tradeToSave.baoAmount);
//account.renBalance-=tradeToSave.renAmount;
}
await account.save({transaction:t});
//平台账户的交易处理
var paccount= await this.pAccountDao.findPAccount({transaction:t});
if(tradeToSave.tradeType=="gift" || tradeToSave.tradeType=="fill"){
// paccount.baoBalance-=tradeToSave.baoAmount;
// paccount.renBalance+=tradeToSave.renAmount?tradeToSave.renAmount:0.0;
paccount.baoBalance=Number(paccount.baoBalance)-Number(tradeToSave.baoAmount);
if(tradeToSave.tradeType=="fill"){
paccount.renBalance=Number(paccount.renBalance)-Number(tradeToSave.renAmount?tradeToSave.renAmount:0.0);
}
}else {
// paccount.baoBalance+=tradeToSave.baoAmount;
paccount.baoBalance=Number(paccount.baoBalance)+Number(tradeToSave.baoAmount);
}
var rc=system.getObject("util.redisClient");
await rc.delete("account_balance_"+account.id+"_"+user.app_id);
await paccount.save({transaction:t});
}
return trade;
}
async create2(user,account,tradeobj,t){
console.log("!!!!!!!@@@@@@@@@@@@@@##############$");
console.log(tradeobj);
var tradeToSave=await this.model.build(tradeobj);
console.log(tradeToSave);
//账户的交易处理
console.log(tradeToSave);
if(tradeToSave.tradeType=="gift" || tradeToSave.tradeType=="fill"){
account.baoBalance=Number(account.baoBalance)+Number(tradeToSave.baoAmount);
if(tradeToSave.tradeType!="fill"){
account.renBalance=Number(account.renBalance)+Number(tradeToSave.renAmount);
}
}else{
account.baoBalance=Number(account.baoBalance)-Number(tradeToSave.baoAmount);
}
await account.save({transaction:t});
//平台账户的交易处理
var paccount= await this.pAccountDao.findPAccount({transaction:t});
if(tradeToSave.tradeType=="gift" || tradeToSave.tradeType=="fill"){
paccount.baoBalance=Number(paccount.baoBalance)-Number(tradeToSave.baoAmount);
if(tradeToSave.tradeType=="fill"){
paccount.renBalance=Number(paccount.renBalance)-Number(tradeToSave.renAmount?tradeToSave.renAmount:0.0);
}
}
else {
paccount.baoBalance=Number(paccount.baoBalance)+Number(tradeToSave.baoAmount);
}
await paccount.save({transaction:t});
var tradeToSave = await this.preCreate(tradeToSave);
var trade=await tradeToSave.save({transaction:t});
await trade.setUser(user,{transaction:t});
await trade.setAccount(account,{transaction:t});
return trade;
}
preCreate(u){
// "fill": "充值", "consume": "消费", "gift": "赠送", "giftMoney": "红包", "refund": "退款","payment":"付款",
// "orderTrade": "订单交易", "orderRefund": "订单退款", "orderPersonFee": "订单个人分润",
// "orderPlatformFee": "订单平台分润","recommendFee": "推荐分润", "tmSubDeductCoin": "商标提报宝币扣除",
// "cashWithdrawal": "现金提现","platUseFee":"平台使用费","publicExpense":"官费","invoiceTaxes":"税费"
//个人:
// 1.人民币: 订单个人分润+ 推荐分润+ 现金提现-
// 2.宝币: 赠送+ 消费- 充值+ 商标提报宝币扣除-
//平台:
// 1.人民币:订单交易+ 订单退款- 订单个人分润- 订单平台分润+ 推荐分润- 平台使用费+ 官费+ 税费+
// 2.宝币: 赠送- 消费+ 充值-+ 商标提报宝币扣除+
if(u.tradeType=="consume" || u.tradeType=="cashWithdrawal" || u.tradeType=="tmSubDeductCoin" ){//消费 现金提现 商标提报宝币扣除
u.baoAmount=Math.abs(u.baoAmount)*(-1);
u.renAmount=Math.abs(u.renAmount)*(-1);
}
return u;
}
async updatePAccount(obj,t){
var bao = obj.bao;
var ren = obj.ren;
var paccount= await this.pAccountDao.findPAccount({transaction:t});
paccount.renBalance=parseFloat(paccount.renBalance)-parseFloat(ren);
console.log(obj);
console.log(paccount.renBalance);
console.log(paccount);
await this.pAccountDao.update(paccount.dataValues,t);
}
async createOrderTrade(u,t){
console.log("createOrderTrade DAO+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
console.log(u);
if(u.tradeType=="orderTrade"){//订单交易
var paccount= await this.pAccountDao.findPAccount({transaction:t});
paccount.renBalance=parseFloat(paccount.renBalance)+parseFloat(u.renAmount);
//await paccount.save({transaction:t});
await this.pAccountDao.update(paccount.dataValues,t);
}
if(u.tradeType=="orderPersonFee"){//订单个人分润
var account = await this.accountDao.findById(u.account_id);
account=account.dataValues;
console.log("订单个人分润");
console.log(account);
// paccount.renBalance=Number(paccount.renBalance)-Number(u.renAmount);
// //await paccount.save({transaction:t});
// await this.pAccountDao.update(paccount.dataValues,t);
account.renBalance=parseFloat(account.renBalance)+parseFloat(u.renAmount);
await this.accountDao.update(account,t);
}
if(u.tradeType=="recommendFee"){//推荐分润
console.log("推荐分润");
console.log(account);
var account = await this.accountDao.findById(u.account_id);
account=account.dataValues;
// paccount.renBalance=Number(paccount.renBalance)-Number(u.renAmount);
// //await paccount.save({transaction:t});
// await this.pAccountDao.update(paccount.dataValues,t);
account.renBalance=parseFloat(account.renBalance)+parseFloat(u.renAmount);
await this.accountDao.update(account,t);
}
if(u.tradeType=="orderPlatformFee" || u.tradeType=="publicExpense" || u.tradeType=="invoiceTaxes"){//平台分润 官费 税费
//平台分润 官费 税费 只创建交易数据 平台账户余额不变
}
if(u.tradeType=="platUseFee"){//平台使用费
console.log("平台使用费");
//平台使用费 只创建交易数据 账户余额不变
}
if(u.tradeType=="consume"){//消费宝币
var paccount= await this.pAccountDao.findPAccount({transaction:t});
var account = await this.accountDao.findById(u.account_id);
account=account.dataValues;
paccount.renBalance=Number(paccount.renBalance)+Number(u.renAmount);
paccount.baoBalance=Number(paccount.baoBalance)+Number(u.baoAmount);
//await paccount.save({transaction:t});
await this.pAccountDao.update(paccount.dataValues,t);
account.renBalance=Number(account.renBalance)-Number(u.renAmount);
account.baoBalance=Number(account.baoBalance)-Number(u.baoAmount);
await this.accountDao.update(account,t);
}
var u2=this.preCreate(u);
return this.model.create(u2,{transaction: t}).then(u=>{
return u;
});
}
}
module.exports=TradeDao;
const system=require("../../../system");
const Dao=require("../../dao.base");
class UploadDao extends Dao{
constructor(){
super(Dao.getModelName(UploadDao));
}
}
module.exports=UploadDao;
const system=require("../../../system");
const Dao=require("../../dao.base");
class MsgHistoryDao extends Dao{
constructor(){
super(Dao.getModelName(MsgHistoryDao));
}
extraWhere(obj,w){
if(obj.ukstr && obj.ukstr!=""){
// w={[this.db.Op.or]:[
// {[this.db.Op.and]:[{sender:obj.ukstr},{target:obj.extra}]},
// {[this.db.Op.and]:[{sender:obj.extra},{target:obj.ukstr}]},
// ]
// };
w[this.db.Op.or]=[
{[this.db.Op.and]:[{sender:obj.ukstr},{target:obj.extra}]},
{[this.db.Op.and]:[{sender:obj.extra},{target:obj.ukstr}]},
];
}
return w;
}
orderBy(){
//return {"key":"include","value":{model:this.db.models.app}};
return [["id","DESC"]];
}
}
module.exports=MsgHistoryDao;
const system=require("../../../system");
const Dao=require("../../dao.base");
class MsgNoticeDao extends Dao{
constructor(){
super(Dao.getModelName(MsgNoticeDao));
}
async saveNotice(msg, t) {
var noticeFrom = await super.findOne({fromId : msg.senderId, toId : msg.targetId});
if(noticeFrom) {
var set = {lastMsgId:msg.id};
if(msg.businessLicense_id) {
set.businessLicense_id = msg.businessLicense_id;
}
await super.updateByWhere(set, {where:{id:noticeFrom.id}}, t);
} else {
noticeFrom = {
fromuser: msg.sender,
fromId:msg.senderId,
touser: msg.target,
toId:msg.targetId,
isAccepted:true,
lastMsgId:msg.id,
businessLicense_id : msg.businessLicense_id || 0
};
await super.create(noticeFrom, t);
}
var noticeTo = await super.findOne({fromId : msg.targetId, toId : msg.senderId});
if(noticeTo) {
var set = {lastMsgId:msg.id};
if(msg.businessLicense_id) {
set.businessLicense_id = msg.businessLicense_id;
}
await super.updateByWhere(set, {where:{id:noticeTo.id}}, t);
} else {
noticeTo = {
fromuser: msg.target,
fromId:msg.targetId,
touser: msg.sender,
toId:msg.senderId,
isAccepted:true,
lastMsgId:msg.id,
businessLicense_id : msg.businessLicense_id || 0
};
await super.create(noticeTo, t);
}
}
orderBy(){
//return {"key":"include","value":{model:this.db.models.app}};
return [["id","DESC"]];
}
}
module.exports=MsgNoticeDao;
......@@ -9,66 +9,10 @@ const md5 = require("MD5");
var dbf=system.getObject("db.common.connection");
var db=dbf.getCon();
db.sync({force:true}).then(async ()=>{
console.log("sync complete...");
//创建平台配置
const PConfig=db.models.pconfig;
var pconfigObjs=await PConfig.bulkCreate([
{configType:"price",configValue:"100",app_id:settings.platformid,company_id:settings.platformcompanyid,appkey:settings.appKey},
{configType:"initGift",configValue:"10000",app_id:settings.platformid,company_id:settings.platformcompanyid,appkey:settings.appKey},
{configType:"apiInitGift",configValue:"500",app_id:settings.platformid,company_id:settings.platformcompanyid,appkey:settings.appKey},
{configType:"apiCallPrice",configValue:"10",app_id:settings.platformid,company_id:settings.platformcompanyid,appkey:settings.appKey},
{configType:"logOpWrite",configValue:"-1",app_id:settings.platformid,company_id:settings.platformcompanyid,appkey:settings.appKey},//操作日志步骤是否写入,0否,1是
]);
//创建平台账户
const PAccount=db.models.paccount;
const pa=await PAccount.create({});
//创建APP
const App=db.models.app;
const Account=db.models.account;
const Company=db.models.company;
const Auth=db.models.auth;
//创建role
const Role=db.models.role;
var hp=settings.homePage();
var authUrl=settings.authUrl();
//建立平台应用和上帝超级管理员
App.create({appkey:"wx76a324c5d201d1a4",
name:"蜂擎开放平台",
homePage:hp,
docUrl:settings.docUrl(),
authUrl:authUrl,isEnabled:true,isSaas:true,secret:"f99d413b767f09b5dff0b3610366cc46",logoUrl:"",
isCommon:true,
isPublic:false,
appType:"web",
}).then(app=>{
const User=db.models.user;
User.create({owner_id:settings.platformid,userName:"sm",password:md5("123"+ "_" + settings.salt),isSuper:true,isAdmin:true,isEnabled:true,nickName:"superman"}).then(function(u){
app.setCreator(u);
u.setApp(app);
Account.create({nickName:"superman",userName:"sm",password:md5("123")}).then(function(ac){
u.setAccount(ac);
});
//设置当前平台初始的租户,并默认设置当前租户所其用的APP
Company.create({name:"蜂擎云服科技有限公司"}).then(async function(cmp){
await u.addCompany(cmp,{through:{isCurrent:false}});
await cmp.addApp(app);
Role.bulkCreate([
{ name:"租户",code:"common",isSystem:1,app_id:app.id,company_id:cmp.id},
{ name:"路过",code:"pass",isSystem:1,app_id:app.id,company_id:cmp.id},
]);
});
//设置当前初始租户所开启的应用
//初始化平台的租户权限
Auth.create({
rolecode:"common",
bizcode:"companyinfo",
codepath:"paasroot/tanentCenter/appMag/companyinfo",
authstrs:"add,edit,delete",
app_id:1,
company_id:1
});
});
const User=db.models.user;
User.create({userName:"sm",password:md5("123"+ "_" + settings.salt),isSuper:true,isAdmin:true,isEnabled:true,nickName:"superman"}).then(function(u){
console.log("sync complete...");
});
//创建role
......
module.exports = {
"config": {
"pdict": {
"app_type": { "api": "API服务","web": "PCWEB","app":"移动APP","xcx":"小程序","access":"接入"},
"data_priv": { "auth.role": "角色", "auth.user": "用户" },
"noticeType": {"sms": "短信", "email": "邮件","wechat":"微信"},
"authType": {"add": "新增", "edit": "编辑","delete":"删除","export":"导出","show":"查看"},
"mediaType": {"vd": "视频", "ad": "音频","qt":"其它"},
"usageType": {"kt": "课堂","taxkt":"财税课堂", "qt": "其它"},
"opstatus": {"0": "失败", "1": "成功"},
"sex": {"male": "男", "female": "女"},
"configType": {"price": "宝币兑换率", "initGift": "初次赠送","apiInitGift":"API初次赠送","apiCallPrice":"api调用价格"},
"logLevel": {"debug": 0, "info": 1, "warn": 2, "error": 3, "fatal": 4},
"msgType": { "sys": "系统", "single": "单点", "multi": "群发", "mryzSingle": "每日易照单点", "mryzLicense": "群发", },
"tradeType": {
"fill": "充值宝币", "consume": "消费宝币", "gift": "赠送宝币", "giftMoney": "红包", "refund": "退款", "payment": "付款",
},
"node_type":{"org":"组织","arc":"文档"}
}
}
}
const fs=require("fs");
const path=require("path");
const appPath=path.normalize(__dirname+"/app");
const bizsPath=path.normalize(__dirname+"/bizs");
var appJsons={
config:require(appPath+"/"+"platform.js").config
}
module.exports=appJsons;
const system=require("../../../system");
const settings=require("../../../../config/settings");
const uiconfig=system.getUiConfig2(settings.appKey);
const appconfig=system.getSysConfig();
module.exports = (db, DataTypes) => {
return db.define("org", {
code: {
......@@ -22,7 +22,7 @@ module.exports = (db, DataTypes) => {
nodeType: {//默认为组织
type:DataTypes.ENUM,
allowNull: false,
values: Object.keys(uiconfig.config.pdict.node_type),
values: Object.keys(appconfig.pdict.node_type),
defaultValue:'org'
},
isPosition:{//是否是岗位
......
const system=require("../../../system");
const settings=require("../../../../config/settings");
const uiconfig=system.getUiConfig2(settings.appKey);
const appconfig=system.getSysConfig();
module.exports = (db, DataTypes) => {
return db.define("user", {
userName: {
......@@ -18,7 +18,7 @@ module.exports = (db, DataTypes) => {
sex: {
type:DataTypes.ENUM,
allowNull: true,
values: Object.keys(uiconfig.config.pdict.sex),
values: Object.keys(appconfig.pdict.sex),
},
mobile:DataTypes.STRING,
mail: {
......@@ -34,9 +34,7 @@ module.exports = (db, DataTypes) => {
type:DataTypes.BOOLEAN,
defaultValue: false
},
wxopenid:DataTypes.STRING,
app_id:DataTypes.INTEGER,
account_id:DataTypes.INTEGER,
center_id:DataTypes.INTEGER,
isEnabled:{
type:DataTypes.BOOLEAN,
defaultValue: true
......
const system=require("../../../system");
const settings=require("../../../../config/settings");
const uiconfig=system.getUiConfig2(settings.appKey);
module.exports = (db, DataTypes) => {
return db.define("account", {
nickName: {
type:DataTypes.STRING(128),
allowNull: true,
},
userName:DataTypes.STRING,
password: {
type:DataTypes.STRING,
validate: {
// length(value){
// if(value.length<6){
// throw new Error("lenght。。。")
// }
// }
}
},
sex: {
type:DataTypes.ENUM,
allowNull: true,
values: Object.keys(uiconfig.config.pdict.sex),
},
headUrl: DataTypes.STRING,
mobile: DataTypes.STRING,
baoBalance:{
type:DataTypes.DECIMAL(12,2),
defaultValue:0.00,
},
renBalance:{
type:DataTypes.DECIMAL(12,2),
defaultValue:0.00,
},
},{
paranoid: true,//假的删除
underscored: true,
version: true,
freezeTableName: true,
//freezeTableName: true,
// define the table's name
tableName: 'p_account',
validate: {
},
indexes:[
// Create a unique index on email
// {
// unique: true,
// fields: ['email']
// },
//
// // Creates a gin index on data with the jsonb_path_ops operator
// {
// fields: ['data'],
// using: 'gin',
// operator: 'jsonb_path_ops'
// },
//
// // By default index name will be [table]_[fields]
// // Creates a multi column partial index
// {
// name: 'public_by_author',
// fields: ['author', 'status'],
// where: {
// status: 'public'
// }
// },
//
// // A BTREE index with a ordered field
// {
// name: 'title_index',
// method: 'BTREE',
// fields: ['author', {attribute: 'title', collate: 'en_US', order: 'DESC', length: 5}]
// }
]
});
}
const system=require("../../../system");
const settings=require("../../../../config/settings");
const uiconfig=system.getUiConfig2(settings.appKey);
module.exports = (db, DataTypes) => {
return db.define("apitrade", {
tradeType: {
type:DataTypes.ENUM,
allowNull: false,
values: Object.keys(uiconfig.config.pdict.tradeType),
},
op:{//访问路径
type:DataTypes.STRING,
allowNull: true,
},
srcappkey:{//
type:DataTypes.STRING,
allowNull: true,
},
destappkey:{//
type:DataTypes.STRING,
allowNull: true,
},
params:{
type:DataTypes.STRING(1024),
allowNull: true,
},
clientIp:DataTypes.STRING,
agent:{
type:DataTypes.STRING,
allowNull: true,
},
isAllowed:{
type:DataTypes.BOOLEAN,
defaultValue: true
},
amount: {//每条多少钱
type:DataTypes.INTEGER ,
allowNull: false,
defaultValue: 0
},
desc:DataTypes.STRING,//比如前500条免费
},{
paranoid: false,//假的删除
underscored: true,
version: true,
freezeTableName: true,
timestamps: true,
updatedAt:false,
//freezeTableName: true,
// define the table's name
tableName: 'api_trade',
validate: {
},
indexes:[
// Create a unique index on email
// {
// unique: true,
// fields: ['email']
// },
//
// // Creates a gin index on data with the jsonb_path_ops operator
// {
// fields: ['data'],
// using: 'gin',
// operator: 'jsonb_path_ops'
// },
//
// // By default index name will be [table]_[fields]
// // Creates a multi column partial index
// {
// name: 'public_by_author',
// fields: ['author', 'status'],
// where: {
// status: 'public'
// }
// },
//
// // A BTREE index with a ordered field
// {
// name: 'title_index',
// method: 'BTREE',
// fields: ['author', {attribute: 'title', collate: 'en_US', order: 'DESC', length: 5}]
// }
]
});
}
const system = require("../../../system");
const settings = require("../../../../config/settings");
const uiconfig = system.getUiConfig2(settings.appKey);
module.exports = (db, DataTypes) => {
return db.define("app", {
appkey: DataTypes.STRING,//需要在后台补充
secret: DataTypes.STRING,//需要在后台补充
name: {
type: DataTypes.STRING,
allowNull: false,
},//和user的from相同,在注册user时,去创建
domainName: DataTypes.STRING,//域名
homePage: DataTypes.STRING,//首页
authUrl: DataTypes.STRING,//认证地址
docUrl: DataTypes.STRING,//接口文档地址
uiconfigUrl: DataTypes.STRING,//基础信息配置信息地址
logoUrl: DataTypes.STRING,//应用Logo
bkimageUrl: DataTypes.STRING,//应用背景图
showimgUrl: DataTypes.STRING,//应用显示图标
detailimgUrl: DataTypes.STRING,//应用详情介绍地址
opCacheUrl: DataTypes.STRING,//操作缓存地址
notifyCacheCountUrl: DataTypes.STRING,//接收API使用计数的通知URL
description: DataTypes.STRING,//应用描述
isSaas: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: true
},//是否启用
isEnabled: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false
},//是否启用
isPublish: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false
},//是否对外
isCommon: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false
},//是否公共服务
appType: {
type: DataTypes.ENUM,
allowNull: true,
values: Object.keys(uiconfig.config.pdict.app_type),
},
}, {
paranoid: true,//假的删除
underscored: true,
version: true,
freezeTableName: true,
//freezeTableName: true,
// define the table's name
tableName: 'p_app',
validate: {
},
indexes: [
// Create a unique index on email
// {
// unique: true,
// fields: ['email']
// },
//
// // Creates a gin index on data with the jsonb_path_ops operator
// {
// fields: ['data'],
// using: 'gin',
// operator: 'jsonb_path_ops'
// },
//
// // By default index name will be [table]_[fields]
// // Creates a multi column partial index
// {
// name: 'public_by_author',
// fields: ['author', 'status'],
// where: {
// status: 'public'
// }
// },
//
// // A BTREE index with a ordered field
// {
// name: 'title_index',
// method: 'BTREE',
// fields: ['author', {attribute: 'title', collate: 'en_US', order: 'DESC', length: 5}]
// }
]
});
}
module.exports = (db, DataTypes) => {
return db.define("company", {
name: {
type:DataTypes.STRING,
allowNull: false,
},
creditCode: {
type:DataTypes.STRING,
allowNull: true,
},
licenseUrl: DataTypes.STRING,
description: DataTypes.STRING,
companykey:{
type:DataTypes.STRING,
allowNull: true,
},
},{
paranoid: true,//假的删除
underscored: true,
version: true,
freezeTableName: true,
tableName: 'p_company',
validate: {
},
});
}
module.exports = (db, DataTypes) => {
return db.define("companyapp", {
},{
paranoid: false,//假的删除
underscored: true,
version: true,
freezeTableName: true,
tableName: 'p_companyapp',
validate: {
},
});
}
const system=require("../../../system");
const settings=require("../../../../config/settings");
const uiconfig=system.getUiConfig2(settings.appKey);
module.exports = (db, DataTypes) => {
return db.define("oplog", {
appkey: {
type:DataTypes.STRING,
allowNull: true,
},
appname:{
type:DataTypes.STRING,
allowNull: false,
},
userid: { type: DataTypes.INTEGER,allowNull: true},
username:{
type:DataTypes.STRING,
allowNull: true,
},
logLevel: {
type:DataTypes.ENUM,
allowNull: false,
values: Object.keys(uiconfig.config.pdict.logLevel),
defaultValue: "info",
},
op:{
type:DataTypes.STRING,
allowNull: true,
},
content:{
type:DataTypes.STRING(4000),
allowNull: true,
},
clientIp:DataTypes.STRING,
agent:{
type:DataTypes.STRING,
allowNull: true,
},
opTitle:DataTypes.STRING(500),
},{
paranoid: false,//假的删除
underscored: true,
version: true,
freezeTableName: true,
timestamps: true,
updatedAt:false,
//freezeTableName: true,
// define the table's name
tableName: 'op_log',
validate: {
},
indexes:[
// Create a unique index on email
// {
// unique: true,
// fields: ['email']
// },
//
// // Creates a gin index on data with the jsonb_path_ops operator
// {
// fields: ['data'],
// using: 'gin',
// operator: 'jsonb_path_ops'
// },
//
// // By default index name will be [table]_[fields]
// // Creates a multi column partial index
// {
// name: 'public_by_author',
// fields: ['author', 'status'],
// where: {
// status: 'public'
// }
// },
//
// // A BTREE index with a ordered field
// {
// name: 'title_index',
// method: 'BTREE',
// fields: ['author', {attribute: 'title', collate: 'en_US', order: 'DESC', length: 5}]
// }
]
});
}
module.exports = (db, DataTypes) => {
return db.define("paccount", {
baoBalance:{
type:DataTypes.DECIMAL(12,2),
defaultValue:0.00,
},
renBalance:{
type:DataTypes.DECIMAL(12,2),
defaultValue:0.00,
},
},{
paranoid: true,//假的删除
underscored: true,
version: true,
freezeTableName: true,
//freezeTableName: true,
// define the table's name
tableName: 'pp_account',
validate: {
},
indexes:[
// Create a unique index on email
// {
// unique: true,
// fields: ['email']
// },
//
// // Creates a gin index on data with the jsonb_path_ops operator
// {
// fields: ['data'],
// using: 'gin',
// operator: 'jsonb_path_ops'
// },
//
// // By default index name will be [table]_[fields]
// // Creates a multi column partial index
// {
// name: 'public_by_author',
// fields: ['author', 'status'],
// where: {
// status: 'public'
// }
// },
//
// // A BTREE index with a ordered field
// {
// name: 'title_index',
// method: 'BTREE',
// fields: ['author', {attribute: 'title', collate: 'en_US', order: 'DESC', length: 5}]
// }
]
});
}
module.exports = (db, DataTypes) => {
const enums={
price:"宝币兑换率",
initGift:"初次赠送",
apiCallPrice:"API调用价格",
apiInitGift:"API初次赠送次数",
logOpWrite:"操作日志步骤是否写入,0否,1是",
}
var PConfig=db.define("pconfig", {
name: {
type:DataTypes.STRING,
allowNull: false,
// get(){
// const ctype = this.getDataValue("configType");
// return enums[ctype];
// }
},
configType: {
type:DataTypes.ENUM,
allowNull: false,
values: Object.keys(enums),
set:function(val){
this.setDataValue("name",enums[val]);
this.setDataValue("configType",val);
}
},
configValue: {
type:DataTypes.STRING,
allowNull: false,
},
appkey: {
type:DataTypes.STRING,
allowNull: false,
},
},{
paranoid: true,//假的删除
underscored: true,
version: true,
freezeTableName: true,
tableName: 'p_config',
validate: {
},
});
PConfig.enums=enums;
return PConfig;
}
module.exports = (db, DataTypes) => {
return db.define("task", {
app_id:DataTypes.STRING,//需要在后台补充
taskClassName: {
type:DataTypes.STRING(100),
allowNull: false,
unique: true
},//和user的from相同,在注册user时,去创建
taskexp: {
type:DataTypes.STRING,
allowNull: false,
},//和user的from相同,在注册user时,去创建
desc:DataTypes.STRING,//需要在后台补充
},{
paranoid: false,//假的删除
underscored: true,
version: true,
freezeTableName: true,
//freezeTableName: true,
// define the table's name
tableName: 'p_task',
validate: {
},
indexes:[
// Create a unique index on email
// {
// unique: true,
// fields: ['email']
// },
//
// // Creates a gin index on data with the jsonb_path_ops operator
// {
// fields: ['data'],
// using: 'gin',
// operator: 'jsonb_path_ops'
// },
//
// // By default index name will be [table]_[fields]
// // Creates a multi column partial index
// {
// name: 'public_by_author',
// fields: ['author', 'status'],
// where: {
// status: 'public'
// }
// },
//
// // A BTREE index with a ordered field
// {
// name: 'title_index',
// method: 'BTREE',
// fields: ['author', {attribute: 'title', collate: 'en_US', order: 'DESC', length: 5}]
// }
]
});
}
module.exports = (db, DataTypes) => {
return db.define("usercompany", {
isCurrent: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false
},//是否对外
},{
paranoid: false,//假的删除
underscored: true,
version: true,
freezeTableName: true,
tableName: 'p_usercompany',
validate: {
},
});
}
const system=require("../../../system");
const settings=require("../../../../config/settings");
const uiconfig=system.getUiConfig2(settings.appKey);
module.exports = (db, DataTypes) => {
return db.define("msghistory", {
msgType:{
type:DataTypes.ENUM,
allowNull: false,
values: Object.keys(uiconfig.config.pdict.msgType),
},
sender:DataTypes.STRING,
senderId:DataTypes.INTEGER,
target:DataTypes.STRING,
targetId:DataTypes.INTEGER,
content: {
type: DataTypes.TEXT('long'),
allowNull: false,
},//需要在后台补充
isRead:{//分享时是否渠道店铺名称,0否,1是
type:DataTypes.BOOLEAN,
defaultValue: false,
},
},{
paranoid: true,//假的删除
underscored: true,
version: true,
freezeTableName: true,
//freezeTableName: true,
// define the table's name
tableName: 'msghistory',
validate: {
},
indexes:[
// Create a unique index on email
// {
// unique: true,
// fields: ['email']
// },
//
// // Creates a gin index on data with the jsonb_path_ops operator
// {
// fields: ['data'],
// using: 'gin',
// operator: 'jsonb_path_ops'
// },
//
// // By default index name will be [table]_[fields]
// // Creates a multi column partial index
// {
// name: 'public_by_author',
// fields: ['author', 'status'],
// where: {
// status: 'public'
// }
// },
//
// // A BTREE index with a ordered field
// {
// name: 'title_index',
// method: 'BTREE',
// fields: ['author', {attribute: 'title', collate: 'en_US', order: 'DESC', length: 5}]
// }
]
});
}
module.exports = (db, DataTypes) => {
return db.define("msgnotice", {
fromuser: DataTypes.STRING,//需要在后台补充
fromId:DataTypes.INTEGER,
touser: DataTypes.STRING,//需要在后台补充
toId:DataTypes.INTEGER,
businessLicense_id:DataTypes.INTEGER,
//"onlineset"+"¥"+data.appkey:[uk+"¥"+data.nickName+"¥"+data.imgUrl] uk=appid¥uid
isAccepted:DataTypes.BOOLEAN,
lastMsgId:DataTypes.INTEGER,
},{
paranoid: true,//假的删除
underscored: true,
version: true,
freezeTableName: true,
//freezeTableName: true,
// define the table's name
tableName: 'msgnotice',
validate: {
},
indexes:[
// Create a unique index on email
// {
// unique: true,
// fields: ['email']
// },
//
// // Creates a gin index on data with the jsonb_path_ops operator
// {
// fields: ['data'],
// using: 'gin',
// operator: 'jsonb_path_ops'
// },
//
// // By default index name will be [table]_[fields]
// // Creates a multi column partial index
// {
// name: 'public_by_author',
// fields: ['author', 'status'],
// where: {
// status: 'public'
// }
// },
//
// // A BTREE index with a ordered field
// {
// name: 'title_index',
// method: 'BTREE',
// fields: ['author', {attribute: 'title', collate: 'en_US', order: 'DESC', length: 5}]
// }
]
});
}
const system = require("../../../system");
const ServiceBase = require("../../sve.base")
const settings = require("../../../../config/settings")
class UserService extends ServiceBase {
constructor() {
super("auth", ServiceBase.getDaoName(UserService));
this.accountDao = system.getObject("db.auth.accountDao");
// this.pConfigDao=system.getObject("db.pconfigDao");
// this.pTradeDao=system.getObject("db.tradeDao");
this.appDao = system.getObject("db.common.appDao");
this.roleDao = system.getObject("db.auth.roleDao");
this.compDao=system.getObject("db.common.companyDao");
}
async modiPasswordByMobile(appid,mobile,newpwd){
var self=this;
var newp=await super.getEncryptStr(newpwd);
return this.db.transaction(async function (t) {
var mu=await self.db.models.user.findOne({
where:{app_id:appid,mobile:mobile},
include:[
{model:self.db.models.account},
],
transaction:t
});
mu.account.password=newp;
await mu.account.save({transaction:t});
//按照accountid去批量修改密码
await self.db.models.user.update({password:newp},{where:{account_id:mu.account_id},transaction:t});
return mu;
//注册接口
//封装kongurl
async register(p,q){
p.password=this.getEncryptStr(p.password);
return this.db.transaction(async function (t) {
let u=await this.dao.create(p,t)
//创建统一账号
});
}
async modiPasswordByUserName(appid,uname,newpwd,oldpwd){
var self=this;
var newp=await super.getEncryptStr(newpwd);
var oldp=oldpwd?await super.getEncryptStr(oldpwd):null;
return this.db.transaction(async function (t) {
var mu=null;
if(oldp){
mu= await self.db.models.user.findOne({
where:{app_id:appid,userName:uname,password:oldp},
include:[
{model:self.db.models.account},
],
transaction:t
});
}else{
mu= await self.db.models.user.findOne({
where:{app_id:appid,userName:uname},
include:[
{model:self.db.models.account},
],
transaction:t
});
}
if(mu){
mu.account.password=newp;
await mu.account.save({transaction:t});
//按照accountid去批量修改密码
await self.db.models.user.update({password:newp},{where:{account_id:mu.account_id},transaction:t});
}
return mu;
});
}
async bindCompany(cmpinfo,uid){
var self=this;
return this.db.transaction(async function (t) {
//先按照公司名称查询,是否存在
var comp=await self.compDao.model.findOne({where:{name:cmpinfo.name}});
if(!comp){
comp=await self.compDao.model.create(cmpinfo,{transaction:t});
//设置登录用户的公司ID
await self.dao.model.update({company_id:comp.id},{where:{id:uid},transaction:t});
}else{
await comp.update(cmpinfo,{transaction:t});
//登录接口封装kong-url
async login(p,q){
}
//创建统一账号
async cregister(uname){
try{
let rtn=await system.post3wFormTypeReq(settings.kongurl+"consumers",{username:uname})
if(rtn.statusCode==409){
return new Error("已经存在相同的统一账号名称!");
}
return comp;
});
}
async authByCode(opencode) {
var openuser = await this.cacheManager["OpenCodeCache"].cache(opencode);
return openuser;
}
async checkSameName(uname, appid, t) {
var ac = await this.dao.model.findOne({ where: { userName: uname, app_id: appid }, transaction: t });
var rtn = { isExist: false };
if (ac) {
rtn.isExist = true;
}
return rtn;
}
//具体某个应用内检查同名,添加公司信息的校验,具体针对具体某个应用用户
//具体某个非平台应用的用户具有owner_id的公司信息
//每个在平台登录的用户,先查询出,查看身份是否是租户,如果是
//如果是pass,那么就查询出
async checkSameNameWithCompany(uname, appid,compid, t) {
var ac = await this.dao.model.findOne({ where: { userName: uname, app_id: appid,owner_id:compid}, transaction: t });
var rtn = { isExist: false };
if (ac) {
rtn.isExist = true;
}
return rtn;
}
//为租户创建具体某个应用的管理员
async createAdminUser(pobj) {
var u = { userName: pobj.userName, password: pobj.password, app_id: pobj.app_id, mobile: pobj.mobile,owner_id:pobj.owner_id,tanentor_id:pobj.tanentor_id};
var rtn = await this.registerAppAdmin(u);
return rtn;
}
//为租户创建具体某个应用的管理员,不需要加密码
async registerAppAdmin(fmuser) {
var self = this;
fmuser.isAdmin = true;
return this.db.transaction(async function (t) {
var sameNameData = await self.checkSameNameWithCompany(fmuser.userName, fmuser.app_id,fmuser.owner_id, t);
if (!sameNameData.isExist) {
if (!fmuser.nickName || fmuser.nickName == "") {
fmuser.nickName = fmuser.userName;
}
//管理员的默认路径设置为/
fmuser.opath="/";
fmuser.ppath="/";
var cruser = await self.dao.create(fmuser, t);
//按照手机号去查询account,如果没有就创建
var ac = await self.accountDao.findOne({ mobile: cruser.mobile });
if (!ac) {
var acnew = await self.accountDao.create(fmuser, t);
await cruser.setAccount(acnew, { transaction: t });
} else {
await cruser.setAccount(ac, { transaction: t });
}
return cruser;
} else {
return null;
if(rtn.statusCode==201){
return rtn.data;
}
});
}
async queryUsersByAppId(appid){
var userlist=await this.dao.model.findAll({where:{app_id:appid},attributes:{exclude: ['password']}});
return userlist;
}
async createUser(pobj) {
var u = {
userName: pobj.userName,
nickName:pobj.nickName,
password: settings.defaultpwd,
app_id: pobj.appid,
mobile: pobj.mobile,
owner_id:pobj.owner_id,
tanentor_id:pobj.tanentor_id,
org_id:pobj.org_id
};
var rtn = await this.registerCommon(u);
return rtn;
return null;
}catch(e){
return null;
}
}
//租户公司管理员创建普通用户
async registerCommon(fmuser) {
var self = this;
fmuser.password = await super.getEncryptStr(fmuser.password);
return this.db.transaction(async function (t) {
//按照org_id,查询出角色,给当前用户设置角色,查询出是否是主岗
var orgcurrent=await self.db.models.org.findOne({
where:{id:fmuser.org_id},transaction:t,
include:[
{model:self.db.models.role,as:"roles",attributes:['id','code','name']},
]});
if(orgcurrent.isMain){//如果是主岗
fmuser.opath=orgcurrent.orgpath;
var n=orgcurrent.orgpath.lastIndexOf("/");
fmuser.ppath=orgcurrent.orgpath.substring(0,n);
}else{
fmuser.opath=orgcurrent.orgpath;
fmuser.ppath= fmuser.opath;
}
var sameNameData = await self.checkSameName(fmuser.userName, fmuser.app_id, t);
if (!sameNameData.isExist) {
if (!fmuser.nickName || fmuser.nickName == "") {
fmuser.nickName = fmuser.userName;
}
var cruser = await self.dao.create(fmuser, t);
//创建jwt身份凭证
async cbindcredential(uname){
//按照手机号去查询account,如果没有就创建
var ac = await self.accountDao.findOne({ mobile: cruser.mobile });
if (!ac) {
var acnew = await self.accountDao.create(fmuser, t);
await cruser.setAccount(acnew, { transaction: t });
} else {
await cruser.setAccount(ac, { transaction: t });
}
await cruser.setRoles(orgcurrent.roles, { transaction: t });
var rtnu=await self.dao.model.findOne({
where:{id:cruser.id},transaction:t,
include: [
{ model: self.db.models.role, as: "Roles", attributes: ["id", "code"] },
{ model: self.db.models.company,include:[self.db.models.app]},
{ model: self.db.models.company,as:"owner"},
{ model: self.db.models.user,as:"tanentor",include:[
{ model: self.db.models.company,include:[self.db.models.app]},
]},
],
});
//创建一个平台非租户用户,角色是pass,登录时,路过角色
//先去检查是否已经存在,按照用户名,密码,电话,app_id=1,如果不存在
//就创建,如果存在了
var passuser=await self.dao.model.findOne({
where:{
userName:fmuser.userName,
password:fmuser.password,
mobile:fmuser.mobile,
app_id:settings.platformid
},transaction:t
});
if(!passuser){
var ptpassuser={
userName:fmuser.userName,
nickName:fmuser.userName,
password:fmuser.password,
mobile:fmuser.mobile,
account_id:rtnu.account_id,
owner_id:settings.platformcompanyid,
tanentor_id:rtnu.tanentor_id,
app_id:settings.platformid
};
passuser=await self.dao.create(ptpassuser,t);
//查询出路过角色,设置路过角色
var passrole=await self.db.models.role.findById(settings.passroleid);
await passuser.setRoles([passrole],{transaction:t});
//查询出相关租户所关联的公司
var cmps=rtnu.tanentor.companies;
var comfinds=cmps.find((item)=>{
return item.usercompany.isCurrent==true;
});
await passuser.addCompanies(cmps,{transaction:t});
var up2=await self.db.models.usercompany.update({isCurrent:true},{where:{user_id:passuser.id,company_id:comfinds.id},transaction:t});
}
return rtnu;
} else {
return null;
}
});
}
async register(fmuser) {
var self = this;
fmuser.password = await super.getEncryptStr(fmuser.password);
return this.db.transaction(async function (t) {
var sameNameData = await self.checkSameName(fmuser.userName, fmuser.app_id, t);
if (!sameNameData.isExist) {
if (!fmuser.nickName || fmuser.nickName == "") {
fmuser.nickName = fmuser.userName;
}
var cruser = await self.dao.create(fmuser, t);
//按照手机号去查询account,如果没有就创建
var ac = await self.accountDao.findOne({ mobile: cruser.mobile });
if (!ac) {
var acnew = await self.accountDao.create(fmuser, t);
await cruser.setAccount(acnew, { transaction: t });
} else {
await cruser.setAccount(ac, { transaction: t });
}
//设置默认普通角色,由于有了租户概念,所以注册时,需要知道当前租户和应用的id 才可以设置默认角色 todo
// var role = await self.roleDao.model.findOne({ where: { code: "common" }, transaction: t });
// await cruser.setRoles([role], { transaction: t });
// }
//如果是平台应用,那么注册时需要关联蜂擎默认公司,添加默认的common角色
if(settings.platformid==cruser.app_id){
await self.db.models.usercompany.create({user_id:cruser.id,company_id:settings.platformcompanyid,isCurrent:true},{transaction:t});
var role = await self.roleDao.model.findOne({ where: { code: "common",company_id: settings.platformcompanyid,app_id:settings.platformid}, transaction: t });
await cruser.setRoles([role], { transaction: t });
//删除统一账号
async cunregister(uname){
try{
let rtn=await system.delReq(settings.kongurl+"consumers/"+uname)
if(rtn.statusCode==204){
return {};
}
var rtnu=await self.dao.model.findOne({
where:{id:cruser.id},transaction:t,
include: [
{ model: self.db.models.role, as: "Roles", attributes: ["id", "code"] },
{ model: self.db.models.company,include:[self.db.models.app]},
{ model: self.db.models.company,as:"owner"},
{ model: self.db.models.user,as:"tanentor"},
],
});
return rtnu;
} else {
return null;
}catch(e){
return null;
}
});
}
}
async modifyPassword(p) {
p.password = await super.getEncryptStr(p.password);
var setObj = {
password: p.password
};
var whereObj = {
where: {account_id: p.account_id}
};
//登录统一账号
async clogin(uname){
//检查是否存在重名
await this.dao.updateByWhere(setObj, whereObj);
return system.getResultSuccess();
}
async getUserByUserNamePwdForApi(u) {
//勇于从别的应用中,点击页面连接,跳转到平台应用中进行管理
u.password = await super.getEncryptStr(u.password);
var user=null;
if(u.app_id==settings.platformid){
user = await this.dao.model.findOne({
where: { userName: u.userName, password: u.password, app_id: u.app_id },
include: [
{ model: this.db.models.role, as: "Roles", attributes: ["id", "code"] },
{ model: this.db.models.company,include:[this.db.models.app]},
{ model: this.db.models.company,as:"owner"},
{ model: this.db.models.user,as:"tanentor"},
]
});
}else{
user = await this.dao.model.findOne({
where: {userName: u.userName, password: u.password, app_id: u.app_id},
include: [
{ model: this.db.models.company,include:[this.db.models.app]},
]
});
}
return user;
}
async checkWxBind(u){
var user = await this.dao.model.findOne({where: {wxopenid: u.openid, app_id: u.app_id}});
return user;
}
async getUserByUserNamePwd(u) {
//勇于从别的应用中,点击页面连接,跳转到平台应用中进行管理
if(!u.isNavto){
u.password = await super.getEncryptStr(u.password);
}
var user=null;
if(u.app_id==settings.platformid){
user = await this.dao.model.findOne({
where: { userName: u.userName, password: u.password, app_id: u.app_id },
include: [
{ model: this.db.models.role, as: "Roles", attributes: ["id", "code"] },
{ model: this.db.models.company,include:[this.db.models.app]},
{ model: this.db.models.company,as:"owner"},
{ model: this.db.models.user,as:"tanentor"},
]
});
}else{
user = await this.dao.model.findOne({
where: {userName: u.userName, password: u.password, app_id: u.app_id,owner_id:u.owner_id},
include: [
{ model: this.db.models.role, as: "Roles", attributes: ["id", "code"] },
{ model: this.db.models.company,include:[this.db.models.app]},
{ model: this.db.models.company,as:"owner"},
]
});
}
return user;
}
async wxBind(u) {
var self=this;
return this.db.transaction(async function (t) {
var user = await self.dao.model.findOne({where: { mobile: u.mobile,app_id: u.app_id }});
if(!user){
return null;
}else{
user.wxopenid=u.openid;
await user.save();
return user;
}
});
}
//按用户名查询统一用户
async findCUser(uname){
async getUserByUserMobile(u) {
//勇于从别的应用中,点击页面连接,跳转到平台应用中进行管理
var user = await this.dao.model.findOne({
where: { mobile: u.mobile,app_id: u.app_id },
include: [
{ model: this.db.models.role, as: "Roles", attributes: ["id", "code"] },
]
});
return user;
}
}
module.exports = UserService;
// var task=new UserService();
// task.getUserStatisticGroupByApp().then(function(result){
// console.log((result));
// }).catch(function(e){
// console.log(e);
// });
(async ()=>{
let u=new UserService();
// let x=await u.cregister("jiangong")
// console.log(x)
// let x=await u.cunregister("jiangong")
// console.log(x)
})()
\ No newline at end of file
const system = require("../../../system");
const ServiceBase = require("../../sve.base");
const settings = require("../../../../config/settings");
const uiconfig = system.getUiConfig2(settings.appKey);
const appconfig = system.getSysConfig();
class AppService extends ServiceBase {
constructor() {
super("common", ServiceBase.getDaoName(AppService));
......
var fs = require("fs");
var objsettings = require("../config/objsettings");
var settings = require("../config/settings");
const request = require('request');
class System {
static declare(ns) {
var ar = ns.split('.');
......@@ -15,6 +16,98 @@ class System {
}
}
}
static async delReq(url,qdata){
let rtn={}
let promise=new Promise(function(resv,rej){
request.del({
url: url,
qs: qdata
}, function(error, response, body) {
rtn.statusCode=response.statusCode
if (!error) {
if(body){
let data=JSON.parse(body)
rtn.data=data
}else{
rtn.data=null
}
resv(rtn);
}else{
rej(error)
}
});
})
return promise;
}
static async getReq(url,qdata){
let promise=new Promise(function(resv,rej){
request.get({
url: url,
qs: qdata
}, function(error, response, body) {
if (!error && response.statusCode == 200) {
resv(body);
}else{
rej(error)
}
});
})
return promise;
}
static async postJsonTypeReq(url,data){
let promise=new Promise(function(resv,rej){
request({
url: url,
method: "POST",
json: true,
headers: {
"content-type": "application/json",
},
body: JSON.stringify(data)
}, function(error, response, body) {
if (!error && response.statusCode == 200) {
resv(body);
}else{
rej(error)
}
});
})
return promise;
}
static async post3wFormTypeReq(url,data){
let rtn={}
let promise=new Promise(function(resv,rej){
request.post({
url: url,
form: data
}, function(error, response, body) {
rtn.statusCode=response.statusCode
if (!error) {
let data=JSON.parse(body)
rtn.data=data
resv(rtn);
}else{
rej(error)
}
});
})
return promise;
}
static async postMpFormTypeReq(url,formdata){
let promise=new Promise(function(resv,rej){
request.post({
url: url,
formData: formdata
}, function(error, response, body) {
if (!error && response.statusCode == 200) {
resv(body);
}else{
rej(error)
}
});
})
return promise;
}
static register(key, ClassObj,groupName,filename) {
if (System.objTable[key] != null) {
throw new Error("相同key的对象已经存在");
......@@ -108,15 +201,8 @@ class System {
return System.register(objabspath, ClassObj,groupName,filename);
}
}
static getUiConfig(appid) {
var configPath = settings.basepath + "/app/base/db/metadata/" + appid + "/index.js";
if (settings.env == "dev") {
delete require.cache[configPath];
}
var configValue = require(configPath);
return configValue;
}
static getUiConfig2(appid) {
static getSysConfig() {
var configPath = settings.basepath + "/app/base/db/metadata/index.js";
// if(settings.env=="dev"){
// console.log("delete "+configPath+"cache config");
......@@ -124,7 +210,7 @@ class System {
// }
delete require.cache[configPath];
var configValue = require(configPath);
return configValue[appid];
return configValue.config;
}
static get_client_ip(req) {
var ip = req.headers['x-forwarded-for'] ||
......@@ -140,6 +226,7 @@ class System {
}
};
}
Date.prototype.Format = function (fmt) { //author: meizz
var o = {
......@@ -189,3 +276,12 @@ System.verifyOpencodeFail = 2040;
//重复操作
System.redoFail = 2050;
module.exports = System;
// (async ()=>{
// try{
// let d=await System.getReq("http://127.0.0.1:8001x/services")
// console.log(d)
// }catch(e){
// console.log(e);
// }
// })()
\ No newline at end of file
......@@ -6,11 +6,11 @@ var settings = {
db: 9,
},
database: {
dbname: "paas",
user: "write",
password: "write",
dbname: "center-manage",
user: "root",
password: "123456",
config: {
host: '192.168.18.237',
host: '192.168.4.119',
port: 3306,
dialect: 'mysql',
operatorsAliases: false,
......
var path= require('path');
var basepath=path.normalize(path.join(__dirname, '../..'));
var settings = {
webbase:path.join(basepath,"app/base/controller/ctl.base.js")
webbase:path.join(basepath,"app/base/controller/ctl.base.js"),
web:path.join(basepath,"app/base/controller/impl"),
apibase:path.join(basepath,"app/base/api/api.base.js"),
api:path.join(basepath,"app/base/api/impl"),
......
......@@ -17,6 +17,7 @@ var settings = {
defaultpwd:"987456",
basepath : path.normalize(path.join(__dirname, '../..')),
port : process.env.NODE_PORT || 4001,
kongurl:"http://127.0.0.1:8001/",
redis:function(){
if(this.env=="dev"){
var localsettings=require("./localsettings");
......
......@@ -31,3 +31,4 @@ var server = http.createServer(app);
server.listen(setttings.port, function(){
console.log('Express server listening on port ' + app.get('port'));
});
{
"name": "bigdata",
"name": "center-manage",
"version": "1.0.0",
"description": "h5framework",
"main": "main.js",
......@@ -10,6 +10,7 @@
"license": "ISC",
"dependencies": {
"@alicloud/pop-core": "^1.7.7",
"MD5": "^1.3.0",
"after": "^0.8.2",
"ali-oss": "^4.12.2",
"babel-polyfill": "^6.26.0",
......@@ -24,7 +25,6 @@
"crypto-js": "^3.1.9-1",
"easyimage": "^3.1.0",
"ejs": "^2.5.8",
"element-ui": "^2.4.0",
"engine.io-parser": "^2.1.2",
"errorhandler": "^1.5.0",
"exceljs": "^1.6.3",
......@@ -34,16 +34,13 @@
"gm": "^1.23.1",
"log4js": "^2.10.0",
"method-override": "^2.3.10",
"mongoose": "^5.3.6",
"morgan": "^1.9.0",
"multer": "^1.3.0",
"mysql2": "^1.5.3",
"node-cron": "^2.0.1",
"node-uuid": "^1.4.8",
"node-wxpay": "^1.1.3",
"pdfcrowd": "^4.2.0",
"pinyin": "^2.8.3",
"puppeteer": "^1.8.0",
"qr-image": "^3.2.0",
"sequelize": "^4.37.8",
"sequelize-cli": "^4.1.1",
......@@ -51,14 +48,10 @@
"sha1": "^1.1.1",
"socket.io": "^2.1.1",
"uuid": "^3.2.1",
"weixin-pay": "^1.1.7",
"wx-pay": "^1.0.2",
"xml2js": "^0.4.19"
},
"devDependencies": {
"del": "^5.1.0",
"element-theme": "^2.0.1",
"element-theme-chalk": "^2.4.0",
"gulp-concat": "^2.6.1",
"gulp-if": "^3.0.0",
"gulp-imagemin": "^6.2.0",
......
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