小程序发货信息录入
This commit is contained in:
parent
bb3fe6cd49
commit
2692e2d6fc
|
|
@ -7,7 +7,6 @@ export type AspectDict<ED extends EntityDict> = {
|
||||||
withdrawAccountId?: string;
|
withdrawAccountId?: string;
|
||||||
}, context: BackendRuntimeContext<ED>) => Promise<EntityDict['withdraw']['CreateSingle']['data']>;
|
}, context: BackendRuntimeContext<ED>) => Promise<EntityDict['withdraw']['CreateSingle']['data']>;
|
||||||
getMpShipState: (params: {
|
getMpShipState: (params: {
|
||||||
depositId?: string;
|
shipId: string;
|
||||||
orderId?: string;
|
|
||||||
}, context: BackendRuntimeContext<ED>) => Promise<EntityDict['ship']['Schema']['iState']>;
|
}, context: BackendRuntimeContext<ED>) => Promise<EntityDict['ship']['Schema']['iState']>;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,5 @@ import { BRC } from '../types/RuntimeCxt';
|
||||||
* @param context
|
* @param context
|
||||||
*/
|
*/
|
||||||
export declare function getMpShipState(params: {
|
export declare function getMpShipState(params: {
|
||||||
depositId?: string;
|
shipId: string;
|
||||||
orderId?: string;
|
|
||||||
}, context: BRC): Promise<string | null | undefined>;
|
}, context: BRC): Promise<string | null | undefined>;
|
||||||
|
|
|
||||||
|
|
@ -8,30 +8,8 @@ export async function getMpShipState(params, context) {
|
||||||
const application = context.getApplication();
|
const application = context.getApplication();
|
||||||
const { type, } = application;
|
const { type, } = application;
|
||||||
if (type === 'wechatMp') {
|
if (type === 'wechatMp') {
|
||||||
const { depositId, orderId } = params;
|
const { shipId } = params;
|
||||||
if (depositId) {
|
const shipState = await getShipState(context, shipId);
|
||||||
//充值
|
return shipState;
|
||||||
const deposits = await context.select('deposit', {
|
|
||||||
data: {
|
|
||||||
id: 1,
|
|
||||||
iState: 1,
|
|
||||||
shipId: 1,
|
|
||||||
ship: {
|
|
||||||
id: 1,
|
|
||||||
iState: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
filter: {
|
|
||||||
id: depositId,
|
|
||||||
}
|
|
||||||
}, {});
|
|
||||||
const deposit = deposits[0];
|
|
||||||
if (deposit) {
|
|
||||||
const shipState = await getShipState(context, deposit);
|
|
||||||
return shipState;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (orderId) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,10 @@ export default OakComponent({
|
||||||
},
|
},
|
||||||
isList: false,
|
isList: false,
|
||||||
properties: {
|
properties: {
|
||||||
accountId: '', // 是否可以使用帐户中的余额抵扣
|
accountId: '',
|
||||||
accountAvailMax: 0, // 本次交易可以使用的帐户中的Avail max值,调用者自己保证此数值的一致性,不要扣成负数
|
accountAvailMax: 0,
|
||||||
onSetPays: (pays) => undefined,
|
onSetPays: (pays) => undefined,
|
||||||
accountTips: '', // 使用余额支付的提示说明
|
accountTips: '',
|
||||||
autoStartPay: false,
|
autoStartPay: false,
|
||||||
},
|
},
|
||||||
formData({ data }) {
|
formData({ data }) {
|
||||||
|
|
|
||||||
|
|
@ -369,7 +369,7 @@ export default OakComponent({
|
||||||
async success() {
|
async success() {
|
||||||
console.log('success');
|
console.log('success');
|
||||||
const mpShipState = await this.features.cache.exec('getMpShipState', {
|
const mpShipState = await this.features.cache.exec('getMpShipState', {
|
||||||
depositId,
|
shipId: next.shipId,
|
||||||
});
|
});
|
||||||
if (mpShipState === 'received') {
|
if (mpShipState === 'received') {
|
||||||
this.setMessage({
|
this.setMessage({
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ const triggers = [
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// todo,应该是所有的ship
|
// todo,deposit的ship和 shipClazz中有配置wechatShip且可获取openId的order的ship
|
||||||
entity: 'ship',
|
entity: 'ship',
|
||||||
name: '当虚拟的ship变为shipping状态时,调用小程序发货信息录入接口',
|
name: '当虚拟的ship变为shipping状态时,调用小程序发货信息录入接口',
|
||||||
action: 'ship',
|
action: 'ship',
|
||||||
|
|
@ -77,21 +77,45 @@ const triggers = [
|
||||||
data: {
|
data: {
|
||||||
id: 1,
|
id: 1,
|
||||||
},
|
},
|
||||||
indexFrom: 0,
|
},
|
||||||
count: 1,
|
entity: 1,
|
||||||
|
entityId: 1,
|
||||||
|
shipServiceId: 1,
|
||||||
|
shipOrder$ship: {
|
||||||
|
$entity: 'shipOrder',
|
||||||
|
data: {
|
||||||
|
id: 1,
|
||||||
|
orderId: 1,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
wechatMpShip: {
|
||||||
|
id: 1,
|
||||||
|
applicationId: 1,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
filter,
|
filter,
|
||||||
}, {});
|
}, {});
|
||||||
const { type, deposit$ship: deposits } = ship || {};
|
const { id: shipId, type, deposit$ship: deposits, shipOrder$ship, shipServiceId, entity, entityId, wechatMpShip } = ship || {};
|
||||||
if (type === 'virtual') {
|
if (deposits && deposits.length > 0) {
|
||||||
const deposit = deposits?.[0];
|
//充值 (此时该充值必定为受发货限制的小程序上的充值)
|
||||||
//当已发货的订单再次调用小程序发货信息录入接口视为重新发货(仅可重新发货一次)
|
|
||||||
//发货前先查询,检查是否为未同步微信端发货状态
|
//发货前先查询,检查是否为未同步微信端发货状态
|
||||||
const shipState = await getShipState(context, deposit);
|
const shipState = await getShipState(context, shipId);
|
||||||
if (shipState === 'unshipped') {
|
if (shipState === 'unshipped') {
|
||||||
const result = await uploadShippingInfo({ depositId: deposit?.id, }, context);
|
await uploadShippingInfo(shipId, context);
|
||||||
if (result) {
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (shipOrder$ship && shipOrder$ship.length > 0) {
|
||||||
|
//订单
|
||||||
|
const clazz = await getShipClazz(entity, entityId, context);
|
||||||
|
const { openId } = await clazz.getReceiverInfo(shipOrder$ship.map((ele) => ele.orderId), wechatMpShip?.applicationId, context);
|
||||||
|
if (openId) {
|
||||||
|
//当存在openId时调用小程序发货信息录入
|
||||||
|
const shipState = await getShipState(context, shipId);
|
||||||
|
//当已发货的订单再次调用小程序发货信息录入接口视为重新发货(仅可重新发货一次)
|
||||||
|
if (shipState && ['unshipped', 'shipping'].includes(shipState)) {
|
||||||
|
// 发货/更换发货
|
||||||
|
await uploadShippingInfo(shipId, context);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -203,7 +227,7 @@ const triggers = [
|
||||||
if (packaged.length > 0) {
|
if (packaged.length > 0) {
|
||||||
await context.operate('order', {
|
await context.operate('order', {
|
||||||
id: await generateNewIdAsync(),
|
id: await generateNewIdAsync(),
|
||||||
action: 'ship',
|
action: 'send',
|
||||||
data: {},
|
data: {},
|
||||||
filter: {
|
filter: {
|
||||||
id: {
|
id: {
|
||||||
|
|
@ -249,33 +273,16 @@ const triggers = [
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, { dontCollect: true });
|
}, { dontCollect: true });
|
||||||
const packaged = orders.filter(ele => ele.receivingMethod === 'express');
|
await context.operate('order', {
|
||||||
if (packaged.length > 0) {
|
id: await generateNewIdAsync(),
|
||||||
await context.operate('order', {
|
action: 'unship',
|
||||||
id: await generateNewIdAsync(),
|
data: {},
|
||||||
action: 'turnBack',
|
filter: {
|
||||||
data: {},
|
id: {
|
||||||
filter: {
|
$in: orders.map(ele => ele.id),
|
||||||
id: {
|
|
||||||
$in: packaged.map(ele => ele.id),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}, option);
|
},
|
||||||
}
|
}, option);
|
||||||
const staged = orders.filter(ele => ele.receivingMethod === 'pickup');
|
|
||||||
if (staged.length > 0) {
|
|
||||||
await context.operate('order', {
|
|
||||||
id: await generateNewIdAsync(),
|
|
||||||
action: 'cancelTaking',
|
|
||||||
data: {},
|
|
||||||
filter: {
|
|
||||||
id: {
|
|
||||||
$in: staged.map(ele => ele.id),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}, option);
|
|
||||||
}
|
|
||||||
assert(staged.length + packaged.length === orders.length);
|
|
||||||
return orders.length;
|
return orders.length;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,10 @@ import { EntityDict } from '../oak-app-domain';
|
||||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/types/Entity';
|
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/types/Entity';
|
||||||
import BackendRuntimeContext from '../context/BackendRuntimeContext';
|
import BackendRuntimeContext from '../context/BackendRuntimeContext';
|
||||||
export default interface ShipClazz<ED extends EntityDict & BaseEntityDict, Context extends BackendRuntimeContext<ED>> {
|
export default interface ShipClazz<ED extends EntityDict & BaseEntityDict, Context extends BackendRuntimeContext<ED>> {
|
||||||
|
getReceiverInfo(orderIds: string[], applicationId: string, context: Context): Promise<{
|
||||||
|
openId?: string;
|
||||||
|
appWxId?: string;
|
||||||
|
}>;
|
||||||
available(shipServiceId: string, orderIds: string[], context: Context): Promise<boolean>;
|
available(shipServiceId: string, orderIds: string[], context: Context): Promise<boolean>;
|
||||||
eOrder(shipId: string, context: Context): Promise<string>;
|
eOrder(shipId: string, context: Context): Promise<string>;
|
||||||
cancelOrder(shipId: string, context: Context): Promise<void>;
|
cancelOrder(shipId: string, context: Context): Promise<void>;
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,18 @@
|
||||||
import { EntityDict } from '../oak-app-domain';
|
import { EntityDict } from '../oak-app-domain';
|
||||||
import { BRC } from '../types/RuntimeCxt';
|
import { BRC } from '../types/RuntimeCxt';
|
||||||
export declare const fullShipProjection: EntityDict['ship']['Projection'];
|
export declare const shipProjection: EntityDict['ship']['Projection'];
|
||||||
|
/**
|
||||||
|
* 手机号掩码(130****0000)
|
||||||
|
* @param phone
|
||||||
|
*/
|
||||||
|
export declare function maskPhone(phone: string): string;
|
||||||
/**
|
/**
|
||||||
* 小程序发货信息录入
|
* 小程序发货信息录入
|
||||||
* @param shipInfo
|
* @param shipInfo
|
||||||
* @param context
|
* @param context
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export declare function uploadShippingInfo(param: {
|
export declare function uploadShippingInfo(shipId: string, context: BRC): Promise<void>;
|
||||||
depositId?: string;
|
|
||||||
orderId?: string;
|
|
||||||
}, context: BRC): Promise<true | undefined>;
|
|
||||||
/**
|
/**
|
||||||
* 获取小程序物流状态
|
* 获取小程序物流状态
|
||||||
* @param context
|
* @param context
|
||||||
|
|
@ -18,7 +20,7 @@ export declare function uploadShippingInfo(param: {
|
||||||
* @param order
|
* @param order
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export declare function getShipState(context: BRC, deposit?: EntityDict['deposit']['Schema'], order?: EntityDict['order']['Schema']): Promise<string | undefined>;
|
export declare function getShipState(context: BRC, shipId: string): Promise<string | undefined>;
|
||||||
/**刷新shipping的ship的小程序物流状态
|
/**刷新shipping的ship的小程序物流状态
|
||||||
* @param ship
|
* @param ship
|
||||||
* @param context
|
* @param context
|
||||||
|
|
|
||||||
388
es/utils/ship.js
388
es/utils/ship.js
|
|
@ -3,10 +3,14 @@ import { assert } from 'oak-domain/lib/utils/assert';
|
||||||
import { generateNewIdAsync } from 'oak-domain/lib/utils/uuid';
|
import { generateNewIdAsync } from 'oak-domain/lib/utils/uuid';
|
||||||
import { UploadShipException } from '../types/Exception';
|
import { UploadShipException } from '../types/Exception';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
export const fullShipProjection = {
|
import { isMobile } from 'oak-domain/lib/utils/validator';
|
||||||
|
export const shipProjection = {
|
||||||
id: 1,
|
id: 1,
|
||||||
type: 1,
|
type: 1,
|
||||||
iState: 1,
|
iState: 1,
|
||||||
|
entity: 1,
|
||||||
|
entityId: 1,
|
||||||
|
extraShipId: 1,
|
||||||
shipService: {
|
shipService: {
|
||||||
id: 1,
|
id: 1,
|
||||||
name: 1,
|
name: 1,
|
||||||
|
|
@ -17,7 +21,6 @@ export const fullShipProjection = {
|
||||||
wechatMpName: 1,
|
wechatMpName: 1,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
serial: 1,
|
|
||||||
deposit$ship: {
|
deposit$ship: {
|
||||||
$entity: 'deposit',
|
$entity: 'deposit',
|
||||||
data: {
|
data: {
|
||||||
|
|
@ -39,6 +42,9 @@ export const fullShipProjection = {
|
||||||
iState: 1,
|
iState: 1,
|
||||||
entity: 1,
|
entity: 1,
|
||||||
entityId: 1,
|
entityId: 1,
|
||||||
|
},
|
||||||
|
filter: {
|
||||||
|
iState: 'paid'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -66,75 +72,90 @@ export const fullShipProjection = {
|
||||||
iState: 1,
|
iState: 1,
|
||||||
entity: 1,
|
entity: 1,
|
||||||
entityId: 1,
|
entityId: 1,
|
||||||
|
},
|
||||||
|
filter: {
|
||||||
|
iState: 'paid'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
from: {
|
||||||
|
id: 1,
|
||||||
|
detail: 1,
|
||||||
|
name: 1,
|
||||||
|
phone: 1,
|
||||||
|
area: {
|
||||||
|
id: 1,
|
||||||
|
name: 1,
|
||||||
|
parent: {
|
||||||
|
id: 1,
|
||||||
|
name: 1,
|
||||||
|
parent: {
|
||||||
|
id: 1,
|
||||||
|
name: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
to: {
|
||||||
|
id: 1,
|
||||||
|
detail: 1,
|
||||||
|
name: 1,
|
||||||
|
phone: 1,
|
||||||
|
area: {
|
||||||
|
id: 1,
|
||||||
|
name: 1,
|
||||||
|
parent: {
|
||||||
|
id: 1,
|
||||||
|
name: 1,
|
||||||
|
parent: {
|
||||||
|
id: 1,
|
||||||
|
name: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* 手机号掩码(130****0000)
|
||||||
|
* @param phone
|
||||||
|
*/
|
||||||
|
export function maskPhone(phone) {
|
||||||
|
assert(isMobile(phone));
|
||||||
|
const start = phone.slice(3);
|
||||||
|
const end = phone.slice(-4);
|
||||||
|
return start + '****' + end;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 小程序发货信息录入
|
* 小程序发货信息录入
|
||||||
* @param shipInfo
|
* @param shipInfo
|
||||||
* @param context
|
* @param context
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export async function uploadShippingInfo(param, context) {
|
export async function uploadShippingInfo(shipId, context) {
|
||||||
const { depositId, orderId } = param;
|
const [ship] = await context.select('ship', {
|
||||||
if (depositId) {
|
data: shipProjection,
|
||||||
const [deposit] = await context.select('deposit', {
|
filter: {
|
||||||
data: {
|
id: shipId,
|
||||||
id: 1,
|
}
|
||||||
iState: 1,
|
}, { forUpdate: true });
|
||||||
shipId: 1,
|
const { deposit$ship: deposits, shipOrder$ship, type: shipType, extraShipId, shipService, from, to } = ship;
|
||||||
ship: {
|
// assert(iState === 'unshipped'); //可更改一次发货信息
|
||||||
id: 1,
|
//发货信息录入前检查小程序订单发货状态
|
||||||
iState: 1,
|
const shipState = await getShipState(context, shipId);
|
||||||
type: 1,
|
const now = dayjs().format();
|
||||||
},
|
const application = context.getApplication();
|
||||||
pay$deposit: {
|
const { type, config } = application;
|
||||||
$entity: 'pay',
|
assert(type === 'wechatMp');
|
||||||
data: {
|
const { appId, appSecret } = config;
|
||||||
id: 1,
|
const wechatInstance = WechatSDK.getInstance(appId, 'wechatMp', appSecret);
|
||||||
entity: 1,
|
if (deposits && deposits.length > 0 && shipState === 'unshipped') {
|
||||||
entityId: 1,
|
//充值
|
||||||
meta: 1,
|
assert(deposits.length === 1);
|
||||||
applicationId: 1,
|
const [deposit] = deposits;
|
||||||
},
|
const { pay$deposit: pays, } = deposit;
|
||||||
filter: {
|
|
||||||
iState: 'paid',
|
|
||||||
},
|
|
||||||
indexFrom: 0,
|
|
||||||
count: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
filter: {
|
|
||||||
id: depositId,
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
blockTrigger: true,
|
|
||||||
forUpdate: true,
|
|
||||||
});
|
|
||||||
const { pay$deposit: pays, } = deposit || {};
|
|
||||||
const pay = pays?.[0];
|
const pay = pays?.[0];
|
||||||
const applicationId = pay?.applicationId;
|
|
||||||
assert(applicationId);
|
|
||||||
const [application] = await context.select('application', {
|
|
||||||
data: {
|
|
||||||
id: 1,
|
|
||||||
type: 1,
|
|
||||||
config: 1.
|
|
||||||
},
|
|
||||||
filter: {
|
|
||||||
id: applicationId,
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
blockTrigger: true,
|
|
||||||
forUpdate: true,
|
|
||||||
});
|
|
||||||
const { type, config } = application;
|
|
||||||
assert(type === 'wechatMp');
|
|
||||||
const { appId, appSecret } = config;
|
|
||||||
const wechatInstance = WechatSDK.getInstance(appId, 'wechatMp', appSecret);
|
|
||||||
const meta = pay?.meta;
|
const meta = pay?.meta;
|
||||||
const shipInfo = {
|
const shipInfo = {
|
||||||
order_key: {
|
order_key: {
|
||||||
|
|
@ -148,22 +169,64 @@ export async function uploadShippingInfo(param, context) {
|
||||||
item_desc: '账户充值',
|
item_desc: '账户充值',
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
upload_time: dayjs().format(),
|
upload_time: now,
|
||||||
payer: {
|
payer: {
|
||||||
openid: meta?.payer?.openid,
|
openid: meta?.payer?.openid,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const result = await wechatInstance.uploadShippingInfo(shipInfo);
|
const result = await wechatInstance.uploadShippingInfo(shipInfo);
|
||||||
if (result?.errcode === 0) {
|
if (result?.errcode !== 0) {
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.error(JSON.stringify(result));
|
console.error(JSON.stringify(result));
|
||||||
throw new UploadShipException(result?.message);
|
throw new UploadShipException(result?.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (orderId) {
|
else if (shipOrder$ship && shipOrder$ship.length > 0 && shipState && ['unshipped', 'shipping'].includes(shipState)) {
|
||||||
//订单
|
//订单 每笔微信支付调用一次接口
|
||||||
|
const orders = shipOrder$ship.map((ele) => ele.order);
|
||||||
|
const fromPhoneStr = maskPhone(from.phone);
|
||||||
|
const toPhoneStr = maskPhone(to.phone);
|
||||||
|
for (const order of orders) {
|
||||||
|
const { pay$order, desc } = order;
|
||||||
|
const wechatPay = pay$order.find((ele) => ele.entity === 'wpProduct');
|
||||||
|
const meta = wechatPay?.meta;
|
||||||
|
let shippingList = [];
|
||||||
|
if (shipType === 'express') {
|
||||||
|
shippingList = [
|
||||||
|
{
|
||||||
|
tracking_no: extraShipId,
|
||||||
|
express_company: shipService?.shipCompany?.wechatMpName,
|
||||||
|
item_desc: desc,
|
||||||
|
contact: {
|
||||||
|
consignor_contact: fromPhoneStr,
|
||||||
|
receiver_contact: toPhoneStr,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
else if (shipType === 'pickup') {
|
||||||
|
shippingList = [{
|
||||||
|
item_desc: desc,
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
const shipInfo = {
|
||||||
|
order_key: {
|
||||||
|
order_number_type: 2,
|
||||||
|
transaction_id: meta?.transaction_id,
|
||||||
|
},
|
||||||
|
logistic_type: shipType === 'express' ? 1 : 4,
|
||||||
|
delivery_mode: 1,
|
||||||
|
shipping_list: shippingList,
|
||||||
|
upload_time: now,
|
||||||
|
payer: {
|
||||||
|
openid: meta?.payer?.openid,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const result = await wechatInstance.uploadShippingInfo(shipInfo);
|
||||||
|
if (result?.errcode !== 0) {
|
||||||
|
console.error(JSON.stringify(result));
|
||||||
|
throw new UploadShipException(result?.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|
@ -173,89 +236,67 @@ export async function uploadShippingInfo(param, context) {
|
||||||
* @param order
|
* @param order
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export async function getShipState(context, deposit, order) {
|
export async function getShipState(context, shipId) {
|
||||||
|
const [ship] = await context.select('ship', {
|
||||||
|
data: shipProjection,
|
||||||
|
filter: {
|
||||||
|
id: shipId,
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
blockTrigger: true,
|
||||||
|
forUpdate: true
|
||||||
|
});
|
||||||
|
assert(ship);
|
||||||
|
const { deposit$ship: deposits, shipOrder$ship } = ship;
|
||||||
const application = context.getApplication();
|
const application = context.getApplication();
|
||||||
const { type, config } = application;
|
const { type, config } = application;
|
||||||
assert(type === 'wechatMp');
|
assert(type === 'wechatMp');
|
||||||
const { appId, appSecret } = config;
|
const { appId, appSecret } = config;
|
||||||
const wechatInstance = WechatSDK.getInstance(appId, 'wechatMp', appSecret);
|
const wechatInstance = WechatSDK.getInstance(appId, 'wechatMp', appSecret);
|
||||||
if (deposit) {
|
let info = undefined;
|
||||||
|
if (deposits && deposits.length > 0) {
|
||||||
//充值
|
//充值
|
||||||
let deposit2 = deposit;
|
const [deposit] = deposits;
|
||||||
const deposits = await context.select('deposit', {
|
const { pay$deposit: pays, } = deposit;
|
||||||
data: {
|
|
||||||
id: 1,
|
|
||||||
iState: 1,
|
|
||||||
pay$deposit: {
|
|
||||||
$entity: 'pay',
|
|
||||||
data: {
|
|
||||||
id: 1,
|
|
||||||
iState: 1,
|
|
||||||
meta: 1,
|
|
||||||
entity: 1,
|
|
||||||
entityId: 1,
|
|
||||||
},
|
|
||||||
filter: {
|
|
||||||
iState: 'paid',
|
|
||||||
},
|
|
||||||
indexFrom: 0,
|
|
||||||
count: 1,
|
|
||||||
},
|
|
||||||
shipId: 1,
|
|
||||||
ship: {
|
|
||||||
id: 1,
|
|
||||||
type: 1,
|
|
||||||
iState: 1,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
filter: {
|
|
||||||
id: deposit?.id,
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
blockTrigger: true,
|
|
||||||
forUpdate: true,
|
|
||||||
});
|
|
||||||
deposit2 = deposits[0];
|
|
||||||
const { pay$deposit: pays, ship, shipId } = deposit2;
|
|
||||||
const pay = pays?.[0];
|
const pay = pays?.[0];
|
||||||
if (shipId && pay) {
|
if (shipId && pay) {
|
||||||
const info = {
|
info = {
|
||||||
transaction_id: pay?.meta?.transaction_id
|
transaction_id: pay?.meta?.transaction_id
|
||||||
};
|
};
|
||||||
const result = await wechatInstance.getOrderState(info);
|
|
||||||
const { orderState, inComplaint } = result;
|
|
||||||
if (!inComplaint) {
|
|
||||||
//未处于纠纷中
|
|
||||||
let state = undefined;
|
|
||||||
// let action = undefined;
|
|
||||||
switch (orderState) {
|
|
||||||
case 1: //待发货
|
|
||||||
state = 'unshipped';
|
|
||||||
break;
|
|
||||||
case 2: //已发货
|
|
||||||
state = 'shipping';
|
|
||||||
// action = 'ship';
|
|
||||||
break;
|
|
||||||
case 3: //确认收货
|
|
||||||
state = 'received';
|
|
||||||
// action = 'receive';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// if (action && ship?.iState !== state) {
|
|
||||||
// await context.operate('ship', {
|
|
||||||
// id: await generateNewIdAsync(),
|
|
||||||
// action,
|
|
||||||
// data: {},
|
|
||||||
// filter: {
|
|
||||||
// id: shipId,
|
|
||||||
// }
|
|
||||||
// }, {});
|
|
||||||
// }
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (order) {
|
else if (shipOrder$ship && shipOrder$ship.length > 0) {
|
||||||
|
const order = shipOrder$ship[0].order;
|
||||||
|
const { pay$order: pays, } = order;
|
||||||
|
const pay = pays?.find((ele) => ele.entity === 'wpProduct');
|
||||||
|
if (shipId && pay) {
|
||||||
|
info = {
|
||||||
|
transaction_id: pay?.meta?.transaction_id
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (info) {
|
||||||
|
const result = await wechatInstance.getOrderState(info);
|
||||||
|
const { orderState, inComplaint } = result;
|
||||||
|
if (!inComplaint) {
|
||||||
|
//未处于纠纷中
|
||||||
|
let state = undefined;
|
||||||
|
// let action = undefined;
|
||||||
|
switch (orderState) {
|
||||||
|
case 1: //待发货
|
||||||
|
state = 'unshipped';
|
||||||
|
break;
|
||||||
|
case 2: //已发货
|
||||||
|
state = 'shipping';
|
||||||
|
// action = 'ship';
|
||||||
|
break;
|
||||||
|
case 3: //确认收货
|
||||||
|
state = 'received';
|
||||||
|
// action = 'receive';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**刷新shipping的ship的小程序物流状态
|
/**刷新shipping的ship的小程序物流状态
|
||||||
|
|
@ -265,9 +306,9 @@ export async function getShipState(context, deposit, order) {
|
||||||
*/
|
*/
|
||||||
export async function refreshtShipState(ship, context) {
|
export async function refreshtShipState(ship, context) {
|
||||||
let ship2 = ship;
|
let ship2 = ship;
|
||||||
if (!ship2.iState || (!ship2.deposit$ship && !ship2.shipOrder$ship)) {
|
if (!ship2.iState) {
|
||||||
const ships = await context.select('ship', {
|
const ships = await context.select('ship', {
|
||||||
data: fullShipProjection,
|
data: shipProjection,
|
||||||
filter: {
|
filter: {
|
||||||
id: ship.id,
|
id: ship.id,
|
||||||
}
|
}
|
||||||
|
|
@ -277,57 +318,26 @@ export async function refreshtShipState(ship, context) {
|
||||||
});
|
});
|
||||||
ship2 = ships[0];
|
ship2 = ships[0];
|
||||||
}
|
}
|
||||||
let application = undefined, info = undefined;
|
const state = await getShipState(context, ship2.id);
|
||||||
const { deposit$ship: deposits, shipOrder$ship: shipOrders, } = ship2;
|
let action = undefined;
|
||||||
if (deposits && deposits.length > 0) {
|
switch (state) {
|
||||||
//充值
|
case 'shipping': //已发货
|
||||||
const deposit = deposits[0];
|
action = 'ship';
|
||||||
const { pay$deposit } = deposit;
|
break;
|
||||||
application = pay$deposit?.[0].application;
|
case 'received': //确认收货
|
||||||
const meta = pay$deposit?.[0].meta;
|
action = 'receive';
|
||||||
info = {
|
break;
|
||||||
transaction_id: meta?.transaction_id
|
default:
|
||||||
};
|
action = undefined;
|
||||||
}
|
}
|
||||||
else if (shipOrders && shipOrders.length > 0) {
|
if (action && ship2.iState !== state) {
|
||||||
//订单
|
return await context.operate('ship', {
|
||||||
}
|
id: await generateNewIdAsync(),
|
||||||
if (application) {
|
action,
|
||||||
const { type, config } = application;
|
data: {},
|
||||||
assert(type === 'wechatMp');
|
filter: {
|
||||||
const { appId, appSecret } = config;
|
id: ship2.id,
|
||||||
const wechatInstance = WechatSDK.getInstance(appId, 'wechatMp', appSecret);
|
|
||||||
if (info) {
|
|
||||||
const result = await wechatInstance.getOrderState(info);
|
|
||||||
const { orderState, inComplaint } = result;
|
|
||||||
if (!inComplaint) {
|
|
||||||
//未处于纠纷中
|
|
||||||
let state = undefined;
|
|
||||||
let action = undefined;
|
|
||||||
switch (orderState) {
|
|
||||||
case 1: //待发货
|
|
||||||
state = 'unshipped';
|
|
||||||
break;
|
|
||||||
case 2: //已发货
|
|
||||||
state = 'shipping';
|
|
||||||
action = 'ship';
|
|
||||||
break;
|
|
||||||
case 3: //确认收货
|
|
||||||
state = 'received';
|
|
||||||
action = 'receive';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (action && ship2.iState !== state) {
|
|
||||||
return await context.operate('ship', {
|
|
||||||
id: await generateNewIdAsync(),
|
|
||||||
action,
|
|
||||||
data: {},
|
|
||||||
filter: {
|
|
||||||
id: ship2.id,
|
|
||||||
}
|
|
||||||
}, {});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}, {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,10 @@ type ExtraAddExpressOrderData = Omit<AddExpressOrderData, 'order_id' | 'openid'
|
||||||
export default class WechatMpShipDebug<ED extends EntityDict & BaseEntityDict, Context extends BackendRuntimeContext<ED>> implements ShipClazz<ED, Context> {
|
export default class WechatMpShipDebug<ED extends EntityDict & BaseEntityDict, Context extends BackendRuntimeContext<ED>> implements ShipClazz<ED, Context> {
|
||||||
private wechatMpShipId;
|
private wechatMpShipId;
|
||||||
private wechatMpShip?;
|
private wechatMpShip?;
|
||||||
private getReceiverInfo;
|
getReceiverInfo: (orderIds: string[], applicationId: string, context: Context) => Promise<{
|
||||||
|
openId?: string;
|
||||||
|
appWxId?: string;
|
||||||
|
}>;
|
||||||
private getExtraData;
|
private getExtraData;
|
||||||
constructor(wechatMpShipId: string, getReceiverInfo: (orderIds: string[], applicationId: string, context: Context) => Promise<{
|
constructor(wechatMpShipId: string, getReceiverInfo: (orderIds: string[], applicationId: string, context: Context) => Promise<{
|
||||||
openId?: string;
|
openId?: string;
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ const ShipServiceCodeDict = {
|
||||||
export default class WechatMpShipDebug {
|
export default class WechatMpShipDebug {
|
||||||
wechatMpShipId;
|
wechatMpShipId;
|
||||||
wechatMpShip;
|
wechatMpShip;
|
||||||
|
// 这个外部可能也需要调用
|
||||||
getReceiverInfo;
|
getReceiverInfo;
|
||||||
getExtraData;
|
getExtraData;
|
||||||
constructor(wechatMpShipId, getReceiverInfo, getExtraData) {
|
constructor(wechatMpShipId, getReceiverInfo, getExtraData) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { mergeOperationResult } from 'oak-domain/lib/utils/operationResult';
|
import { mergeOperationResult } from 'oak-domain/lib/utils/operationResult';
|
||||||
import { fullShipProjection, refreshtShipState } from '../utils/ship';
|
import { shipProjection, refreshtShipState } from '../utils/ship';
|
||||||
const QUERY_PAYING_STATE_GAP = process.env.NODE_ENV === 'production' ? 600 * 1000 : 60 * 1000;
|
const QUERY_PAYING_STATE_GAP = process.env.NODE_ENV === 'production' ? 600 * 1000 : 60 * 1000;
|
||||||
const watchers = [
|
const watchers = [
|
||||||
{
|
{
|
||||||
|
|
@ -14,7 +14,7 @@ const watchers = [
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
projection: fullShipProjection,
|
projection: shipProjection,
|
||||||
fn: async (context, data) => {
|
fn: async (context, data) => {
|
||||||
const results = [];
|
const results = [];
|
||||||
for (const ship of data) {
|
for (const ship of data) {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ export type AspectDict<ED extends EntityDict> = {
|
||||||
withdrawAccountId?: string;
|
withdrawAccountId?: string;
|
||||||
}, context: BackendRuntimeContext<ED>) => Promise<EntityDict['withdraw']['CreateSingle']['data']>;
|
}, context: BackendRuntimeContext<ED>) => Promise<EntityDict['withdraw']['CreateSingle']['data']>;
|
||||||
getMpShipState: (params: {
|
getMpShipState: (params: {
|
||||||
depositId?: string;
|
shipId: string;
|
||||||
orderId?: string;
|
|
||||||
}, context: BackendRuntimeContext<ED>) => Promise<EntityDict['ship']['Schema']['iState']>;
|
}, context: BackendRuntimeContext<ED>) => Promise<EntityDict['ship']['Schema']['iState']>;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,5 @@ import { BRC } from '../types/RuntimeCxt';
|
||||||
* @param context
|
* @param context
|
||||||
*/
|
*/
|
||||||
export declare function getMpShipState(params: {
|
export declare function getMpShipState(params: {
|
||||||
depositId?: string;
|
shipId: string;
|
||||||
orderId?: string;
|
|
||||||
}, context: BRC): Promise<string | null | undefined>;
|
}, context: BRC): Promise<string | null | undefined>;
|
||||||
|
|
|
||||||
|
|
@ -11,31 +11,9 @@ async function getMpShipState(params, context) {
|
||||||
const application = context.getApplication();
|
const application = context.getApplication();
|
||||||
const { type, } = application;
|
const { type, } = application;
|
||||||
if (type === 'wechatMp') {
|
if (type === 'wechatMp') {
|
||||||
const { depositId, orderId } = params;
|
const { shipId } = params;
|
||||||
if (depositId) {
|
const shipState = await (0, ship_1.getShipState)(context, shipId);
|
||||||
//充值
|
return shipState;
|
||||||
const deposits = await context.select('deposit', {
|
|
||||||
data: {
|
|
||||||
id: 1,
|
|
||||||
iState: 1,
|
|
||||||
shipId: 1,
|
|
||||||
ship: {
|
|
||||||
id: 1,
|
|
||||||
iState: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
filter: {
|
|
||||||
id: depositId,
|
|
||||||
}
|
|
||||||
}, {});
|
|
||||||
const deposit = deposits[0];
|
|
||||||
if (deposit) {
|
|
||||||
const shipState = await (0, ship_1.getShipState)(context, deposit);
|
|
||||||
return shipState;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (orderId) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.getMpShipState = getMpShipState;
|
exports.getMpShipState = getMpShipState;
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ const triggers = [
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// todo,应该是所有的ship
|
// todo,deposit的ship和 shipClazz中有配置wechatShip且可获取openId的order的ship
|
||||||
entity: 'ship',
|
entity: 'ship',
|
||||||
name: '当虚拟的ship变为shipping状态时,调用小程序发货信息录入接口',
|
name: '当虚拟的ship变为shipping状态时,调用小程序发货信息录入接口',
|
||||||
action: 'ship',
|
action: 'ship',
|
||||||
|
|
@ -80,21 +80,45 @@ const triggers = [
|
||||||
data: {
|
data: {
|
||||||
id: 1,
|
id: 1,
|
||||||
},
|
},
|
||||||
indexFrom: 0,
|
},
|
||||||
count: 1,
|
entity: 1,
|
||||||
|
entityId: 1,
|
||||||
|
shipServiceId: 1,
|
||||||
|
shipOrder$ship: {
|
||||||
|
$entity: 'shipOrder',
|
||||||
|
data: {
|
||||||
|
id: 1,
|
||||||
|
orderId: 1,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
wechatMpShip: {
|
||||||
|
id: 1,
|
||||||
|
applicationId: 1,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
filter,
|
filter,
|
||||||
}, {});
|
}, {});
|
||||||
const { type, deposit$ship: deposits } = ship || {};
|
const { id: shipId, type, deposit$ship: deposits, shipOrder$ship, shipServiceId, entity, entityId, wechatMpShip } = ship || {};
|
||||||
if (type === 'virtual') {
|
if (deposits && deposits.length > 0) {
|
||||||
const deposit = deposits?.[0];
|
//充值 (此时该充值必定为受发货限制的小程序上的充值)
|
||||||
//当已发货的订单再次调用小程序发货信息录入接口视为重新发货(仅可重新发货一次)
|
|
||||||
//发货前先查询,检查是否为未同步微信端发货状态
|
//发货前先查询,检查是否为未同步微信端发货状态
|
||||||
const shipState = await (0, ship_1.getShipState)(context, deposit);
|
const shipState = await (0, ship_1.getShipState)(context, shipId);
|
||||||
if (shipState === 'unshipped') {
|
if (shipState === 'unshipped') {
|
||||||
const result = await (0, ship_1.uploadShippingInfo)({ depositId: deposit?.id, }, context);
|
await (0, ship_1.uploadShippingInfo)(shipId, context);
|
||||||
if (result) {
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (shipOrder$ship && shipOrder$ship.length > 0) {
|
||||||
|
//订单
|
||||||
|
const clazz = await (0, shipClazz_1.getShipClazz)(entity, entityId, context);
|
||||||
|
const { openId } = await clazz.getReceiverInfo(shipOrder$ship.map((ele) => ele.orderId), wechatMpShip?.applicationId, context);
|
||||||
|
if (openId) {
|
||||||
|
//当存在openId时调用小程序发货信息录入
|
||||||
|
const shipState = await (0, ship_1.getShipState)(context, shipId);
|
||||||
|
//当已发货的订单再次调用小程序发货信息录入接口视为重新发货(仅可重新发货一次)
|
||||||
|
if (shipState && ['unshipped', 'shipping'].includes(shipState)) {
|
||||||
|
// 发货/更换发货
|
||||||
|
await (0, ship_1.uploadShippingInfo)(shipId, context);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -206,7 +230,7 @@ const triggers = [
|
||||||
if (packaged.length > 0) {
|
if (packaged.length > 0) {
|
||||||
await context.operate('order', {
|
await context.operate('order', {
|
||||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||||
action: 'ship',
|
action: 'send',
|
||||||
data: {},
|
data: {},
|
||||||
filter: {
|
filter: {
|
||||||
id: {
|
id: {
|
||||||
|
|
@ -252,33 +276,16 @@ const triggers = [
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, { dontCollect: true });
|
}, { dontCollect: true });
|
||||||
const packaged = orders.filter(ele => ele.receivingMethod === 'express');
|
await context.operate('order', {
|
||||||
if (packaged.length > 0) {
|
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||||
await context.operate('order', {
|
action: 'unship',
|
||||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
data: {},
|
||||||
action: 'turnBack',
|
filter: {
|
||||||
data: {},
|
id: {
|
||||||
filter: {
|
$in: orders.map(ele => ele.id),
|
||||||
id: {
|
|
||||||
$in: packaged.map(ele => ele.id),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}, option);
|
},
|
||||||
}
|
}, option);
|
||||||
const staged = orders.filter(ele => ele.receivingMethod === 'pickup');
|
|
||||||
if (staged.length > 0) {
|
|
||||||
await context.operate('order', {
|
|
||||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
|
||||||
action: 'cancelTaking',
|
|
||||||
data: {},
|
|
||||||
filter: {
|
|
||||||
id: {
|
|
||||||
$in: staged.map(ele => ele.id),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}, option);
|
|
||||||
}
|
|
||||||
(0, assert_1.default)(staged.length + packaged.length === orders.length);
|
|
||||||
return orders.length;
|
return orders.length;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,10 @@ import { EntityDict } from '../oak-app-domain';
|
||||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/types/Entity';
|
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/types/Entity';
|
||||||
import BackendRuntimeContext from '../context/BackendRuntimeContext';
|
import BackendRuntimeContext from '../context/BackendRuntimeContext';
|
||||||
export default interface ShipClazz<ED extends EntityDict & BaseEntityDict, Context extends BackendRuntimeContext<ED>> {
|
export default interface ShipClazz<ED extends EntityDict & BaseEntityDict, Context extends BackendRuntimeContext<ED>> {
|
||||||
|
getReceiverInfo(orderIds: string[], applicationId: string, context: Context): Promise<{
|
||||||
|
openId?: string;
|
||||||
|
appWxId?: string;
|
||||||
|
}>;
|
||||||
available(shipServiceId: string, orderIds: string[], context: Context): Promise<boolean>;
|
available(shipServiceId: string, orderIds: string[], context: Context): Promise<boolean>;
|
||||||
eOrder(shipId: string, context: Context): Promise<string>;
|
eOrder(shipId: string, context: Context): Promise<string>;
|
||||||
cancelOrder(shipId: string, context: Context): Promise<void>;
|
cancelOrder(shipId: string, context: Context): Promise<void>;
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,18 @@
|
||||||
import { EntityDict } from '../oak-app-domain';
|
import { EntityDict } from '../oak-app-domain';
|
||||||
import { BRC } from '../types/RuntimeCxt';
|
import { BRC } from '../types/RuntimeCxt';
|
||||||
export declare const fullShipProjection: EntityDict['ship']['Projection'];
|
export declare const shipProjection: EntityDict['ship']['Projection'];
|
||||||
|
/**
|
||||||
|
* 手机号掩码(130****0000)
|
||||||
|
* @param phone
|
||||||
|
*/
|
||||||
|
export declare function maskPhone(phone: string): string;
|
||||||
/**
|
/**
|
||||||
* 小程序发货信息录入
|
* 小程序发货信息录入
|
||||||
* @param shipInfo
|
* @param shipInfo
|
||||||
* @param context
|
* @param context
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export declare function uploadShippingInfo(param: {
|
export declare function uploadShippingInfo(shipId: string, context: BRC): Promise<void>;
|
||||||
depositId?: string;
|
|
||||||
orderId?: string;
|
|
||||||
}, context: BRC): Promise<true | undefined>;
|
|
||||||
/**
|
/**
|
||||||
* 获取小程序物流状态
|
* 获取小程序物流状态
|
||||||
* @param context
|
* @param context
|
||||||
|
|
@ -18,7 +20,7 @@ export declare function uploadShippingInfo(param: {
|
||||||
* @param order
|
* @param order
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export declare function getShipState(context: BRC, deposit?: EntityDict['deposit']['Schema'], order?: EntityDict['order']['Schema']): Promise<string | undefined>;
|
export declare function getShipState(context: BRC, shipId: string): Promise<string | undefined>;
|
||||||
/**刷新shipping的ship的小程序物流状态
|
/**刷新shipping的ship的小程序物流状态
|
||||||
* @param ship
|
* @param ship
|
||||||
* @param context
|
* @param context
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,20 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.refreshtShipState = exports.getShipState = exports.uploadShippingInfo = exports.fullShipProjection = void 0;
|
exports.refreshtShipState = exports.getShipState = exports.uploadShippingInfo = exports.maskPhone = exports.shipProjection = void 0;
|
||||||
const tslib_1 = require("tslib");
|
const tslib_1 = require("tslib");
|
||||||
const oak_external_sdk_1 = require("oak-external-sdk");
|
const oak_external_sdk_1 = require("oak-external-sdk");
|
||||||
const assert_1 = require("oak-domain/lib/utils/assert");
|
const assert_1 = require("oak-domain/lib/utils/assert");
|
||||||
const uuid_1 = require("oak-domain/lib/utils/uuid");
|
const uuid_1 = require("oak-domain/lib/utils/uuid");
|
||||||
const Exception_1 = require("../types/Exception");
|
const Exception_1 = require("../types/Exception");
|
||||||
const dayjs_1 = tslib_1.__importDefault(require("dayjs"));
|
const dayjs_1 = tslib_1.__importDefault(require("dayjs"));
|
||||||
exports.fullShipProjection = {
|
const validator_1 = require("oak-domain/lib/utils/validator");
|
||||||
|
exports.shipProjection = {
|
||||||
id: 1,
|
id: 1,
|
||||||
type: 1,
|
type: 1,
|
||||||
iState: 1,
|
iState: 1,
|
||||||
|
entity: 1,
|
||||||
|
entityId: 1,
|
||||||
|
extraShipId: 1,
|
||||||
shipService: {
|
shipService: {
|
||||||
id: 1,
|
id: 1,
|
||||||
name: 1,
|
name: 1,
|
||||||
|
|
@ -21,7 +25,6 @@ exports.fullShipProjection = {
|
||||||
wechatMpName: 1,
|
wechatMpName: 1,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
serial: 1,
|
|
||||||
deposit$ship: {
|
deposit$ship: {
|
||||||
$entity: 'deposit',
|
$entity: 'deposit',
|
||||||
data: {
|
data: {
|
||||||
|
|
@ -43,6 +46,9 @@ exports.fullShipProjection = {
|
||||||
iState: 1,
|
iState: 1,
|
||||||
entity: 1,
|
entity: 1,
|
||||||
entityId: 1,
|
entityId: 1,
|
||||||
|
},
|
||||||
|
filter: {
|
||||||
|
iState: 'paid'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -70,75 +76,91 @@ exports.fullShipProjection = {
|
||||||
iState: 1,
|
iState: 1,
|
||||||
entity: 1,
|
entity: 1,
|
||||||
entityId: 1,
|
entityId: 1,
|
||||||
|
},
|
||||||
|
filter: {
|
||||||
|
iState: 'paid'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
from: {
|
||||||
|
id: 1,
|
||||||
|
detail: 1,
|
||||||
|
name: 1,
|
||||||
|
phone: 1,
|
||||||
|
area: {
|
||||||
|
id: 1,
|
||||||
|
name: 1,
|
||||||
|
parent: {
|
||||||
|
id: 1,
|
||||||
|
name: 1,
|
||||||
|
parent: {
|
||||||
|
id: 1,
|
||||||
|
name: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
to: {
|
||||||
|
id: 1,
|
||||||
|
detail: 1,
|
||||||
|
name: 1,
|
||||||
|
phone: 1,
|
||||||
|
area: {
|
||||||
|
id: 1,
|
||||||
|
name: 1,
|
||||||
|
parent: {
|
||||||
|
id: 1,
|
||||||
|
name: 1,
|
||||||
|
parent: {
|
||||||
|
id: 1,
|
||||||
|
name: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* 手机号掩码(130****0000)
|
||||||
|
* @param phone
|
||||||
|
*/
|
||||||
|
function maskPhone(phone) {
|
||||||
|
(0, assert_1.assert)((0, validator_1.isMobile)(phone));
|
||||||
|
const start = phone.slice(3);
|
||||||
|
const end = phone.slice(-4);
|
||||||
|
return start + '****' + end;
|
||||||
|
}
|
||||||
|
exports.maskPhone = maskPhone;
|
||||||
/**
|
/**
|
||||||
* 小程序发货信息录入
|
* 小程序发货信息录入
|
||||||
* @param shipInfo
|
* @param shipInfo
|
||||||
* @param context
|
* @param context
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async function uploadShippingInfo(param, context) {
|
async function uploadShippingInfo(shipId, context) {
|
||||||
const { depositId, orderId } = param;
|
const [ship] = await context.select('ship', {
|
||||||
if (depositId) {
|
data: exports.shipProjection,
|
||||||
const [deposit] = await context.select('deposit', {
|
filter: {
|
||||||
data: {
|
id: shipId,
|
||||||
id: 1,
|
}
|
||||||
iState: 1,
|
}, { forUpdate: true });
|
||||||
shipId: 1,
|
const { deposit$ship: deposits, shipOrder$ship, type: shipType, extraShipId, shipService, from, to } = ship;
|
||||||
ship: {
|
// assert(iState === 'unshipped'); //可更改一次发货信息
|
||||||
id: 1,
|
//发货信息录入前检查小程序订单发货状态
|
||||||
iState: 1,
|
const shipState = await getShipState(context, shipId);
|
||||||
type: 1,
|
const now = (0, dayjs_1.default)().format();
|
||||||
},
|
const application = context.getApplication();
|
||||||
pay$deposit: {
|
const { type, config } = application;
|
||||||
$entity: 'pay',
|
(0, assert_1.assert)(type === 'wechatMp');
|
||||||
data: {
|
const { appId, appSecret } = config;
|
||||||
id: 1,
|
const wechatInstance = oak_external_sdk_1.WechatSDK.getInstance(appId, 'wechatMp', appSecret);
|
||||||
entity: 1,
|
if (deposits && deposits.length > 0 && shipState === 'unshipped') {
|
||||||
entityId: 1,
|
//充值
|
||||||
meta: 1,
|
(0, assert_1.assert)(deposits.length === 1);
|
||||||
applicationId: 1,
|
const [deposit] = deposits;
|
||||||
},
|
const { pay$deposit: pays, } = deposit;
|
||||||
filter: {
|
|
||||||
iState: 'paid',
|
|
||||||
},
|
|
||||||
indexFrom: 0,
|
|
||||||
count: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
filter: {
|
|
||||||
id: depositId,
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
blockTrigger: true,
|
|
||||||
forUpdate: true,
|
|
||||||
});
|
|
||||||
const { pay$deposit: pays, } = deposit || {};
|
|
||||||
const pay = pays?.[0];
|
const pay = pays?.[0];
|
||||||
const applicationId = pay?.applicationId;
|
|
||||||
(0, assert_1.assert)(applicationId);
|
|
||||||
const [application] = await context.select('application', {
|
|
||||||
data: {
|
|
||||||
id: 1,
|
|
||||||
type: 1,
|
|
||||||
config: 1.
|
|
||||||
},
|
|
||||||
filter: {
|
|
||||||
id: applicationId,
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
blockTrigger: true,
|
|
||||||
forUpdate: true,
|
|
||||||
});
|
|
||||||
const { type, config } = application;
|
|
||||||
(0, assert_1.assert)(type === 'wechatMp');
|
|
||||||
const { appId, appSecret } = config;
|
|
||||||
const wechatInstance = oak_external_sdk_1.WechatSDK.getInstance(appId, 'wechatMp', appSecret);
|
|
||||||
const meta = pay?.meta;
|
const meta = pay?.meta;
|
||||||
const shipInfo = {
|
const shipInfo = {
|
||||||
order_key: {
|
order_key: {
|
||||||
|
|
@ -152,22 +174,64 @@ async function uploadShippingInfo(param, context) {
|
||||||
item_desc: '账户充值',
|
item_desc: '账户充值',
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
upload_time: (0, dayjs_1.default)().format(),
|
upload_time: now,
|
||||||
payer: {
|
payer: {
|
||||||
openid: meta?.payer?.openid,
|
openid: meta?.payer?.openid,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const result = await wechatInstance.uploadShippingInfo(shipInfo);
|
const result = await wechatInstance.uploadShippingInfo(shipInfo);
|
||||||
if (result?.errcode === 0) {
|
if (result?.errcode !== 0) {
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.error(JSON.stringify(result));
|
console.error(JSON.stringify(result));
|
||||||
throw new Exception_1.UploadShipException(result?.message);
|
throw new Exception_1.UploadShipException(result?.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (orderId) {
|
else if (shipOrder$ship && shipOrder$ship.length > 0 && shipState && ['unshipped', 'shipping'].includes(shipState)) {
|
||||||
//订单
|
//订单 每笔微信支付调用一次接口
|
||||||
|
const orders = shipOrder$ship.map((ele) => ele.order);
|
||||||
|
const fromPhoneStr = maskPhone(from.phone);
|
||||||
|
const toPhoneStr = maskPhone(to.phone);
|
||||||
|
for (const order of orders) {
|
||||||
|
const { pay$order, desc } = order;
|
||||||
|
const wechatPay = pay$order.find((ele) => ele.entity === 'wpProduct');
|
||||||
|
const meta = wechatPay?.meta;
|
||||||
|
let shippingList = [];
|
||||||
|
if (shipType === 'express') {
|
||||||
|
shippingList = [
|
||||||
|
{
|
||||||
|
tracking_no: extraShipId,
|
||||||
|
express_company: shipService?.shipCompany?.wechatMpName,
|
||||||
|
item_desc: desc,
|
||||||
|
contact: {
|
||||||
|
consignor_contact: fromPhoneStr,
|
||||||
|
receiver_contact: toPhoneStr,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
else if (shipType === 'pickup') {
|
||||||
|
shippingList = [{
|
||||||
|
item_desc: desc,
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
const shipInfo = {
|
||||||
|
order_key: {
|
||||||
|
order_number_type: 2,
|
||||||
|
transaction_id: meta?.transaction_id,
|
||||||
|
},
|
||||||
|
logistic_type: shipType === 'express' ? 1 : 4,
|
||||||
|
delivery_mode: 1,
|
||||||
|
shipping_list: shippingList,
|
||||||
|
upload_time: now,
|
||||||
|
payer: {
|
||||||
|
openid: meta?.payer?.openid,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const result = await wechatInstance.uploadShippingInfo(shipInfo);
|
||||||
|
if (result?.errcode !== 0) {
|
||||||
|
console.error(JSON.stringify(result));
|
||||||
|
throw new Exception_1.UploadShipException(result?.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.uploadShippingInfo = uploadShippingInfo;
|
exports.uploadShippingInfo = uploadShippingInfo;
|
||||||
|
|
@ -178,89 +242,67 @@ exports.uploadShippingInfo = uploadShippingInfo;
|
||||||
* @param order
|
* @param order
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async function getShipState(context, deposit, order) {
|
async function getShipState(context, shipId) {
|
||||||
|
const [ship] = await context.select('ship', {
|
||||||
|
data: exports.shipProjection,
|
||||||
|
filter: {
|
||||||
|
id: shipId,
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
blockTrigger: true,
|
||||||
|
forUpdate: true
|
||||||
|
});
|
||||||
|
(0, assert_1.assert)(ship);
|
||||||
|
const { deposit$ship: deposits, shipOrder$ship } = ship;
|
||||||
const application = context.getApplication();
|
const application = context.getApplication();
|
||||||
const { type, config } = application;
|
const { type, config } = application;
|
||||||
(0, assert_1.assert)(type === 'wechatMp');
|
(0, assert_1.assert)(type === 'wechatMp');
|
||||||
const { appId, appSecret } = config;
|
const { appId, appSecret } = config;
|
||||||
const wechatInstance = oak_external_sdk_1.WechatSDK.getInstance(appId, 'wechatMp', appSecret);
|
const wechatInstance = oak_external_sdk_1.WechatSDK.getInstance(appId, 'wechatMp', appSecret);
|
||||||
if (deposit) {
|
let info = undefined;
|
||||||
|
if (deposits && deposits.length > 0) {
|
||||||
//充值
|
//充值
|
||||||
let deposit2 = deposit;
|
const [deposit] = deposits;
|
||||||
const deposits = await context.select('deposit', {
|
const { pay$deposit: pays, } = deposit;
|
||||||
data: {
|
|
||||||
id: 1,
|
|
||||||
iState: 1,
|
|
||||||
pay$deposit: {
|
|
||||||
$entity: 'pay',
|
|
||||||
data: {
|
|
||||||
id: 1,
|
|
||||||
iState: 1,
|
|
||||||
meta: 1,
|
|
||||||
entity: 1,
|
|
||||||
entityId: 1,
|
|
||||||
},
|
|
||||||
filter: {
|
|
||||||
iState: 'paid',
|
|
||||||
},
|
|
||||||
indexFrom: 0,
|
|
||||||
count: 1,
|
|
||||||
},
|
|
||||||
shipId: 1,
|
|
||||||
ship: {
|
|
||||||
id: 1,
|
|
||||||
type: 1,
|
|
||||||
iState: 1,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
filter: {
|
|
||||||
id: deposit?.id,
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
blockTrigger: true,
|
|
||||||
forUpdate: true,
|
|
||||||
});
|
|
||||||
deposit2 = deposits[0];
|
|
||||||
const { pay$deposit: pays, ship, shipId } = deposit2;
|
|
||||||
const pay = pays?.[0];
|
const pay = pays?.[0];
|
||||||
if (shipId && pay) {
|
if (shipId && pay) {
|
||||||
const info = {
|
info = {
|
||||||
transaction_id: pay?.meta?.transaction_id
|
transaction_id: pay?.meta?.transaction_id
|
||||||
};
|
};
|
||||||
const result = await wechatInstance.getOrderState(info);
|
|
||||||
const { orderState, inComplaint } = result;
|
|
||||||
if (!inComplaint) {
|
|
||||||
//未处于纠纷中
|
|
||||||
let state = undefined;
|
|
||||||
// let action = undefined;
|
|
||||||
switch (orderState) {
|
|
||||||
case 1: //待发货
|
|
||||||
state = 'unshipped';
|
|
||||||
break;
|
|
||||||
case 2: //已发货
|
|
||||||
state = 'shipping';
|
|
||||||
// action = 'ship';
|
|
||||||
break;
|
|
||||||
case 3: //确认收货
|
|
||||||
state = 'received';
|
|
||||||
// action = 'receive';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// if (action && ship?.iState !== state) {
|
|
||||||
// await context.operate('ship', {
|
|
||||||
// id: await generateNewIdAsync(),
|
|
||||||
// action,
|
|
||||||
// data: {},
|
|
||||||
// filter: {
|
|
||||||
// id: shipId,
|
|
||||||
// }
|
|
||||||
// }, {});
|
|
||||||
// }
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (order) {
|
else if (shipOrder$ship && shipOrder$ship.length > 0) {
|
||||||
|
const order = shipOrder$ship[0].order;
|
||||||
|
const { pay$order: pays, } = order;
|
||||||
|
const pay = pays?.find((ele) => ele.entity === 'wpProduct');
|
||||||
|
if (shipId && pay) {
|
||||||
|
info = {
|
||||||
|
transaction_id: pay?.meta?.transaction_id
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (info) {
|
||||||
|
const result = await wechatInstance.getOrderState(info);
|
||||||
|
const { orderState, inComplaint } = result;
|
||||||
|
if (!inComplaint) {
|
||||||
|
//未处于纠纷中
|
||||||
|
let state = undefined;
|
||||||
|
// let action = undefined;
|
||||||
|
switch (orderState) {
|
||||||
|
case 1: //待发货
|
||||||
|
state = 'unshipped';
|
||||||
|
break;
|
||||||
|
case 2: //已发货
|
||||||
|
state = 'shipping';
|
||||||
|
// action = 'ship';
|
||||||
|
break;
|
||||||
|
case 3: //确认收货
|
||||||
|
state = 'received';
|
||||||
|
// action = 'receive';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.getShipState = getShipState;
|
exports.getShipState = getShipState;
|
||||||
|
|
@ -271,9 +313,9 @@ exports.getShipState = getShipState;
|
||||||
*/
|
*/
|
||||||
async function refreshtShipState(ship, context) {
|
async function refreshtShipState(ship, context) {
|
||||||
let ship2 = ship;
|
let ship2 = ship;
|
||||||
if (!ship2.iState || (!ship2.deposit$ship && !ship2.shipOrder$ship)) {
|
if (!ship2.iState) {
|
||||||
const ships = await context.select('ship', {
|
const ships = await context.select('ship', {
|
||||||
data: exports.fullShipProjection,
|
data: exports.shipProjection,
|
||||||
filter: {
|
filter: {
|
||||||
id: ship.id,
|
id: ship.id,
|
||||||
}
|
}
|
||||||
|
|
@ -283,58 +325,27 @@ async function refreshtShipState(ship, context) {
|
||||||
});
|
});
|
||||||
ship2 = ships[0];
|
ship2 = ships[0];
|
||||||
}
|
}
|
||||||
let application = undefined, info = undefined;
|
const state = await getShipState(context, ship2.id);
|
||||||
const { deposit$ship: deposits, shipOrder$ship: shipOrders, } = ship2;
|
let action = undefined;
|
||||||
if (deposits && deposits.length > 0) {
|
switch (state) {
|
||||||
//充值
|
case 'shipping': //已发货
|
||||||
const deposit = deposits[0];
|
action = 'ship';
|
||||||
const { pay$deposit } = deposit;
|
break;
|
||||||
application = pay$deposit?.[0].application;
|
case 'received': //确认收货
|
||||||
const meta = pay$deposit?.[0].meta;
|
action = 'receive';
|
||||||
info = {
|
break;
|
||||||
transaction_id: meta?.transaction_id
|
default:
|
||||||
};
|
action = undefined;
|
||||||
}
|
}
|
||||||
else if (shipOrders && shipOrders.length > 0) {
|
if (action && ship2.iState !== state) {
|
||||||
//订单
|
return await context.operate('ship', {
|
||||||
}
|
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||||
if (application) {
|
action,
|
||||||
const { type, config } = application;
|
data: {},
|
||||||
(0, assert_1.assert)(type === 'wechatMp');
|
filter: {
|
||||||
const { appId, appSecret } = config;
|
id: ship2.id,
|
||||||
const wechatInstance = oak_external_sdk_1.WechatSDK.getInstance(appId, 'wechatMp', appSecret);
|
|
||||||
if (info) {
|
|
||||||
const result = await wechatInstance.getOrderState(info);
|
|
||||||
const { orderState, inComplaint } = result;
|
|
||||||
if (!inComplaint) {
|
|
||||||
//未处于纠纷中
|
|
||||||
let state = undefined;
|
|
||||||
let action = undefined;
|
|
||||||
switch (orderState) {
|
|
||||||
case 1: //待发货
|
|
||||||
state = 'unshipped';
|
|
||||||
break;
|
|
||||||
case 2: //已发货
|
|
||||||
state = 'shipping';
|
|
||||||
action = 'ship';
|
|
||||||
break;
|
|
||||||
case 3: //确认收货
|
|
||||||
state = 'received';
|
|
||||||
action = 'receive';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (action && ship2.iState !== state) {
|
|
||||||
return await context.operate('ship', {
|
|
||||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
|
||||||
action,
|
|
||||||
data: {},
|
|
||||||
filter: {
|
|
||||||
id: ship2.id,
|
|
||||||
}
|
|
||||||
}, {});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}, {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.refreshtShipState = refreshtShipState;
|
exports.refreshtShipState = refreshtShipState;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,10 @@ type ExtraAddExpressOrderData = Omit<AddExpressOrderData, 'order_id' | 'openid'
|
||||||
export default class WechatMpShipDebug<ED extends EntityDict & BaseEntityDict, Context extends BackendRuntimeContext<ED>> implements ShipClazz<ED, Context> {
|
export default class WechatMpShipDebug<ED extends EntityDict & BaseEntityDict, Context extends BackendRuntimeContext<ED>> implements ShipClazz<ED, Context> {
|
||||||
private wechatMpShipId;
|
private wechatMpShipId;
|
||||||
private wechatMpShip?;
|
private wechatMpShip?;
|
||||||
private getReceiverInfo;
|
getReceiverInfo: (orderIds: string[], applicationId: string, context: Context) => Promise<{
|
||||||
|
openId?: string;
|
||||||
|
appWxId?: string;
|
||||||
|
}>;
|
||||||
private getExtraData;
|
private getExtraData;
|
||||||
constructor(wechatMpShipId: string, getReceiverInfo: (orderIds: string[], applicationId: string, context: Context) => Promise<{
|
constructor(wechatMpShipId: string, getReceiverInfo: (orderIds: string[], applicationId: string, context: Context) => Promise<{
|
||||||
openId?: string;
|
openId?: string;
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ const ShipServiceCodeDict = {
|
||||||
class WechatMpShipDebug {
|
class WechatMpShipDebug {
|
||||||
wechatMpShipId;
|
wechatMpShipId;
|
||||||
wechatMpShip;
|
wechatMpShip;
|
||||||
|
// 这个外部可能也需要调用
|
||||||
getReceiverInfo;
|
getReceiverInfo;
|
||||||
getExtraData;
|
getExtraData;
|
||||||
constructor(wechatMpShipId, getReceiverInfo, getExtraData) {
|
constructor(wechatMpShipId, getReceiverInfo, getExtraData) {
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ const watchers = [
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
projection: ship_1.fullShipProjection,
|
projection: ship_1.shipProjection,
|
||||||
fn: async (context, data) => {
|
fn: async (context, data) => {
|
||||||
const results = [];
|
const results = [];
|
||||||
for (const ship of data) {
|
for (const ship of data) {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ export type AspectDict<ED extends EntityDict> = {
|
||||||
withdrawAccountId?: string;
|
withdrawAccountId?: string;
|
||||||
}, context: BackendRuntimeContext<ED>) => Promise<EntityDict['withdraw']['CreateSingle']['data']>;
|
}, context: BackendRuntimeContext<ED>) => Promise<EntityDict['withdraw']['CreateSingle']['data']>;
|
||||||
getMpShipState: (params: {
|
getMpShipState: (params: {
|
||||||
depositId?: string;
|
shipId: string;
|
||||||
orderId?: string;
|
|
||||||
}, context: BackendRuntimeContext<ED>) => Promise<EntityDict['ship']['Schema']['iState']>;
|
}, context: BackendRuntimeContext<ED>) => Promise<EntityDict['ship']['Schema']['iState']>;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -11,41 +11,18 @@ import { getShipState } from '../utils/ship';
|
||||||
*/
|
*/
|
||||||
export async function getMpShipState(
|
export async function getMpShipState(
|
||||||
params: {
|
params: {
|
||||||
depositId?: string,
|
shipId: string,
|
||||||
orderId?: string,
|
|
||||||
},
|
},
|
||||||
context: BRC
|
context: BRC
|
||||||
) {
|
) {
|
||||||
const application = context.getApplication();
|
const application = context.getApplication();
|
||||||
const { type, } = application!;
|
const { type, } = application!;
|
||||||
if (type === 'wechatMp') {
|
if (type === 'wechatMp') {
|
||||||
const { depositId, orderId } = params;
|
const { shipId } = params;
|
||||||
if (depositId) {
|
const shipState = await getShipState(
|
||||||
//充值
|
context,
|
||||||
const deposits = await context.select('deposit', {
|
shipId,
|
||||||
data: {
|
) as EntityDict['ship']['Schema']['iState'];
|
||||||
id: 1,
|
return shipState;
|
||||||
iState: 1,
|
|
||||||
shipId: 1,
|
|
||||||
ship: {
|
|
||||||
id: 1,
|
|
||||||
iState: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
filter: {
|
|
||||||
id: depositId,
|
|
||||||
}
|
|
||||||
}, {});
|
|
||||||
const deposit = deposits[0] as EntityDict['deposit']['Schema'];
|
|
||||||
if (deposit) {
|
|
||||||
const shipState = await getShipState(
|
|
||||||
context,
|
|
||||||
deposit,
|
|
||||||
) as EntityDict['ship']['Schema']['iState'];
|
|
||||||
return shipState;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (orderId) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -162,7 +162,7 @@ export default OakComponent({
|
||||||
);
|
);
|
||||||
|
|
||||||
const { mode } = this.props;
|
const { mode } = this.props;
|
||||||
const succeedable =data["#oakLegalActions"]?.includes('succeedPaying');
|
const succeedable = data["#oakLegalActions"]?.includes('succeedPaying');
|
||||||
|
|
||||||
const payChannels = this.features.pay.getPayChannels();
|
const payChannels = this.features.pay.getPayChannels();
|
||||||
const offlines = this.features.cache.get('offlineAccount', {
|
const offlines = this.features.cache.get('offlineAccount', {
|
||||||
|
|
@ -400,7 +400,7 @@ export default OakComponent({
|
||||||
async success() {
|
async success() {
|
||||||
console.log('success');
|
console.log('success');
|
||||||
const mpShipState = await this.features.cache.exec('getMpShipState', {
|
const mpShipState = await this.features.cache.exec('getMpShipState', {
|
||||||
depositId,
|
shipId: next.shipId,
|
||||||
})
|
})
|
||||||
if (mpShipState === 'received') {
|
if (mpShipState === 'received') {
|
||||||
this.setMessage({
|
this.setMessage({
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ const triggers: Trigger<EntityDict, 'ship', BRC>[] = [
|
||||||
}
|
}
|
||||||
} as CreateTriggerCrossTxn<EntityDict, 'ship', BRC>,
|
} as CreateTriggerCrossTxn<EntityDict, 'ship', BRC>,
|
||||||
{
|
{
|
||||||
// todo,应该是所有的ship
|
// todo,deposit的ship和 shipClazz中有配置wechatShip且可获取openId的order的ship
|
||||||
entity: 'ship',
|
entity: 'ship',
|
||||||
name: '当虚拟的ship变为shipping状态时,调用小程序发货信息录入接口',
|
name: '当虚拟的ship变为shipping状态时,调用小程序发货信息录入接口',
|
||||||
action: 'ship',
|
action: 'ship',
|
||||||
|
|
@ -85,21 +85,47 @@ const triggers: Trigger<EntityDict, 'ship', BRC>[] = [
|
||||||
data: {
|
data: {
|
||||||
id: 1,
|
id: 1,
|
||||||
},
|
},
|
||||||
indexFrom: 0,
|
},
|
||||||
count: 1,
|
entity: 1,
|
||||||
|
entityId: 1,
|
||||||
|
shipServiceId: 1,
|
||||||
|
shipOrder$ship: {
|
||||||
|
$entity: 'shipOrder',
|
||||||
|
data: {
|
||||||
|
id: 1,
|
||||||
|
orderId: 1,
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
wechatMpShip: {
|
||||||
|
id: 1,
|
||||||
|
applicationId: 1,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
filter,
|
filter,
|
||||||
}, {});
|
}, {});
|
||||||
const { type, deposit$ship: deposits } = ship || {};
|
const { id: shipId, type, deposit$ship: deposits, shipOrder$ship, shipServiceId, entity, entityId, wechatMpShip } = ship || {};
|
||||||
if (type === 'virtual') {
|
if (deposits && deposits.length > 0) {
|
||||||
const deposit = deposits?.[0];
|
//充值 (此时该充值必定为受发货限制的小程序上的充值)
|
||||||
//当已发货的订单再次调用小程序发货信息录入接口视为重新发货(仅可重新发货一次)
|
|
||||||
//发货前先查询,检查是否为未同步微信端发货状态
|
//发货前先查询,检查是否为未同步微信端发货状态
|
||||||
const shipState = await getShipState(context, deposit);
|
const shipState = await getShipState(context, shipId!);
|
||||||
if (shipState === 'unshipped') {
|
if (shipState === 'unshipped') {
|
||||||
const result = await uploadShippingInfo({ depositId: deposit?.id, }, context);
|
await uploadShippingInfo(shipId!, context);
|
||||||
if (result) {
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (shipOrder$ship && shipOrder$ship.length > 0) {
|
||||||
|
//订单
|
||||||
|
const clazz = await getShipClazz(entity!, entityId!, context);
|
||||||
|
const { openId } = await clazz.getReceiverInfo(shipOrder$ship.map((ele) => ele.orderId!), wechatMpShip?.applicationId!, context);
|
||||||
|
if (openId) {
|
||||||
|
//当存在openId时调用小程序发货信息录入
|
||||||
|
const shipState = await getShipState(context, shipId!);
|
||||||
|
//当已发货的订单再次调用小程序发货信息录入接口视为重新发货(仅可重新发货一次)
|
||||||
|
if (shipState && ['unshipped', 'shipping'].includes(shipState)) {
|
||||||
|
// 发货/更换发货
|
||||||
|
await uploadShippingInfo(shipId!, context);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,10 @@ import { EntityDict as BaseEntityDict } from 'oak-domain/lib/types/Entity';
|
||||||
import BackendRuntimeContext from '../context/BackendRuntimeContext';
|
import BackendRuntimeContext from '../context/BackendRuntimeContext';
|
||||||
|
|
||||||
export default interface ShipClazz<ED extends EntityDict & BaseEntityDict, Context extends BackendRuntimeContext<ED>> {
|
export default interface ShipClazz<ED extends EntityDict & BaseEntityDict, Context extends BackendRuntimeContext<ED>> {
|
||||||
|
getReceiverInfo(orderIds: string[], applicationId: string, context: Context): Promise<{
|
||||||
|
openId?: string;
|
||||||
|
appWxId?: string;
|
||||||
|
}>;
|
||||||
// 是否可以使用这个接口下单
|
// 是否可以使用这个接口下单
|
||||||
available(shipServiceId: string, orderIds: string[], context: Context): Promise<boolean>;
|
available(shipServiceId: string, orderIds: string[], context: Context): Promise<boolean>;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,18 @@ import { WechatMpConfig } from '@project/oak-app-domain/Application/Schema';
|
||||||
import { generateNewIdAsync } from 'oak-domain/lib/utils/uuid';
|
import { generateNewIdAsync } from 'oak-domain/lib/utils/uuid';
|
||||||
import { UploadShipException } from '../types/Exception';
|
import { UploadShipException } from '../types/Exception';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
import { isMobile } from 'oak-domain/lib/utils/validator';
|
||||||
|
import { OakInputIllegalException } from 'oak-domain/lib/types';
|
||||||
|
import { unionBy } from 'oak-domain/lib/utils/lodash';
|
||||||
|
|
||||||
|
|
||||||
export const fullShipProjection: EntityDict['ship']['Projection'] = {
|
export const shipProjection: EntityDict['ship']['Projection'] = {
|
||||||
id: 1,
|
id: 1,
|
||||||
type: 1,
|
type: 1,
|
||||||
iState: 1,
|
iState: 1,
|
||||||
|
entity: 1,
|
||||||
|
entityId: 1,
|
||||||
|
extraShipId: 1,
|
||||||
shipService: {
|
shipService: {
|
||||||
id: 1,
|
id: 1,
|
||||||
name: 1,
|
name: 1,
|
||||||
|
|
@ -43,6 +49,9 @@ export const fullShipProjection: EntityDict['ship']['Projection'] = {
|
||||||
iState: 1,
|
iState: 1,
|
||||||
entity: 1,
|
entity: 1,
|
||||||
entityId: 1,
|
entityId: 1,
|
||||||
|
},
|
||||||
|
filter: {
|
||||||
|
iState: 'paid'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -70,11 +79,61 @@ export const fullShipProjection: EntityDict['ship']['Projection'] = {
|
||||||
iState: 1,
|
iState: 1,
|
||||||
entity: 1,
|
entity: 1,
|
||||||
entityId: 1,
|
entityId: 1,
|
||||||
|
},
|
||||||
|
filter: {
|
||||||
|
iState: 'paid'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
from: {
|
||||||
|
id: 1,
|
||||||
|
detail: 1,
|
||||||
|
name: 1,
|
||||||
|
phone: 1,
|
||||||
|
area: {
|
||||||
|
id: 1,
|
||||||
|
name: 1,
|
||||||
|
parent: {
|
||||||
|
id: 1,
|
||||||
|
name: 1,
|
||||||
|
parent: {
|
||||||
|
id: 1,
|
||||||
|
name: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
to: {
|
||||||
|
id: 1,
|
||||||
|
detail: 1,
|
||||||
|
name: 1,
|
||||||
|
phone: 1,
|
||||||
|
area: {
|
||||||
|
id: 1,
|
||||||
|
name: 1,
|
||||||
|
parent: {
|
||||||
|
id: 1,
|
||||||
|
name: 1,
|
||||||
|
parent: {
|
||||||
|
id: 1,
|
||||||
|
name: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手机号掩码(130****0000)
|
||||||
|
* @param phone
|
||||||
|
*/
|
||||||
|
export function maskPhone(phone: string) {
|
||||||
|
assert(isMobile(phone));
|
||||||
|
const start = phone.slice(3);
|
||||||
|
const end = phone.slice(-4);
|
||||||
|
return start + '****' + end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -84,74 +143,38 @@ export const fullShipProjection: EntityDict['ship']['Projection'] = {
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export async function uploadShippingInfo(
|
export async function uploadShippingInfo(
|
||||||
param: {
|
shipId: string,
|
||||||
depositId?: string,
|
|
||||||
orderId?: string,
|
|
||||||
},
|
|
||||||
context: BRC,
|
context: BRC,
|
||||||
) {
|
) {
|
||||||
const { depositId, orderId } = param;
|
const [ship] = await context.select('ship', {
|
||||||
if (depositId) {
|
data: shipProjection,
|
||||||
const [deposit] = await context.select('deposit', {
|
filter: {
|
||||||
data: {
|
id: shipId,
|
||||||
id: 1,
|
}
|
||||||
iState: 1,
|
}, { forUpdate: true });
|
||||||
shipId: 1,
|
const { deposit$ship: deposits, shipOrder$ship, type: shipType, extraShipId, shipService, from, to } = ship;
|
||||||
ship: {
|
// assert(iState === 'unshipped'); //可更改一次发货信息
|
||||||
id: 1,
|
|
||||||
iState: 1,
|
//发货信息录入前检查小程序订单发货状态
|
||||||
type: 1,
|
const shipState = await getShipState(context, shipId);
|
||||||
},
|
const now = dayjs().format();
|
||||||
pay$deposit: {
|
|
||||||
$entity: 'pay',
|
const application = context.getApplication();
|
||||||
data: {
|
const { type, config } = application!;
|
||||||
id: 1,
|
assert(type === 'wechatMp');
|
||||||
entity: 1,
|
const { appId, appSecret } = config as WechatMpConfig;
|
||||||
entityId: 1,
|
const wechatInstance = WechatSDK.getInstance(
|
||||||
meta: 1,
|
appId,
|
||||||
applicationId: 1,
|
'wechatMp',
|
||||||
},
|
appSecret,
|
||||||
filter: {
|
) as WechatMpInstance;
|
||||||
iState: 'paid',
|
|
||||||
},
|
if (deposits && deposits.length > 0 && shipState === 'unshipped') {
|
||||||
indexFrom: 0,
|
//充值
|
||||||
count: 1,
|
assert(deposits.length === 1);
|
||||||
},
|
const [deposit] = deposits;
|
||||||
},
|
const { pay$deposit: pays, } = deposit;
|
||||||
filter: {
|
|
||||||
id: depositId,
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
blockTrigger: true,
|
|
||||||
forUpdate: true,
|
|
||||||
});
|
|
||||||
const { pay$deposit: pays, } = deposit || {};
|
|
||||||
const pay = pays?.[0];
|
const pay = pays?.[0];
|
||||||
const applicationId = pay?.applicationId;
|
|
||||||
assert(applicationId);
|
|
||||||
const [application] = await context.select('application', {
|
|
||||||
data: {
|
|
||||||
id: 1,
|
|
||||||
type: 1,
|
|
||||||
config: 1.
|
|
||||||
},
|
|
||||||
filter: {
|
|
||||||
id: applicationId,
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
blockTrigger: true,
|
|
||||||
forUpdate: true,
|
|
||||||
})
|
|
||||||
const { type, config } = application!;
|
|
||||||
assert(type === 'wechatMp');
|
|
||||||
const { appId, appSecret } = config as WechatMpConfig;
|
|
||||||
|
|
||||||
const wechatInstance = WechatSDK.getInstance(
|
|
||||||
appId,
|
|
||||||
'wechatMp',
|
|
||||||
appSecret,
|
|
||||||
) as WechatMpInstance;
|
|
||||||
|
|
||||||
const meta = pay?.meta as {
|
const meta = pay?.meta as {
|
||||||
transaction_id: string;
|
transaction_id: string;
|
||||||
payer: {
|
payer: {
|
||||||
|
|
@ -168,29 +191,71 @@ export async function uploadShippingInfo(
|
||||||
shipping_list: [
|
shipping_list: [
|
||||||
{
|
{
|
||||||
item_desc: '账户充值',
|
item_desc: '账户充值',
|
||||||
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
upload_time: dayjs().format(),
|
upload_time: now,
|
||||||
payer: {
|
payer: {
|
||||||
openid: meta?.payer?.openid,
|
openid: meta?.payer?.openid,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
const result = await wechatInstance.uploadShippingInfo(shipInfo);
|
const result = await wechatInstance.uploadShippingInfo(shipInfo);
|
||||||
if (result?.errcode === 0) {
|
if (result?.errcode !== 0) {
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
console.error(JSON.stringify(result));
|
console.error(JSON.stringify(result));
|
||||||
throw new UploadShipException(result?.message);
|
throw new UploadShipException(result?.message);
|
||||||
}
|
}
|
||||||
|
} else if (shipOrder$ship && shipOrder$ship.length > 0 && shipState && ['unshipped', 'shipping'].includes(shipState)) {
|
||||||
|
//订单 每笔微信支付调用一次接口
|
||||||
|
const orders = shipOrder$ship.map((ele) => ele.order);
|
||||||
|
const fromPhoneStr = maskPhone(from!.phone!);
|
||||||
|
const toPhoneStr = maskPhone(to!.phone!);
|
||||||
|
for (const order of orders) {
|
||||||
|
const { pay$order, desc } = order;
|
||||||
|
const wechatPay = pay$order!.find((ele) => ele.entity === 'wpProduct');
|
||||||
|
const meta = wechatPay?.meta as {
|
||||||
|
transaction_id: string;
|
||||||
|
payer: {
|
||||||
|
openid: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
let shippingList: Array<Object> = [];
|
||||||
|
if (shipType === 'express') {
|
||||||
|
shippingList = [
|
||||||
|
{
|
||||||
|
tracking_no: extraShipId,
|
||||||
|
express_company: shipService?.shipCompany?.wechatMpName,
|
||||||
|
item_desc: desc,
|
||||||
|
contact: {
|
||||||
|
consignor_contact: fromPhoneStr,
|
||||||
|
receiver_contact: toPhoneStr,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
} else if (shipType === 'pickup') {
|
||||||
|
shippingList = [{
|
||||||
|
item_desc: desc,
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
const shipInfo: any = {
|
||||||
|
order_key: {
|
||||||
|
order_number_type: 2,
|
||||||
|
transaction_id: meta?.transaction_id,
|
||||||
|
},
|
||||||
|
logistic_type: shipType === 'express' ? 1 : 4,
|
||||||
|
delivery_mode: 1,
|
||||||
|
shipping_list: shippingList,
|
||||||
|
upload_time: now,
|
||||||
|
payer: {
|
||||||
|
openid: meta?.payer?.openid,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await wechatInstance.uploadShippingInfo(shipInfo);
|
||||||
|
if (result?.errcode !== 0) {
|
||||||
|
console.error(JSON.stringify(result));
|
||||||
|
throw new UploadShipException(result?.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (orderId) {
|
|
||||||
//订单
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -202,98 +267,74 @@ export async function uploadShippingInfo(
|
||||||
*/
|
*/
|
||||||
export async function getShipState(
|
export async function getShipState(
|
||||||
context: BRC,
|
context: BRC,
|
||||||
deposit?: EntityDict['deposit']['Schema'],
|
shipId: string,
|
||||||
order?: EntityDict['order']['Schema'],
|
|
||||||
) {
|
) {
|
||||||
|
const [ship] = await context.select('ship', {
|
||||||
|
data: shipProjection,
|
||||||
|
filter: {
|
||||||
|
id: shipId,
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
blockTrigger: true,
|
||||||
|
forUpdate: true
|
||||||
|
});
|
||||||
|
|
||||||
|
assert(ship);
|
||||||
|
const { deposit$ship: deposits, shipOrder$ship } = ship;
|
||||||
|
|
||||||
const application = context.getApplication();
|
const application = context.getApplication();
|
||||||
const { type, config } = application!;
|
const { type, config } = application!;
|
||||||
assert(type === 'wechatMp');
|
assert(type === 'wechatMp');
|
||||||
const { appId, appSecret } = config as WechatMpConfig;
|
const { appId, appSecret } = config as WechatMpConfig;
|
||||||
|
|
||||||
const wechatInstance = WechatSDK.getInstance(
|
const wechatInstance = WechatSDK.getInstance(
|
||||||
appId,
|
appId,
|
||||||
'wechatMp',
|
'wechatMp',
|
||||||
appSecret,
|
appSecret,
|
||||||
) as WechatMpInstance;
|
) as WechatMpInstance;
|
||||||
|
|
||||||
if (deposit) {
|
let info = undefined;
|
||||||
|
if (deposits && deposits.length > 0) {
|
||||||
//充值
|
//充值
|
||||||
let deposit2 = deposit;
|
const [deposit] = deposits;
|
||||||
const deposits = await context.select('deposit', {
|
const { pay$deposit: pays, } = deposit;
|
||||||
data: {
|
|
||||||
id: 1,
|
|
||||||
iState: 1,
|
|
||||||
pay$deposit: {
|
|
||||||
$entity: 'pay',
|
|
||||||
data: {
|
|
||||||
id: 1,
|
|
||||||
iState: 1,
|
|
||||||
meta: 1,
|
|
||||||
entity: 1,
|
|
||||||
entityId: 1,
|
|
||||||
},
|
|
||||||
filter: {
|
|
||||||
iState: 'paid',
|
|
||||||
},
|
|
||||||
indexFrom: 0,
|
|
||||||
count: 1,
|
|
||||||
},
|
|
||||||
shipId: 1,
|
|
||||||
ship: {
|
|
||||||
id: 1,
|
|
||||||
type: 1,
|
|
||||||
iState: 1,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
filter: {
|
|
||||||
id: deposit?.id,
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
blockTrigger: true,
|
|
||||||
forUpdate: true,
|
|
||||||
});
|
|
||||||
deposit2 = deposits[0] as typeof deposit;
|
|
||||||
const { pay$deposit: pays, ship, shipId } = deposit2;
|
|
||||||
const pay = pays?.[0];
|
const pay = pays?.[0];
|
||||||
if (shipId && pay) {
|
if (shipId && pay) {
|
||||||
const info = {
|
info = {
|
||||||
|
transaction_id: (pay?.meta as { transaction_id: string })?.transaction_id
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else if (shipOrder$ship && shipOrder$ship.length > 0) {
|
||||||
|
const order = shipOrder$ship[0].order;
|
||||||
|
const { pay$order: pays, } = order;
|
||||||
|
const pay = pays?.find((ele) => ele.entity === 'wpProduct');
|
||||||
|
if (shipId && pay) {
|
||||||
|
info = {
|
||||||
transaction_id: (pay?.meta as { transaction_id: string })?.transaction_id
|
transaction_id: (pay?.meta as { transaction_id: string })?.transaction_id
|
||||||
};
|
};
|
||||||
const result = await wechatInstance.getOrderState(info);
|
|
||||||
const { orderState, inComplaint } = result;
|
|
||||||
if (!inComplaint) {
|
|
||||||
//未处于纠纷中
|
|
||||||
let state = undefined;
|
|
||||||
// let action = undefined;
|
|
||||||
switch (orderState) {
|
|
||||||
case 1: //待发货
|
|
||||||
state = 'unshipped';
|
|
||||||
break;
|
|
||||||
case 2: //已发货
|
|
||||||
state = 'shipping';
|
|
||||||
// action = 'ship';
|
|
||||||
break;
|
|
||||||
case 3: //确认收货
|
|
||||||
state = 'received';
|
|
||||||
// action = 'receive';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// if (action && ship?.iState !== state) {
|
|
||||||
// await context.operate('ship', {
|
|
||||||
// id: await generateNewIdAsync(),
|
|
||||||
// action,
|
|
||||||
// data: {},
|
|
||||||
// filter: {
|
|
||||||
// id: shipId,
|
|
||||||
// }
|
|
||||||
// }, {});
|
|
||||||
// }
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (order) {
|
if (info) {
|
||||||
|
const result = await wechatInstance.getOrderState(info);
|
||||||
|
const { orderState, inComplaint } = result;
|
||||||
|
if (!inComplaint) {
|
||||||
|
//未处于纠纷中
|
||||||
|
let state = undefined;
|
||||||
|
// let action = undefined;
|
||||||
|
switch (orderState) {
|
||||||
|
case 1: //待发货
|
||||||
|
state = 'unshipped';
|
||||||
|
break;
|
||||||
|
case 2: //已发货
|
||||||
|
state = 'shipping';
|
||||||
|
// action = 'ship';
|
||||||
|
break;
|
||||||
|
case 3: //确认收货
|
||||||
|
state = 'received';
|
||||||
|
// action = 'receive';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -309,9 +350,9 @@ export async function refreshtShipState(
|
||||||
context: BRC,
|
context: BRC,
|
||||||
) {
|
) {
|
||||||
let ship2 = ship;
|
let ship2 = ship;
|
||||||
if (!ship2.iState || (!ship2.deposit$ship && !ship2.shipOrder$ship)) {
|
if (!ship2.iState) {
|
||||||
const ships = await context.select('ship', {
|
const ships = await context.select('ship', {
|
||||||
data: fullShipProjection,
|
data: shipProjection,
|
||||||
filter: {
|
filter: {
|
||||||
id: ship.id,
|
id: ship.id,
|
||||||
}
|
}
|
||||||
|
|
@ -321,62 +362,26 @@ export async function refreshtShipState(
|
||||||
});
|
});
|
||||||
ship2 = ships[0] as typeof ship;
|
ship2 = ships[0] as typeof ship;
|
||||||
}
|
}
|
||||||
let application = undefined, info = undefined;
|
const state = await getShipState(context, ship2.id!);
|
||||||
const { deposit$ship: deposits, shipOrder$ship: shipOrders, } = ship2;
|
let action = undefined;
|
||||||
if (deposits && deposits.length > 0) {
|
switch (state) {
|
||||||
//充值
|
case 'shipping': //已发货
|
||||||
const deposit = deposits[0];
|
action = 'ship';
|
||||||
const { pay$deposit } = deposit;
|
break;
|
||||||
application = pay$deposit?.[0]!.application;
|
case 'received': //确认收货
|
||||||
const meta = pay$deposit?.[0]!.meta;
|
action = 'receive';
|
||||||
info = {
|
break;
|
||||||
transaction_id: (meta as { transaction_id: string })?.transaction_id
|
default:
|
||||||
};
|
action = undefined;
|
||||||
}
|
}
|
||||||
else if (shipOrders && shipOrders.length > 0) {
|
if (action && ship2.iState !== state) {
|
||||||
//订单
|
return await context.operate('ship', {
|
||||||
}
|
id: await generateNewIdAsync(),
|
||||||
if (application) {
|
action,
|
||||||
const { type, config } = application!;
|
data: {},
|
||||||
assert(type === 'wechatMp');
|
filter: {
|
||||||
const { appId, appSecret } = config as WechatMpConfig;
|
id: ship2.id,
|
||||||
const wechatInstance = WechatSDK.getInstance(
|
|
||||||
appId,
|
|
||||||
'wechatMp',
|
|
||||||
appSecret,
|
|
||||||
) as WechatMpInstance;
|
|
||||||
|
|
||||||
if (info) {
|
|
||||||
const result = await wechatInstance.getOrderState(info);
|
|
||||||
const { orderState, inComplaint } = result;
|
|
||||||
if (!inComplaint) {
|
|
||||||
//未处于纠纷中
|
|
||||||
let state = undefined;
|
|
||||||
let action = undefined;
|
|
||||||
switch (orderState) {
|
|
||||||
case 1: //待发货
|
|
||||||
state = 'unshipped';
|
|
||||||
break;
|
|
||||||
case 2: //已发货
|
|
||||||
state = 'shipping';
|
|
||||||
action = 'ship';
|
|
||||||
break;
|
|
||||||
case 3: //确认收货
|
|
||||||
state = 'received';
|
|
||||||
action = 'receive'
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (action && ship2.iState !== state) {
|
|
||||||
return await context.operate('ship', {
|
|
||||||
id: await generateNewIdAsync(),
|
|
||||||
action,
|
|
||||||
data: {},
|
|
||||||
filter: {
|
|
||||||
id: ship2.id,
|
|
||||||
}
|
|
||||||
}, {});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}, {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,7 +3,7 @@ import { EntityDict } from '../oak-app-domain';
|
||||||
import { BRC } from '../types/RuntimeCxt';
|
import { BRC } from '../types/RuntimeCxt';
|
||||||
import { OperationResult } from 'oak-domain/lib/types';
|
import { OperationResult } from 'oak-domain/lib/types';
|
||||||
import { mergeOperationResult } from 'oak-domain/lib/utils/operationResult';
|
import { mergeOperationResult } from 'oak-domain/lib/utils/operationResult';
|
||||||
import { fullShipProjection, refreshtShipState } from '../utils/ship';
|
import { shipProjection, refreshtShipState } from '../utils/ship';
|
||||||
|
|
||||||
const QUERY_PAYING_STATE_GAP = process.env.NODE_ENV === 'production' ? 600 * 1000 : 60 * 1000;
|
const QUERY_PAYING_STATE_GAP = process.env.NODE_ENV === 'production' ? 600 * 1000 : 60 * 1000;
|
||||||
|
|
||||||
|
|
@ -20,7 +20,7 @@ const watchers: Watcher<EntityDict, 'ship', BRC>[] = [
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
projection: fullShipProjection,
|
projection: shipProjection,
|
||||||
fn: async (context, data) => {
|
fn: async (context, data) => {
|
||||||
const results = [] as OperationResult<EntityDict>[];
|
const results = [] as OperationResult<EntityDict>[];
|
||||||
for (const ship of data) {
|
for (const ship of data) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue