小程序确认收货组件显示调整

This commit is contained in:
lxy 2025-08-15 10:41:41 +08:00
parent d50130ce3a
commit 7dc0f8c66c
27 changed files with 528 additions and 386 deletions

View File

@ -15,4 +15,7 @@ export type AspectDict<ED extends EntityDict> = {
type: "html";
data: string;
}>;
shipConfirmSuccess: (params: {
shipId: string;
}, context: BackendRuntimeContext<ED>) => Promise<Boolean>;
};

View File

@ -1,8 +1,9 @@
import { getWithdrawCreateData } from './withdraw';
import { getExpressPrintInfo, getMpShipState } from './ship';
import { getExpressPrintInfo, getMpShipState, shipConfirmSuccess } from './ship';
const aspectDict = {
getMpShipState,
getWithdrawCreateData,
getExpressPrintInfo,
shipConfirmSuccess,
};
export default aspectDict;

View File

@ -16,3 +16,9 @@ export declare function getExpressPrintInfo(params: {
type: "html";
data: string;
}>;
/**
* ship状态
*/
export declare function shipConfirmSuccess(params: {
shipId: string;
}, context: BRC): Promise<boolean>;

View File

@ -1,6 +1,7 @@
import { OakPreConditionUnsetException } from 'oak-domain/lib/types';
import { getOrderShipState } from '../utils/ship';
import { getShipClazz } from '../utils/shipClazz';
import { generateNewIdAsync } from 'oak-domain/lib/utils/uuid';
/**
* 获取小程序订单发货状态
* @param params
@ -39,3 +40,42 @@ export async function getExpressPrintInfo(params, context) {
const clazz = await getShipClazz(entity, entityId, context);
return await clazz.getPrintInfo(shipId, context);
}
/**
* 小程序确认收货组件成功后更新ship状态
*/
export async function shipConfirmSuccess(params, context) {
const application = context.getApplication();
const { type, } = application;
if (type === 'wechatMp') {
try {
const { shipId } = params;
const shipState = await getOrderShipState(context, shipId);
if (shipState === 'received') {
//微信端已确认收货
const [ship] = await context.select('ship', {
data: {
id: 1,
iState: 1,
}, filter: {
id: shipId,
}
}, { forUpdate: true });
if (ship.iState === 'receiving') {
await context.operate('ship', {
id: await generateNewIdAsync(),
action: 'succeedReceiving',
data: {},
filter: {
id: shipId,
},
}, {});
return true;
}
}
}
catch (err) {
return false;
}
}
return false;
}

View File

@ -21,13 +21,8 @@ declare const List: <T extends keyof EntityDict>(props: ReactComponentProps<Enti
rowSelection?: any;
hideHeader?: boolean | undefined;
disableSerialNumber?: boolean | undefined;
size?: "small" | "middle" | "large" | undefined;
scroll?: ({
x?: string | number | true | undefined;
y?: string | number | undefined;
} & {
scrollToFirstRowOnChange?: boolean | undefined;
}) | undefined;
size?: "small" | "large" | "middle" | undefined;
scroll?: any;
empty?: React.ReactNode;
opWidth?: number | undefined;
ellipsis?: boolean | undefined;
@ -48,7 +43,7 @@ declare const ListPro: <T extends keyof EntityDict>(props: {
tablePagination?: any;
rowSelection?: any;
disableSerialNumber?: boolean | undefined;
size?: "small" | "middle" | "large" | undefined;
size?: "small" | "large" | "middle" | undefined;
scroll?: any;
empty?: any;
opWidth?: number | undefined;

View File

@ -347,30 +347,43 @@ export default OakComponent({
},
success: async () => {
console.log('success');
const { result: mpShipState } = await this.features.cache.exec('getMpShipState', {
// const { result: mpShipState } = await this.features.cache.exec('getMpShipState', {
// shipId: ship.id,
// })
// if (mpShipState === 'received') {
// await this.features.cache.operate('ship',
// [{
// id: await generateNewIdAsync(),
// action: 'succeedReceiving',
// data: {},
// filter: {
// id: ship.id,
// },
// }]
// );
// this.setMessage({
// type: 'success',
// content: this.t('ship.success')
// });
// } else {
// console.log(mpShipState);
// this.reRender();
// // this.setMessage({
// // type: 'warning',
// // content: this.t('ship.wait'),
// // })
// }
const { result } = await this.features.cache.exec('shipConfirmSuccess', {
shipId: ship.id,
});
if (mpShipState === 'received') {
await this.features.cache.operate('ship', [{
id: await generateNewIdAsync(),
action: 'succeedReceiving',
data: {},
filter: {
id: ship.id,
},
}]);
if (result) {
this.setMessage({
type: 'success',
content: this.t('ship.success')
});
}
else {
console.log(mpShipState);
this.reRender();
// this.setMessage({
// type: 'warning',
// content: this.t('ship.wait'),
// })
}
},
fail: () => {

View File

@ -360,30 +360,43 @@ export default OakComponent({
},
success: async () => {
console.log('success');
const { result: mpShipState } = await this.features.cache.exec('getMpShipState', {
// const { result: mpShipState } = await this.features.cache.exec('getMpShipState', {
// shipId,
// })
// if (mpShipState === 'received') {
// await this.features.cache.operate('ship',
// [{
// id: await generateNewIdAsync(),
// action: 'succeedReceiving',
// data: {},
// filter: {
// id: shipId,
// },
// }]
// );
// this.reRender();
// this.setMessage({
// type: 'success',
// content: this.t('ship.success')
// });
// } else {
// console.log(mpShipState);
// // this.setMessage({
// // type: 'warning',
// // content: this.t('ship.wait'),
// // })
// this.reRender();
// }
const { result } = await this.features.cache.exec('shipConfirmSuccess', {
shipId,
});
if (mpShipState === 'received') {
await this.features.cache.operate('ship', [{
id: await generateNewIdAsync(),
action: 'succeedReceiving',
data: {},
filter: {
id: shipId,
},
}]);
this.reRender();
if (result) {
this.setMessage({
type: 'success',
content: this.t('ship.success')
});
}
else {
console.log(mpShipState);
// this.setMessage({
// type: 'warning',
// content: this.t('ship.wait'),
// })
this.reRender();
}
},
@ -422,16 +435,27 @@ export default OakComponent({
const unsub = await this.subDataEvents([
`${DATA_SUBSCRIBER_KEYS.payStateChanged}-${oakId}`,
`${DATA_SUBSCRIBER_KEYS.depositStateChanged}-${oakId}`
]);
], async (event, opRecords) => {
for (const record of opRecords) {
console.log(record);
if (record.e === 'pay' || record.e === 'deposit') {
const { f } = record;
const [pay] = this.features.cache.get('pay', {
data: baseProjection,
filter: f,
});
console.log(JSON.stringify(pay));
}
}
});
let depositUnsub = undefined;
const { depositId } = this.state;
if (depositId) {
const depositUnsub = await this.subDataEvents([`${DATA_SUBSCRIBER_KEYS.shipStateChanged}-${depositId}`]);
this.setState({
depositUnsub,
});
depositUnsub = await this.subDataEvents([`${DATA_SUBSCRIBER_KEYS.shipStateChanged}-${depositId}`]);
}
this.setState({
unsub,
depositUnsub,
});
},
async mature() {

View File

@ -8,7 +8,7 @@ const timers = [
filter: {
type: 'express',
iState: {
$nin: ['received', 'cancelled', 'rejected', 'receiving'],
$nin: ['received', 'cancelled', 'rejected', 'receiving', 'unshipped'],
},
entity: {
$exists: true
@ -41,7 +41,7 @@ const timers = [
},
{
name: '同步微信小程序虚拟、自提ship状态',
cron: '0 0/2 * * * ?',
cron: '0 * * * * ?',
entity: 'ship',
filter: {
type: {
@ -53,6 +53,7 @@ const timers = [
},
projection: {
id: 1,
iState: 1,
},
fn: async (context, data) => {
const results = [];
@ -68,21 +69,21 @@ const timers = [
return results.reduce((prev, cur) => mergeOperationResult(prev, cur));
},
},
{
name: '对虚拟或自提类型的ship自动发货',
cron: '0 * * * * ?',
entity: 'ship',
filter: {
type: {
$in: ['virtual', 'pickup'],
},
iState: 'unshipped',
},
projection: {
id: 1,
},
action: 'ship',
actionData: {},
},
// {
// name: '对虚拟或自提类型的ship自动发货',
// cron: '0 * * * * ?',
// entity: 'ship',
// filter: {
// type: {
// $in: ['virtual', 'pickup'],
// },
// iState: 'unshipped',
// },
// projection: {
// id: 1,
// },
// action: 'ship',
// actionData: {},
// },
];
export default timers;

View File

@ -3,6 +3,7 @@ import { DATA_SUBSCRIBER_KEYS } from '../config/constants';
import assert from 'assert';
import { getShipClazz, getShipEntity } from '../utils/shipClazz';
import { notifyConfirmReceive, uploadShippingInfo } from '../utils/ship';
import { promisify } from 'util';
const triggers = [
{
name: '当虚拟或自提类型的ship创建后自动发货',
@ -14,14 +15,27 @@ const triggers = [
check: (operation) => ['virtual', 'pickup'].includes(operation.data.type),
fn: async ({ ids }, context, option) => {
for (const id of ids) {
await context.operate('ship', {
id: await generateNewIdAsync(),
action: 'ship',
data: {},
const [ship] = await context.select('ship', {
data: {
id: 1,
iState: 1,
type: 1,
},
filter: {
id,
id
}
}, option);
}, { dontCollect: true, forUpdate: true });
const { iState, type } = ship;
if (iState && ['unshipped', 'unknown'].includes(iState) && type && ['virtual', 'pickup'].includes(type)) {
await context.operate('ship', {
id: await generateNewIdAsync(),
action: 'ship',
data: {},
filter: {
id,
}
}, option);
}
}
return;
},
@ -48,7 +62,7 @@ const triggers = [
id
}
}, { dontCollect: true, forUpdate: true });
const { entity, entityId } = ship;
const { entity, entityId } = ship || {};
if (entity && entityId) {
const shipClazz = await getShipClazz(entity, entityId, context);
const extraShipId = await shipClazz.eOrder(id, context);
@ -116,6 +130,9 @@ const triggers = [
const { id: shipId, type, deposit$ship: deposits, shipOrder$ship, shipServiceId, entity, entityId, wechatMpShip } = ship || {};
if (deposits && deposits.length > 0) {
//充值 (此时该充值必定为受发货限制的小程序上的充值)
//等待5秒以避免小程序订单号查询不到
const sleep = promisify(setTimeout);
await sleep(5 * 1000);
await uploadShippingInfo(shipId, context);
cnt++;
}
@ -448,49 +465,5 @@ const triggers = [
return count;
},
},
{
name: '当虚拟ship自动确认收货后更新deposit状态',
entity: 'ship',
action: 'update',
when: 'after',
asRoot: true,
fn: async ({ operation }, context, option) => {
const { filter, id, data } = operation;
const ships = await context.select('ship', {
data: {
id: 1,
iState: 1,
type: 1,
deposit$ship: {
$entity: 'deposit',
data: {
id: 1,
iState: 1,
}
}
},
filter,
}, { forUpdate: true });
let count = 0;
const virtualShips = ships?.filter((ele) => ele.type === 'virtual');
if (virtualShips && virtualShips.length > 0) {
for (const ship of virtualShips) {
const deposit = ship.deposit$ship?.[0];
if (deposit && deposit.iState === 'shipped') {
await context.operate('deposit', {
id: await generateNewIdAsync(),
action: 'succeed',
data: {},
filter: {
id: deposit.id,
}
}, option);
count++;
}
}
}
return count;
}
},
];
export default triggers;

View File

@ -6,6 +6,6 @@ import { BRC } from '../types/RuntimeCxt';
* @param context
* @param refunds
*/
export declare function updateWithdrawState(context: BRC, id: string): Promise<0 | 1>;
export declare function updateWithdrawState(context: BRC, id: string): Promise<1 | 0>;
declare const triggers: Trigger<EntityDict, 'withdraw', BRC>[];
export default triggers;

View File

@ -1,34 +1,34 @@
import { mergeOperationResult } from 'oak-domain/lib/utils/operationResult';
import { shipProjection, refreshShipState } from '../utils/ship';
const QUERY_PAYING_STATE_GAP = process.env.NODE_ENV === 'production' ? 3600 * 1000 : 60 * 1000;
const watchers = [
{
name: '对shipping状态的物流同步其真实状态',
entity: 'ship',
filter: async () => {
const now = Date.now();
return {
type: 'express',
iState: 'shipping',
$$updateAt$$: {
$lte: now - QUERY_PAYING_STATE_GAP,
},
};
},
projection: shipProjection,
fn: async (context, data) => {
const results = [];
for (const ship of data) {
const result = await refreshShipState(ship.id, context);
if (result) {
results.push(result);
}
}
if (results.length === 0) {
return {};
}
return results.reduce((prev, cur) => mergeOperationResult(prev, cur));
}
}
// {
// name: '对shipping状态的物流同步其真实状态',
// entity: 'ship',
// filter: async () => {
// const now = Date.now();
// return {
// type: 'express',
// iState: 'shipping',
// $$updateAt$$: {
// $lte: now - QUERY_PAYING_STATE_GAP,
// },
// };
// },
// projection: shipProjection,
// fn: async (context, data) => {
// const results = [] as OperationResult<EntityDict>[];
// for (const ship of data) {
// const result = await refreshShipState(ship.id!, context);
// if (result) {
// results.push(result);
// }
// }
// if (results.length === 0) {
// return {};
// }
// return results.reduce(
// (prev, cur) => mergeOperationResult(prev, cur)
// );
// }
// }
];
export default watchers;

View File

@ -15,4 +15,7 @@ export type AspectDict<ED extends EntityDict> = {
type: "html";
data: string;
}>;
shipConfirmSuccess: (params: {
shipId: string;
}, context: BackendRuntimeContext<ED>) => Promise<Boolean>;
};

View File

@ -6,5 +6,6 @@ const aspectDict = {
getMpShipState: ship_1.getMpShipState,
getWithdrawCreateData: withdraw_1.getWithdrawCreateData,
getExpressPrintInfo: ship_1.getExpressPrintInfo,
shipConfirmSuccess: ship_1.shipConfirmSuccess,
};
exports.default = aspectDict;

View File

@ -16,3 +16,9 @@ export declare function getExpressPrintInfo(params: {
type: "html";
data: string;
}>;
/**
* ship状态
*/
export declare function shipConfirmSuccess(params: {
shipId: string;
}, context: BRC): Promise<boolean>;

View File

@ -1,9 +1,10 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getExpressPrintInfo = exports.getMpShipState = void 0;
exports.shipConfirmSuccess = exports.getExpressPrintInfo = exports.getMpShipState = void 0;
const types_1 = require("oak-domain/lib/types");
const ship_1 = require("../utils/ship");
const shipClazz_1 = require("../utils/shipClazz");
const uuid_1 = require("oak-domain/lib/utils/uuid");
/**
* 获取小程序订单发货状态
* @param params
@ -44,3 +45,43 @@ async function getExpressPrintInfo(params, context) {
return await clazz.getPrintInfo(shipId, context);
}
exports.getExpressPrintInfo = getExpressPrintInfo;
/**
* 小程序确认收货组件成功后更新ship状态
*/
async function shipConfirmSuccess(params, context) {
const application = context.getApplication();
const { type, } = application;
if (type === 'wechatMp') {
try {
const { shipId } = params;
const shipState = await (0, ship_1.getOrderShipState)(context, shipId);
if (shipState === 'received') {
//微信端已确认收货
const [ship] = await context.select('ship', {
data: {
id: 1,
iState: 1,
}, filter: {
id: shipId,
}
}, { forUpdate: true });
if (ship.iState === 'receiving') {
await context.operate('ship', {
id: await (0, uuid_1.generateNewIdAsync)(),
action: 'succeedReceiving',
data: {},
filter: {
id: shipId,
},
}, {});
return true;
}
}
}
catch (err) {
return false;
}
}
return false;
}
exports.shipConfirmSuccess = shipConfirmSuccess;

View File

@ -10,7 +10,7 @@ const timers = [
filter: {
type: 'express',
iState: {
$nin: ['received', 'cancelled', 'rejected', 'receiving'],
$nin: ['received', 'cancelled', 'rejected', 'receiving', 'unshipped'],
},
entity: {
$exists: true
@ -43,7 +43,7 @@ const timers = [
},
{
name: '同步微信小程序虚拟、自提ship状态',
cron: '0 0/2 * * * ?',
cron: '0 * * * * ?',
entity: 'ship',
filter: {
type: {
@ -55,6 +55,7 @@ const timers = [
},
projection: {
id: 1,
iState: 1,
},
fn: async (context, data) => {
const results = [];
@ -70,21 +71,21 @@ const timers = [
return results.reduce((prev, cur) => (0, operationResult_1.mergeOperationResult)(prev, cur));
},
},
{
name: '对虚拟或自提类型的ship自动发货',
cron: '0 * * * * ?',
entity: 'ship',
filter: {
type: {
$in: ['virtual', 'pickup'],
},
iState: 'unshipped',
},
projection: {
id: 1,
},
action: 'ship',
actionData: {},
},
// {
// name: '对虚拟或自提类型的ship自动发货',
// cron: '0 * * * * ?',
// entity: 'ship',
// filter: {
// type: {
// $in: ['virtual', 'pickup'],
// },
// iState: 'unshipped',
// },
// projection: {
// id: 1,
// },
// action: 'ship',
// actionData: {},
// },
];
exports.default = timers;

View File

@ -6,6 +6,7 @@ const constants_1 = require("../config/constants");
const assert_1 = tslib_1.__importDefault(require("assert"));
const shipClazz_1 = require("../utils/shipClazz");
const ship_1 = require("../utils/ship");
const util_1 = require("util");
const triggers = [
{
name: '当虚拟或自提类型的ship创建后自动发货',
@ -17,14 +18,27 @@ const triggers = [
check: (operation) => ['virtual', 'pickup'].includes(operation.data.type),
fn: async ({ ids }, context, option) => {
for (const id of ids) {
await context.operate('ship', {
id: await (0, uuid_1.generateNewIdAsync)(),
action: 'ship',
data: {},
const [ship] = await context.select('ship', {
data: {
id: 1,
iState: 1,
type: 1,
},
filter: {
id,
id
}
}, option);
}, { dontCollect: true, forUpdate: true });
const { iState, type } = ship;
if (iState && ['unshipped', 'unknown'].includes(iState) && type && ['virtual', 'pickup'].includes(type)) {
await context.operate('ship', {
id: await (0, uuid_1.generateNewIdAsync)(),
action: 'ship',
data: {},
filter: {
id,
}
}, option);
}
}
return;
},
@ -51,7 +65,7 @@ const triggers = [
id
}
}, { dontCollect: true, forUpdate: true });
const { entity, entityId } = ship;
const { entity, entityId } = ship || {};
if (entity && entityId) {
const shipClazz = await (0, shipClazz_1.getShipClazz)(entity, entityId, context);
const extraShipId = await shipClazz.eOrder(id, context);
@ -119,6 +133,9 @@ const triggers = [
const { id: shipId, type, deposit$ship: deposits, shipOrder$ship, shipServiceId, entity, entityId, wechatMpShip } = ship || {};
if (deposits && deposits.length > 0) {
//充值 (此时该充值必定为受发货限制的小程序上的充值)
//等待5秒以避免小程序订单号查询不到
const sleep = (0, util_1.promisify)(setTimeout);
await sleep(5 * 1000);
await (0, ship_1.uploadShippingInfo)(shipId, context);
cnt++;
}
@ -451,49 +468,5 @@ const triggers = [
return count;
},
},
{
name: '当虚拟ship自动确认收货后更新deposit状态',
entity: 'ship',
action: 'update',
when: 'after',
asRoot: true,
fn: async ({ operation }, context, option) => {
const { filter, id, data } = operation;
const ships = await context.select('ship', {
data: {
id: 1,
iState: 1,
type: 1,
deposit$ship: {
$entity: 'deposit',
data: {
id: 1,
iState: 1,
}
}
},
filter,
}, { forUpdate: true });
let count = 0;
const virtualShips = ships?.filter((ele) => ele.type === 'virtual');
if (virtualShips && virtualShips.length > 0) {
for (const ship of virtualShips) {
const deposit = ship.deposit$ship?.[0];
if (deposit && deposit.iState === 'shipped') {
await context.operate('deposit', {
id: await (0, uuid_1.generateNewIdAsync)(),
action: 'succeed',
data: {},
filter: {
id: deposit.id,
}
}, option);
count++;
}
}
}
return count;
}
},
];
exports.default = triggers;

View File

@ -6,6 +6,6 @@ import { BRC } from '../types/RuntimeCxt';
* @param context
* @param refunds
*/
export declare function updateWithdrawState(context: BRC, id: string): Promise<0 | 1>;
export declare function updateWithdrawState(context: BRC, id: string): Promise<1 | 0>;
declare const triggers: Trigger<EntityDict, 'withdraw', BRC>[];
export default triggers;

View File

@ -1,36 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const operationResult_1 = require("oak-domain/lib/utils/operationResult");
const ship_1 = require("../utils/ship");
const QUERY_PAYING_STATE_GAP = process.env.NODE_ENV === 'production' ? 3600 * 1000 : 60 * 1000;
const watchers = [
{
name: '对shipping状态的物流同步其真实状态',
entity: 'ship',
filter: async () => {
const now = Date.now();
return {
type: 'express',
iState: 'shipping',
$$updateAt$$: {
$lte: now - QUERY_PAYING_STATE_GAP,
},
};
},
projection: ship_1.shipProjection,
fn: async (context, data) => {
const results = [];
for (const ship of data) {
const result = await (0, ship_1.refreshShipState)(ship.id, context);
if (result) {
results.push(result);
}
}
if (results.length === 0) {
return {};
}
return results.reduce((prev, cur) => (0, operationResult_1.mergeOperationResult)(prev, cur));
}
}
// {
// name: '对shipping状态的物流同步其真实状态',
// entity: 'ship',
// filter: async () => {
// const now = Date.now();
// return {
// type: 'express',
// iState: 'shipping',
// $$updateAt$$: {
// $lte: now - QUERY_PAYING_STATE_GAP,
// },
// };
// },
// projection: shipProjection,
// fn: async (context, data) => {
// const results = [] as OperationResult<EntityDict>[];
// for (const ship of data) {
// const result = await refreshShipState(ship.id!, context);
// if (result) {
// results.push(result);
// }
// }
// if (results.length === 0) {
// return {};
// }
// return results.reduce(
// (prev, cur) => mergeOperationResult(prev, cur)
// );
// }
// }
];
exports.default = watchers;

View File

@ -13,4 +13,7 @@ export type AspectDict<ED extends EntityDict> = {
getExpressPrintInfo: (params: {
shipId: string;
}, context: BackendRuntimeContext<ED>) => Promise<{ type: "html", data: string }>;
shipConfirmSuccess: (params: {
shipId: string;
}, context: BackendRuntimeContext<ED>) => Promise<Boolean>;
};

View File

@ -1,12 +1,13 @@
import { EntityDict } from '../oak-app-domain';
import { AspectDict } from './AspectDict';
import { getWithdrawCreateData } from './withdraw';
import { getExpressPrintInfo, getMpShipState } from './ship';
import { getExpressPrintInfo, getMpShipState, shipConfirmSuccess } from './ship';
const aspectDict = {
getMpShipState,
getWithdrawCreateData,
getExpressPrintInfo,
shipConfirmSuccess,
} as AspectDict<EntityDict>;
export default aspectDict;

View File

@ -4,6 +4,7 @@ import { BRC } from '../types/RuntimeCxt';
import assert from 'assert';
import { getOrderShipState } from '../utils/ship';
import { getShipClazz } from '../utils/shipClazz';
import { generateNewIdAsync } from 'oak-domain/lib/utils/uuid';
/**
*
@ -61,4 +62,54 @@ export async function getExpressPrintInfo(
}
const clazz = await getShipClazz(entity, entityId, context);
return await clazz.getPrintInfo(shipId, context);
}
/**
* ship状态
*/
export async function shipConfirmSuccess(
params: {
shipId: string,
},
context: BRC,
) {
const application = context.getApplication();
const { type, } = application!;
if (type === 'wechatMp') {
try {
const { shipId } = params;
const shipState = await getOrderShipState(
context,
shipId,
) as EntityDict['ship']['Schema']['iState'];
if (shipState === 'received') {
//微信端已确认收货
const [ship] = await context.select('ship', {
data: {
id: 1,
iState: 1,
}, filter: {
id: shipId,
}
}, { forUpdate: true });
if (ship.iState === 'receiving') {
await context.operate('ship', {
id: await generateNewIdAsync(),
action: 'succeedReceiving',
data: {},
filter: {
id: shipId,
},
}, {});
return true;
}
}
}
catch (err) {
return false;
}
}
return false;
}

View File

@ -356,31 +356,42 @@ export default OakComponent({
},
success: async () => {
console.log('success');
const { result: mpShipState } = await this.features.cache.exec('getMpShipState', {
// const { result: mpShipState } = await this.features.cache.exec('getMpShipState', {
// shipId: ship.id,
// })
// if (mpShipState === 'received') {
// await this.features.cache.operate('ship',
// [{
// id: await generateNewIdAsync(),
// action: 'succeedReceiving',
// data: {},
// filter: {
// id: ship.id,
// },
// }]
// );
// this.setMessage({
// type: 'success',
// content: this.t('ship.success')
// });
// } else {
// console.log(mpShipState);
// this.reRender();
// // this.setMessage({
// // type: 'warning',
// // content: this.t('ship.wait'),
// // })
// }
const { result } = await this.features.cache.exec('shipConfirmSuccess', {
shipId: ship.id,
})
if (mpShipState === 'received') {
await this.features.cache.operate('ship',
[{
id: await generateNewIdAsync(),
action: 'succeedReceiving',
data: {},
filter: {
id: ship.id,
},
}]
);
if (result) {
this.setMessage({
type: 'success',
content: this.t('ship.success')
});
} else {
console.log(mpShipState);
this.reRender();
// this.setMessage({
// type: 'warning',
// content: this.t('ship.wait'),
// })
}
},
fail: () => {

View File

@ -393,31 +393,42 @@ export default OakComponent({
},
success: async () => {
console.log('success');
const { result: mpShipState } = await this.features.cache.exec('getMpShipState', {
// const { result: mpShipState } = await this.features.cache.exec('getMpShipState', {
// shipId,
// })
// if (mpShipState === 'received') {
// await this.features.cache.operate('ship',
// [{
// id: await generateNewIdAsync(),
// action: 'succeedReceiving',
// data: {},
// filter: {
// id: shipId,
// },
// }]
// );
// this.reRender();
// this.setMessage({
// type: 'success',
// content: this.t('ship.success')
// });
// } else {
// console.log(mpShipState);
// // this.setMessage({
// // type: 'warning',
// // content: this.t('ship.wait'),
// // })
// this.reRender();
// }
const { result } = await this.features.cache.exec('shipConfirmSuccess', {
shipId,
})
if (mpShipState === 'received') {
await this.features.cache.operate('ship',
[{
id: await generateNewIdAsync(),
action: 'succeedReceiving',
data: {},
filter: {
id: shipId,
},
}]
);
this.reRender();
if (result) {
this.setMessage({
type: 'success',
content: this.t('ship.success')
});
} else {
console.log(mpShipState);
// this.setMessage({
// type: 'warning',
// content: this.t('ship.wait'),
// })
this.reRender();
}
},
@ -454,17 +465,28 @@ export default OakComponent({
const unsub = await this.subDataEvents([
`${DATA_SUBSCRIBER_KEYS.payStateChanged}-${oakId}`,
`${DATA_SUBSCRIBER_KEYS.depositStateChanged}-${oakId}`
]);
], async (event: string, opRecords: OpRecord<ED>[]) => {
for (const record of opRecords) {
console.log(record);
if ((record as any).e === 'pay' || (record as any).e === 'deposit') {
const { f } = record as any;
const [pay] = this.features.cache.get('pay', {
data: baseProjection,
filter: f,
})
console.log(JSON.stringify(pay));
}
}
});
let depositUnsub = undefined;
const { depositId } = this.state;
if (depositId) {
const depositUnsub = await this.subDataEvents([`${DATA_SUBSCRIBER_KEYS.shipStateChanged}-${depositId}`]);
this.setState({
depositUnsub,
})
depositUnsub = await this.subDataEvents([`${DATA_SUBSCRIBER_KEYS.shipStateChanged}-${depositId}`]);
}
this.setState({
unsub,
depositUnsub,
})
},
async mature() {

View File

@ -13,7 +13,7 @@ const timers: Array<Timer<EntityDict, 'ship', BRC>> = [
filter: {
type: 'express',
iState: {
$nin: ['received', 'cancelled', 'rejected', 'receiving'],
$nin: ['received', 'cancelled', 'rejected', 'receiving', 'unshipped'],
},
entity: {
$exists: true
@ -48,7 +48,7 @@ const timers: Array<Timer<EntityDict, 'ship', BRC>> = [
},
{
name: '同步微信小程序虚拟、自提ship状态',
cron: '0 0/2 * * * ?',
cron: '0 * * * * ?',
entity: 'ship',
filter: {
type: {
@ -60,6 +60,7 @@ const timers: Array<Timer<EntityDict, 'ship', BRC>> = [
},
projection: {
id: 1,
iState: 1,
},
fn: async (context, data) => {
const results = [] as OperationResult<EntityDict>[];
@ -77,22 +78,22 @@ const timers: Array<Timer<EntityDict, 'ship', BRC>> = [
);
},
},
{
name: '对虚拟或自提类型的ship自动发货',
cron: '0 * * * * ?',
entity: 'ship',
filter: {
type: {
$in: ['virtual', 'pickup'],
},
iState: 'unshipped',
},
projection: {
id: 1,
},
action: 'ship',
actionData: {},
},
// {
// name: '对虚拟或自提类型的ship自动发货',
// cron: '0 * * * * ?',
// entity: 'ship',
// filter: {
// type: {
// $in: ['virtual', 'pickup'],
// },
// iState: 'unshipped',
// },
// projection: {
// id: 1,
// },
// action: 'ship',
// actionData: {},
// },
];
export default timers;

View File

@ -6,6 +6,7 @@ import { DATA_SUBSCRIBER_KEYS } from '../config/constants';
import assert from 'assert';
import { getShipClazz, getShipEntity } from '../utils/shipClazz';
import { notifyConfirmReceive, uploadShippingInfo } from '../utils/ship';
import { promisify } from 'util';
const triggers: Trigger<EntityDict, 'ship', BRC>[] = [
{
@ -18,15 +19,28 @@ const triggers: Trigger<EntityDict, 'ship', BRC>[] = [
check: (operation: EntityDict['ship']['CreateSingle']) => ['virtual', 'pickup'].includes(operation.data.type!),
fn: async ({ ids }, context, option) => {
for (const id of ids) {
await context.operate('ship', {
id: await generateNewIdAsync(),
action: 'ship',
const [ship] = await context.select('ship', {
data: {
id: 1,
iState: 1,
type: 1,
},
filter: {
id,
id
}
}, option);
}, { dontCollect: true, forUpdate: true });
const { iState, type } = ship;
if (iState && ['unshipped', 'unknown'].includes(iState) && type && ['virtual', 'pickup'].includes(type)) {
await context.operate('ship', {
id: await generateNewIdAsync(),
action: 'ship',
data: {
},
filter: {
id,
}
}, option);
}
}
return;
},
@ -55,7 +69,7 @@ const triggers: Trigger<EntityDict, 'ship', BRC>[] = [
}, { dontCollect: true, forUpdate: true });
const { entity, entityId } = ship;
const { entity, entityId } = ship || {};
if (entity && entityId) {
const shipClazz = await getShipClazz(entity, entityId, context);
const extraShipId = await shipClazz.eOrder(id!, context);
@ -125,6 +139,9 @@ const triggers: Trigger<EntityDict, 'ship', BRC>[] = [
const { id: shipId, type, deposit$ship: deposits, shipOrder$ship, shipServiceId, entity, entityId, wechatMpShip } = ship || {};
if (deposits && deposits.length > 0) {
//充值 (此时该充值必定为受发货限制的小程序上的充值)
//等待5秒以避免小程序订单号查询不到
const sleep = promisify(setTimeout);
await sleep(5 * 1000);
await uploadShippingInfo(shipId!, context);
cnt++;
} else if (shipOrder$ship && shipOrder$ship.length > 0) {
@ -465,51 +482,6 @@ const triggers: Trigger<EntityDict, 'ship', BRC>[] = [
return count;
},
},
{
name: '当虚拟ship自动确认收货后更新deposit状态',
entity: 'ship',
action: 'update',
when: 'after',
asRoot: true,
fn: async ({ operation }, context, option) => {
const { filter, id, data } = operation as EntityDict['ship']['Update'];
const ships = await context.select('ship', {
data: {
id: 1,
iState: 1,
type: 1,
deposit$ship: {
$entity: 'deposit',
data: {
id: 1,
iState: 1,
}
}
},
filter,
}, { forUpdate: true });
let count = 0;
const virtualShips = ships?.filter((ele) => ele.type === 'virtual');
if (virtualShips && virtualShips.length > 0) {
for (const ship of virtualShips) {
const deposit = ship.deposit$ship?.[0];
if (deposit && deposit.iState === 'shipped') {
await context.operate('deposit', {
id: await generateNewIdAsync(),
action: 'succeed',
data: {
},
filter: {
id: deposit.id,
}
}, option);
count++;
}
}
}
return count;
}
},
];
export default triggers;

View File

@ -8,37 +8,37 @@ import { shipProjection, refreshShipState } from '../utils/ship';
const QUERY_PAYING_STATE_GAP = process.env.NODE_ENV === 'production' ? 3600 * 1000 : 60 * 1000;
const watchers: Watcher<EntityDict, 'ship', BRC>[] = [
{
name: '对shipping状态的物流同步其真实状态',
entity: 'ship',
filter: async () => {
const now = Date.now();
return {
type: 'express',
iState: 'shipping',
$$updateAt$$: {
$lte: now - QUERY_PAYING_STATE_GAP,
},
};
},
projection: shipProjection,
fn: async (context, data) => {
const results = [] as OperationResult<EntityDict>[];
for (const ship of data) {
const result = await refreshShipState(ship.id!, context);
if (result) {
results.push(result);
}
}
// {
// name: '对shipping状态的物流同步其真实状态',
// entity: 'ship',
// filter: async () => {
// const now = Date.now();
// return {
// type: 'express',
// iState: 'shipping',
// $$updateAt$$: {
// $lte: now - QUERY_PAYING_STATE_GAP,
// },
// };
// },
// projection: shipProjection,
// fn: async (context, data) => {
// const results = [] as OperationResult<EntityDict>[];
// for (const ship of data) {
// const result = await refreshShipState(ship.id!, context);
// if (result) {
// results.push(result);
// }
// }
if (results.length === 0) {
return {};
}
return results.reduce(
(prev, cur) => mergeOperationResult(prev, cur)
);
}
}
// if (results.length === 0) {
// return {};
// }
// return results.reduce(
// (prev, cur) => mergeOperationResult(prev, cur)
// );
// }
// }
];
export default watchers;