Commit 11606669 by 王昆

gsb

parent 183dec7c
......@@ -6,8 +6,9 @@ class TradeCtl extends CtlBase {
this.tradeSve = system.getObject("service.trade.tradeSve");
}
async parseItem(params, pobj2, req) {
async parseItems(params, pobj2, req) {
try {
params.fileName = req.loginUser.id;
return await this.tradeSve.parseItems(params);
} catch (error) {
return system.getResult(null, `系统错误 错误信息 ${error}`);
......
......@@ -3,49 +3,77 @@ const ServiceBase = require("../../svems.base");
const settings = require("../../../../config/settings");
const fs = require("fs");
const xlsx = require('node-xlsx');
const axios = require("axios");
const path = require("path");
class TradeService extends ServiceBase {
constructor() {
super();
this.businessmenSve = system.getObject("service.business.businessmenSve");
this.merchantSve = system.getObject("service.saas.merchantSve");
}
async downloadFile(url, filePath) {
let writer = fs.createWriteStream(filePath);
let response = await axios({
url,
method: "GET",
responseType: "stream",
});
response.data.pipe(writer);
return new Promise((resolve, reject) => {
writer.on("finish", resolve);
writer.on("error", reject);
});
async parseItems(params) {
// 读取excel
let dataList = await this.readItems(params.fileUrl, params.fileName);
// 验证字段
let error = await this.checkDataList(dataList);
// 计算预计付款基恩
let result = await this.countAmt(dataList, params.saas_merchant_id);
// 封装返回对象
result.error = error;
result.dataList = dataList;
return system.getResultSuccess(result);
}
async countAmt(dataList, saas_merchant_id) {
let result = {actual_amt:0, deduct_amt:0, service_tax:0};
if(!dataList) {
return result;
}
async parseItems(params) {
// 获取商户签约信息
let info = await this.merchantSve.signInfo({id: saas_merchant_id}) || {};
info = info.data || {};
// 服务费,这里已经处理了分转元,不用在处理
let service_rate = info.trans_service_rate;
// 实发总数
let totalAmt = 0;
for (let data of dataList) {
totalAmt = totalAmt + Number(data.amt || 0);
}
// 服务费
result.service_tax = parseFloat((totalAmt * service_rate) / 100).toFixed(2);
// 总实发
result.actual_amt = parseFloat(totalAmt).toFixed(2);
// 总扣款
result.deduct_amt = parseFloat(Number(result.actual_amt) + Number(result.service_tax)).toFixed(2);
return result;
}
async readItems(fileUrl, fileName) {
let dataList = [];
let filePath = settings.localpath() + "saas_xgg_trade_order_" + this.trim(params.fileName) + ".xlsx";
let filePath = settings.localpath() + "saas_xgg_trade_order_" + this.trim(fileName) + ".xlsx";
try {
await this.downloadFile(params.url, filePath);
// await this.restClient.execDownload("'" + ossurl + "'", filePath);
// await this.downloadFile(params.url, filePath);
await this.restClient.execDownload2(fileUrl, filePath);
let sheets = xlsx.parse(filePath);
fs.unlinkSync(filePath);
if(!sheets || sheets.length == 0) {
if (!sheets || sheets.length == 0) {
return system.getResult(null, "打款文件无数据")
}
let sheet = sheets[0];
if(!sheet || !sheet.data || sheet.data.length == 0) {
if (!sheet || !sheet.data || sheet.data.length == 0) {
return system.getResult(null, "打款文件无数据")
}
let rows = sheet.data;
let dataList = [];
for (let idx = 6; idx < rows.length; idx ++) {
for (let idx = 6; idx < rows.length; idx++) {
var data = {
errors: []
};
......@@ -53,10 +81,10 @@ class TradeService extends ServiceBase {
let cells = rows[idx];
let cellLength = cells.length;
if(cellLength == 0) {
if (cellLength == 0) {
continue;
}
if(cellLength < 7) {
if (cellLength < 7) {
data.errors.push("缺少数据, 列数不全");
continue;
}
......@@ -69,7 +97,7 @@ class TradeService extends ServiceBase {
dataList.push(data);
}
return await this.checkDataList(dataList);
return dataList;
} catch (error) {
console.log(error);
return system.getResult(null, "excel解析出错")
......@@ -77,10 +105,8 @@ class TradeService extends ServiceBase {
}
async checkDataList(dataList) {
let result = {
hasError: false,
};
if(!dataList || dataList.length == 0) {
let error = false;
if (!dataList || dataList.length == 0) {
return system.getResult(null, "打款文件无数据")
}
......@@ -91,49 +117,49 @@ class TradeService extends ServiceBase {
}
let creditCodeMap = await this.businessmenSve.mapByCreditCodes({creditCodes: creditCodes, attrs: "credit_code"});
for (let data of dataList) {
this.checkField(data, "acc_name", {is_require: true, maxLen: 64});
this.checkField(data, "acc_name", {name: "收款户名", is_require: true, maxLen: 64});
let bm = creditCodeMap[data.credit_code];
if(!bm) {
if (!bm) {
data.errors.push(`统一社会信用代码[${data.credit_code}]不存在`);
}
this.checkField(data, "credit_code", {is_require: true, eqLen: 18});
this.checkField(data, "acc_no", {is_require: true, maxLen: 30, is_number:true});
this.checkField(data, "open_bank", {maxLen: 100});
this.checkField(data, "amt", {is_require: true, maxLen: 100, is_number:true});
this.checkField(data, "remark", {maxLen: 100});
this.checkField(data, "credit_code", {name: "个体户统一信用代码", is_require: true, eqLen: 18});
this.checkField(data, "acc_no", {name: "收款账号", is_require: true, maxLen: 30, is_number: true});
this.checkField(data, "open_bank", {name: "开户银行全称", maxLen: 100});
this.checkField(data, "amt", {name: "商户请求打款金额", is_require: true, maxLen: 100, is_number: true});
this.checkField(data, "remark", {name: "备注", maxLen: 100});
if(!result.hasError && data.errors.length > 0) {
result.hasError = true;
if (!error && data.errors.length > 0) {
error = true;
}
}
result.dataList = dataList;
return result;
return error;
}
checkField(data, field, rule) {
if(!data || !field) {
if (!data || !field) {
return;
}
let v = data[field];
if(rule.is_require && !v) {
if (rule.is_require && !v) {
data.errors.push(`${rule.name}未填写`);
}
if(rule.maxLen && v.length > rule.maxLen) {
if (rule.maxLen && v.length > rule.maxLen) {
data.errors.push(`${rule.name}长度不允许超过${rule.maxLen}`);
}
if(rule.minLen && v.length < rule.minLen) {
if (rule.minLen && v.length < rule.minLen) {
data.errors.push(`${rule.name}长度不允许少于${rule.minLen}`);
}
if(rule.eqLen && v.length != rule.eqLen) {
if (rule.eqLen && v.length != rule.eqLen) {
data.errors.push(`${rule.name}长度为${rule.eqLen}`);
}
if(rule.is_number && isNaN(v)) {
if (rule.is_number && isNaN(v)) {
data.errors.push(`${rule.name}需要填写数字类型`);
}
if(rule.is_number && isNaN(v)) {
if (rule.is_number && isNaN(v)) {
data.errors.push(`${rule.name}需要填写数字类型`);
}
}
}
module.exports = TradeService;
\ No newline at end of file
......@@ -170,27 +170,27 @@ class System {
var path = "/api/op/action/springboard";
if (settings.env == "dev") {
// var domain = "http://192.168.18.237";
var domain = "http://127.0.0.1";
var domain2 = "http://39.107.234.14";
let local = "http://127.0.0.1";
let dev = "http://39.107.234.14";
return {
// 公共服务
common: domain2 + ":3102" + path,
common: dev + ":3102" + path,
// common: "http://127.0.0.1:3102" + path,
// 商户服务
merchant: domain2 + ":3101" + path,
merchant: dev + ":3101" + path,
// merchant: "http://127.0.0.1:3101" + path,
// 订单服务
order: domain2 + ":3103" + path,
order: dev + ":3103" + path,
// order: "http://127.0.0.1:3103" + path,
// 发票服务
invoice: domain2 + ":3105" + path,
invoice: dev + ":3105" + path,
// invoice: "http://127.0.0.1:3105" + path,
// 用户服务
uc: domain2 + ":3106" + path,
uc: dev + ":3106" + path,
// uc: "http://127.0.0.1:3106" + path,
}
} else {
......
......@@ -3,6 +3,8 @@ const util = require('util');
const exec = util.promisify(require('child_process').exec);
const querystring = require('querystring');
var settings = require("../../config/settings");
const fs = require("fs");
const axios = require("axios");
class RestClient {
constructor() {
this.cmdGetPattern = "curl {-G} -k -d '{data}' {url}";
......@@ -68,6 +70,20 @@ class RestClient {
var result = await this.exec(cmd);
return result;
}
async execDownload2(url, outfname) {
let writer = fs.createWriteStream(outfname);
let response = await axios({
url,
method: "GET",
responseType: "stream",
});
response.data.pipe(writer);
return new Promise((resolve, reject) => {
writer.on("finish", resolve);
writer.on("error", reject);
});
}
async execGet(subData, url) {
let cmd = this.FetchGetCmd(subData, url);
var result = await this.exec(cmd);
......
......@@ -19,6 +19,9 @@
## 订单管理
  1 [订单接口](/doc/saas/order.md)
## 交易管理
  1 [交易接口](/doc/saas/trade.md)
## 小程序接口
  1 [登录](/doc/applet/login.md)
......
<a name="menu">目录</a>
1. [批量打款列表](#page)
1. [上传数据](#parseItems)
1. [锁定批次](#add)
1. [付款申请](#payVoucher)
## **<a name="page"> 订单列表</a>**
[返回到目录](#menu)
##### URL
[/web/saas/orderCtl/page]
#### 参数格式 `JSON`
#### HTTP请求方式 `POST`
``` javascript
订单状态 下拉筛选
1010 待付款,
2010 待审核,
2030 审核驳回,
3010 业务办理中,
3020 待交付,
3030 已交付
{
"currentPage": "1",
"pageSize": "10",
"saas_merchant_id": "", // 商户id 查询条件使用商户字典下拉选择
"createBegin": "", // 创建时间 开始
"createEnd": "" // 创建时间 结束
"legal_idno": "" // 身份证号码
"status": "" // 订单状态
}
```
#### 返回结果
```javascript
{
"status": 0,
"msg": "success",
"data": {
"count": 0,
"rows": [
{
"id": "1726724188001516", // 订单编号
"price": 1500, // 订单价格
"pay_voucher_img": "0", // 付款凭证
"audit_remark": "", // 审核凭证
"deliver_man": "", // 交付联系人
"deliver_mobile": "", // 交付联系电话
"deliver_addr": "", // 邮寄地址
"created_at": "2020-03-21 07:45:18", // 创建时间
"status": "3030", // 订单状态
"status_name": "已交付" // 订单状态名称
// 订单信息
"bminfo": {
"idcard_front": "11111", // 身份证正面
"idcard_back": "11111", // 身份证反面
"legal_name": "11111", // 法人名称
"legal_mobile": "11111", // 手机号
"legal_idno": "11111", // 身份证号码
"company_names": "11111", // 个体户名称
"bank_front": "11111", // 银行卡正面图
"bank_back": "11111", // 银行卡反面图
"bank_name": "11111", // 开户行
"bank_no": "11111", // 银行卡号
"bank_mobile": "11111", // 预留手机号
"domicile_id": "", // 注册地id
"domicile_name": "", // 注册地
"business_scope_id": "", // 经营范围id
"business_type": "", // 经营范围类型
"business_scope": "", // 经营范围详情
}
}
],
"total": 1
},
"requestid": "00521a0a0f094c8d982bf4375fbe91b1"
}
```
1. [上传数据](#parseItems)
## **<a name="parseItems"> 上传数据</a>**
[返回到目录](#menu)
##### URL
[/web/trade/tradeCtl/parseItems]
#### 参数格式 `JSON`
#### HTTP请求方式 `POST`
``` javascript
{
"id": "1726882554002859" // 订单id
}
```
#### 返回结果
```javascript
{
"status": 0,
"msg": "success",
"data": {
// 基本剑术
"baseInfo": {
"id": "1726882554002859", // 订单编号
"created_at": "2020-03-23 03:44:44", // 创建时间
"price": 1500 // 价格
},
// 注册申请信息
"regInfo": {
"legal_name": "11111", // 法人
"legal_idno": "11111", // 身份证号码
"legal_mobile": "11111", // 联系电话
"company_names": "11111", // 个体户名称
"idcard_front": "11111", // 身份证图正面
"idcard_back": "11111" // 身份证图反面
},
// 商户交付信息
"merchantDeliverInfo": {
"merchant_deliver_man": "", // 联系人
"merchant_deliver_mobile": "", // 联系电话
"merchant_deliver_addr": "" // 邮寄地址
},
// 支付信息
"payInfo": {
"amount": 0, // 付款金额
"created_at": "2020-03-23", // 支付时间
"trade_no": "1123123", // 资金流水号
"pay_voucher_img": "123213" // 付款凭证
},
// 订单交付信息
"deliverInfo": {
"deliver_express_no": "", // 快递单号
"deliver_express_img": "" // 交接单
},
},
"requestid": "b46e1ff5176143ffa4135a357f93d757"
}
```
## **<a name="checkPay"> 支付验证</a>**
[返回到目录](#menu)
##### URL
[/web/saas/orderCtl/checkPay]
#### 参数格式 `JSON`
#### HTTP请求方式 `POST`
``` javascript
{
"ids": ['172...', '172..', ''], // 订单多选
}
```
#### 返回结果
```javascript
{
"status": 0,
"msg": "操作成功",
"data": {
"totalNum": 3, // 共 XX 笔订单
"totalPrice": 4500, // 应付金额 元
"account_name": "扬大", // 账户名称
"account_bank_name": "中国银行", // 开户银行
"account_bank_no": "222" // 银行账户
},
"bizmsg": "empty"
}
```
## **<a name="offlinePay"> 订单支付</a>**
[返回到目录](#menu)
##### URL
[/web/saas/orderCtl/offlinePay]
#### 参数格式 `JSON`
#### HTTP请求方式 `POST`
``` javascript
{
"ids": ['172...', '172..', ''], // 订单多选
"pay_voucher_img": "", // 付款凭证图
"merchant_deliver_man": "", // 联系人
"merchant_deliver_mobile": "", // 联系电话
"merchant_deliver_addr": "" // 邮寄地址
}
```
#### 返回结果
```javascript
{
"status": 0,
"msg": "success",
"data": null,
"requestid": "b46e1ff5176143ffa4135a357f93d757"
}
```
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