微调了一些数据结构

This commit is contained in:
Xu Chang 2025-03-04 17:07:56 +08:00
parent 061c0bb2cf
commit 076f6d53d8
27 changed files with 309 additions and 105 deletions

View File

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

View File

@ -28,8 +28,8 @@ export interface Schema extends EntityShape {
export type IAction = 'startPaying' | 'payAll' | 'payPartially' | 'payNone' | 'timeout' | 'cancel' | 'startRefunding' | 'refundAll' | 'refundPartially' | 'refundNone';
export type IState = 'unpaid' | 'timeout' | 'cancelled' | 'paying' | 'partiallyPaid' | 'paid' | 'refunding' | 'partiallyRefunded' | 'refunded';
export declare const IActionDef: ActionDef<IAction, IState>;
export type GState = 'staging' | 'shipped' | 'unshipped' | 'received' | 'taken' | 'taking';
export type GAction = 'send' | 'receive' | 'store' | 'take' | 'startTaking' | 'cancelTaking' | 'completeTaking' | 'turnBack' | 'unship';
export type GState = 'staging' | 'shipping' | 'packaged' | 'unshipped' | 'received' | 'taken' | 'taking';
export type GAction = 'package' | 'send' | 'receive' | 'store' | 'take' | 'startTaking' | 'cancelTaking' | 'completeTaking' | 'turnBack' | 'unship';
export declare const GActionDef: ActionDef<GAction, GState>;
export type Action = IAction | GAction | 'settle';
export declare const entityDesc: EntityDesc<Schema, Action, '', {

View File

@ -16,11 +16,12 @@ export const IActionDef = {
};
export const GActionDef = {
stm: {
send: ['unshipped', 'shipped'],
receive: ['shipped', 'received'],
store: [['unshipped', 'shipped'], 'staging'],
unship: [['shipped', 'staging'], 'unshipped'],
turnBack: ['shipped', 'unshipped'],
package: ['unshipped', 'packaged'],
send: ['packaged', 'shipping'],
receive: ['shipping', 'received'],
store: ['unshipped', 'staging'],
unship: [['packaged', 'staging'], 'unshipped'],
turnBack: ['shipping', 'unshipped'],
take: [['staging'], 'taken'],
startTaking: ['staging', 'taking'],
cancelTaking: ['taking', 'staging'],
@ -94,6 +95,7 @@ export const entityDesc = {
refundAll: '完全退款',
refundNone: '退款失败',
refundPartially: '部分退款',
package: '打包',
send: '发货',
store: '暂存',
take: '提货',
@ -119,7 +121,8 @@ export const entityDesc = {
},
gState: {
unshipped: '未发货',
shipped: '已发货',
packaged: '已打包',
shipping: '已发货',
received: '已收货',
staging: '寄存中',
taken: '已提货',
@ -169,7 +172,8 @@ export const entityDesc = {
},
gState: {
unshipped: '#AF601A',
shipped: '#2874A6',
packaged: '#676855',
shipping: '#2874A6',
received: '#1E8449',
staging: '#283747',
taken: '#117A65',

View File

@ -3,8 +3,8 @@ import { GenericAction } from "oak-domain/lib/actions/action";
export type IAction = 'startPaying' | 'payAll' | 'payPartially' | 'payNone' | 'timeout' | 'cancel' | 'startRefunding' | 'refundAll' | 'refundPartially' | 'refundNone' | string;
export type IState = 'unpaid' | 'timeout' | 'cancelled' | 'paying' | 'partiallyPaid' | 'paid' | 'refunding' | 'partiallyRefunded' | 'refunded' | string;
export declare const IActionDef: ActionDef<IAction, IState>;
export type GState = 'staging' | 'shipped' | 'unshipped' | 'received' | 'taken' | 'taking' | string;
export type GAction = 'send' | 'receive' | 'store' | 'take' | 'startTaking' | 'cancelTaking' | 'completeTaking' | 'turnBack' | 'unship' | string;
export type GState = 'staging' | 'shipping' | 'packaged' | 'unshipped' | 'received' | 'taken' | 'taking' | string;
export type GAction = 'package' | 'send' | 'receive' | 'store' | 'take' | 'startTaking' | 'cancelTaking' | 'completeTaking' | 'turnBack' | 'unship' | string;
export declare const GActionDef: ActionDef<GAction, GState>;
export type ParticularAction = IAction | GAction | 'settle';
export declare const actions: string[];

View File

@ -15,11 +15,12 @@ export const IActionDef = {
};
export const GActionDef = {
stm: {
send: ['unshipped', 'shipped'],
receive: ['shipped', 'received'],
store: [['unshipped', 'shipped'], 'staging'],
unship: [['shipped', 'staging'], 'unshipped'],
turnBack: ['shipped', 'unshipped'],
package: ['unshipped', 'packaged'],
send: ['packaged', 'shipping'],
receive: ['shipping', 'received'],
store: ['unshipped', 'staging'],
unship: [['packaged', 'staging'], 'unshipped'],
turnBack: ['shipping', 'unshipped'],
take: [['staging'], 'taken'],
startTaking: ['staging', 'taking'],
cancelTaking: ['taking', 'staging'],
@ -27,7 +28,7 @@ export const GActionDef = {
},
is: 'unshipped',
};
export const actions = ["count", "stat", "download", "select", "aggregate", "create", "remove", "update", "startPaying", "payAll", "payPartially", "payNone", "timeout", "cancel", "startRefunding", "refundAll", "refundPartially", "refundNone", "send", "receive", "store", "take", "startTaking", "cancelTaking", "completeTaking", "turnBack", "unship", "settle"];
export const actions = ["count", "stat", "download", "select", "aggregate", "create", "remove", "update", "startPaying", "payAll", "payPartially", "payNone", "timeout", "cancel", "startRefunding", "refundAll", "refundPartially", "refundNone", "package", "send", "receive", "store", "take", "startTaking", "cancelTaking", "completeTaking", "turnBack", "unship", "settle"];
export const actionDefDict = {
iState: IActionDef,
gState: GActionDef

View File

@ -82,7 +82,7 @@ export const desc = {
},
gState: {
type: "enum",
enumeration: ["staging", "shipped", "unshipped", "received", "taken", "taking"]
enumeration: ["staging", "shipping", "packaged", "unshipped", "received", "taken", "taking"]
}
},
actionType: "crud",

View File

@ -35,7 +35,8 @@ export const style = {
},
gState: {
unshipped: '#AF601A',
shipped: '#2874A6',
packaged: '#676855',
shipping: '#2874A6',
received: '#1E8449',
staging: '#283747',
taken: '#117A65',

View File

@ -33,6 +33,7 @@
"refundAll": "完全退款",
"refundNone": "退款失败",
"refundPartially": "部分退款",
"package": "打包",
"send": "发货",
"store": "暂存",
"take": "提货",
@ -58,7 +59,8 @@
},
"gState": {
"unshipped": "未发货",
"shipped": "已发货",
"packaged": "已打包",
"shipping": "已发货",
"received": "已收货",
"staging": "寄存中",
"taken": "已提货",

View File

@ -1,15 +1,16 @@
import { generateNewIdAsync } from 'oak-domain/lib/utils/uuid';
import { DATA_SUBSCRIBER_KEYS } from '../config/constants';
import assert from 'assert';
import { getShipState, uploadShippingInfo } from '../utils/ship';
const triggers = [
{
name: '当虚拟发货创建后自动发货',
name: '当虚拟或自提类型的ship创建后自动发货',
entity: 'ship',
action: 'create',
when: 'commit',
strict: 'makeSure',
asRoot: true,
check: (operation) => operation.data.type === 'virtual',
check: (operation) => ['virtual', 'pickup'].includes(operation.data.type),
fn: async ({ ids }, context, option) => {
for (const id of ids) {
await context.operate('ship', {
@ -79,9 +80,9 @@ const triggers = [
}
},
{
name: '当物流创建时将对应的order状态变为已发货',
name: '当物流发货时将对应的order状态变为已发货/提货中',
entity: 'ship',
action: 'create',
action: 'ship',
when: 'after',
fn: async ({ operation }, context, option) => {
const { data } = operation;
@ -96,20 +97,34 @@ const triggers = [
}
}
}, { dontCollect: true });
const unshipped = orders.filter(ele => ele.gState === 'unshipped');
if (unshipped.length > 0) {
const packaged = orders.filter(ele => ele.gState === 'packaged');
if (packaged.length > 0) {
await context.operate('order', {
id: await generateNewIdAsync(),
action: 'ship',
data: {},
filter: {
id: {
$in: unshipped.map(ele => ele.id),
$in: packaged.map(ele => ele.id),
},
},
}, option);
}
return unshipped.length;
const staged = orders.filter(ele => ele.gState === 'staging');
if (staged.length > 0) {
await context.operate('order', {
id: await generateNewIdAsync(),
action: 'startTaking',
data: {},
filter: {
id: {
$in: staged.map(ele => ele.id),
},
},
}, option);
}
assert(staged.length + packaged.length === orders.length);
return orders.length;
}
}
];

View File

@ -1,16 +1,14 @@
import { EntityDict } from '../oak-app-domain';
import { BRC } from '../types/RuntimeCxt';
export default interface ShipClazz {
bindBizId(bizId: string): Promise<void>;
unbindBizId(bizId: string): Promise<void>;
eOrder(bizId: string, ship: EntityDict['ship']['Schema'], context: BRC): Promise<string>;
preOrder(ship: EntityDict['ship']['Schema'], context: BRC): Promise<string | void>;
cancelOrder(ship: EntityDict['ship']['Schema'], context: BRC): Promise<void>;
getState(ship: EntityDict['ship']['Schema']): Promise<{
eOrder(ship: EntityDict['ship']['OpSchema'], context: BRC): Promise<string>;
preOrder(ship: EntityDict['ship']['OpSchema'], context: BRC): Promise<string | void>;
cancelOrder(ship: EntityDict['ship']['OpSchema'], context: BRC): Promise<void>;
getState(ship: EntityDict['ship']['OpSchema']): Promise<{
iState: EntityDict['ship']['OpSchema']['iState'];
extraPaths?: EntityDict['ship']['OpSchema']['extraPaths'];
}>;
getPrintInfo(ship: EntityDict['ship']['Schema']): Promise<{
getPrintInfo(ship: EntityDict['ship']['OpSchema']): Promise<{
type: 'html';
data: string;
}>;

View File

@ -1,4 +1,4 @@
import WechatPay from './WechatPay';
import WechatPayDebug from './WechatPay.debug';
declare const _default: typeof WechatPay | typeof WechatPayDebug;
declare const _default: typeof WechatPayDebug | typeof WechatPay;
export default _default;

View File

@ -28,8 +28,8 @@ export interface Schema extends EntityShape {
export type IAction = 'startPaying' | 'payAll' | 'payPartially' | 'payNone' | 'timeout' | 'cancel' | 'startRefunding' | 'refundAll' | 'refundPartially' | 'refundNone';
export type IState = 'unpaid' | 'timeout' | 'cancelled' | 'paying' | 'partiallyPaid' | 'paid' | 'refunding' | 'partiallyRefunded' | 'refunded';
export declare const IActionDef: ActionDef<IAction, IState>;
export type GState = 'staging' | 'shipped' | 'unshipped' | 'received' | 'taken' | 'taking';
export type GAction = 'send' | 'receive' | 'store' | 'take' | 'startTaking' | 'cancelTaking' | 'completeTaking' | 'turnBack' | 'unship';
export type GState = 'staging' | 'shipping' | 'packaged' | 'unshipped' | 'received' | 'taken' | 'taking';
export type GAction = 'package' | 'send' | 'receive' | 'store' | 'take' | 'startTaking' | 'cancelTaking' | 'completeTaking' | 'turnBack' | 'unship';
export declare const GActionDef: ActionDef<GAction, GState>;
export type Action = IAction | GAction | 'settle';
export declare const entityDesc: EntityDesc<Schema, Action, '', {

View File

@ -19,11 +19,12 @@ exports.IActionDef = {
};
exports.GActionDef = {
stm: {
send: ['unshipped', 'shipped'],
receive: ['shipped', 'received'],
store: [['unshipped', 'shipped'], 'staging'],
unship: [['shipped', 'staging'], 'unshipped'],
turnBack: ['shipped', 'unshipped'],
package: ['unshipped', 'packaged'],
send: ['packaged', 'shipping'],
receive: ['shipping', 'received'],
store: ['unshipped', 'staging'],
unship: [['packaged', 'staging'], 'unshipped'],
turnBack: ['shipping', 'unshipped'],
take: [['staging'], 'taken'],
startTaking: ['staging', 'taking'],
cancelTaking: ['taking', 'staging'],
@ -97,6 +98,7 @@ exports.entityDesc = {
refundAll: '完全退款',
refundNone: '退款失败',
refundPartially: '部分退款',
package: '打包',
send: '发货',
store: '暂存',
take: '提货',
@ -122,7 +124,8 @@ exports.entityDesc = {
},
gState: {
unshipped: '未发货',
shipped: '已发货',
packaged: '已打包',
shipping: '已发货',
received: '已收货',
staging: '寄存中',
taken: '已提货',
@ -172,7 +175,8 @@ exports.entityDesc = {
},
gState: {
unshipped: '#AF601A',
shipped: '#2874A6',
packaged: '#676855',
shipping: '#2874A6',
received: '#1E8449',
staging: '#283747',
taken: '#117A65',

View File

@ -3,8 +3,8 @@ import { GenericAction } from "oak-domain/lib/actions/action";
export type IAction = 'startPaying' | 'payAll' | 'payPartially' | 'payNone' | 'timeout' | 'cancel' | 'startRefunding' | 'refundAll' | 'refundPartially' | 'refundNone' | string;
export type IState = 'unpaid' | 'timeout' | 'cancelled' | 'paying' | 'partiallyPaid' | 'paid' | 'refunding' | 'partiallyRefunded' | 'refunded' | string;
export declare const IActionDef: ActionDef<IAction, IState>;
export type GState = 'staging' | 'shipped' | 'unshipped' | 'received' | 'taken' | 'taking' | string;
export type GAction = 'send' | 'receive' | 'store' | 'take' | 'startTaking' | 'cancelTaking' | 'completeTaking' | 'turnBack' | 'unship' | string;
export type GState = 'staging' | 'shipping' | 'packaged' | 'unshipped' | 'received' | 'taken' | 'taking' | string;
export type GAction = 'package' | 'send' | 'receive' | 'store' | 'take' | 'startTaking' | 'cancelTaking' | 'completeTaking' | 'turnBack' | 'unship' | string;
export declare const GActionDef: ActionDef<GAction, GState>;
export type ParticularAction = IAction | GAction | 'settle';
export declare const actions: string[];

View File

@ -18,11 +18,12 @@ exports.IActionDef = {
};
exports.GActionDef = {
stm: {
send: ['unshipped', 'shipped'],
receive: ['shipped', 'received'],
store: [['unshipped', 'shipped'], 'staging'],
unship: [['shipped', 'staging'], 'unshipped'],
turnBack: ['shipped', 'unshipped'],
package: ['unshipped', 'packaged'],
send: ['packaged', 'shipping'],
receive: ['shipping', 'received'],
store: ['unshipped', 'staging'],
unship: [['packaged', 'staging'], 'unshipped'],
turnBack: ['shipping', 'unshipped'],
take: [['staging'], 'taken'],
startTaking: ['staging', 'taking'],
cancelTaking: ['taking', 'staging'],
@ -30,7 +31,7 @@ exports.GActionDef = {
},
is: 'unshipped',
};
exports.actions = ["count", "stat", "download", "select", "aggregate", "create", "remove", "update", "startPaying", "payAll", "payPartially", "payNone", "timeout", "cancel", "startRefunding", "refundAll", "refundPartially", "refundNone", "send", "receive", "store", "take", "startTaking", "cancelTaking", "completeTaking", "turnBack", "unship", "settle"];
exports.actions = ["count", "stat", "download", "select", "aggregate", "create", "remove", "update", "startPaying", "payAll", "payPartially", "payNone", "timeout", "cancel", "startRefunding", "refundAll", "refundPartially", "refundNone", "package", "send", "receive", "store", "take", "startTaking", "cancelTaking", "completeTaking", "turnBack", "unship", "settle"];
exports.actionDefDict = {
iState: exports.IActionDef,
gState: exports.GActionDef

View File

@ -85,7 +85,7 @@ exports.desc = {
},
gState: {
type: "enum",
enumeration: ["staging", "shipped", "unshipped", "received", "taken", "taking"]
enumeration: ["staging", "shipping", "packaged", "unshipped", "received", "taken", "taking"]
}
},
actionType: "crud",

View File

@ -38,7 +38,8 @@ exports.style = {
},
gState: {
unshipped: '#AF601A',
shipped: '#2874A6',
packaged: '#676855',
shipping: '#2874A6',
received: '#1E8449',
staging: '#283747',
taken: '#117A65',

View File

@ -33,6 +33,7 @@
"refundAll": "完全退款",
"refundNone": "退款失败",
"refundPartially": "部分退款",
"package": "打包",
"send": "发货",
"store": "暂存",
"take": "提货",
@ -58,7 +59,8 @@
},
"gState": {
"unshipped": "未发货",
"shipped": "已发货",
"packaged": "已打包",
"shipping": "已发货",
"received": "已收货",
"staging": "寄存中",
"taken": "已提货",

View File

@ -1,17 +1,19 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const uuid_1 = require("oak-domain/lib/utils/uuid");
const constants_1 = require("../config/constants");
const assert_1 = tslib_1.__importDefault(require("assert"));
const ship_1 = require("../utils/ship");
const triggers = [
{
name: '当虚拟发货创建后自动发货',
name: '当虚拟或自提类型的ship创建后自动发货',
entity: 'ship',
action: 'create',
when: 'commit',
strict: 'makeSure',
asRoot: true,
check: (operation) => operation.data.type === 'virtual',
check: (operation) => ['virtual', 'pickup'].includes(operation.data.type),
fn: async ({ ids }, context, option) => {
for (const id of ids) {
await context.operate('ship', {
@ -81,9 +83,9 @@ const triggers = [
}
},
{
name: '当物流创建时将对应的order状态变为已发货',
name: '当物流发货时将对应的order状态变为已发货/提货中',
entity: 'ship',
action: 'create',
action: 'ship',
when: 'after',
fn: async ({ operation }, context, option) => {
const { data } = operation;
@ -98,20 +100,34 @@ const triggers = [
}
}
}, { dontCollect: true });
const unshipped = orders.filter(ele => ele.gState === 'unshipped');
if (unshipped.length > 0) {
const packaged = orders.filter(ele => ele.gState === 'packaged');
if (packaged.length > 0) {
await context.operate('order', {
id: await (0, uuid_1.generateNewIdAsync)(),
action: 'ship',
data: {},
filter: {
id: {
$in: unshipped.map(ele => ele.id),
$in: packaged.map(ele => ele.id),
},
},
}, option);
}
return unshipped.length;
const staged = orders.filter(ele => ele.gState === 'staging');
if (staged.length > 0) {
await context.operate('order', {
id: await (0, uuid_1.generateNewIdAsync)(),
action: 'startTaking',
data: {},
filter: {
id: {
$in: staged.map(ele => ele.id),
},
},
}, option);
}
(0, assert_1.default)(staged.length + packaged.length === orders.length);
return orders.length;
}
}
];

View File

@ -1,16 +1,14 @@
import { EntityDict } from '../oak-app-domain';
import { BRC } from '../types/RuntimeCxt';
export default interface ShipClazz {
bindBizId(bizId: string): Promise<void>;
unbindBizId(bizId: string): Promise<void>;
eOrder(bizId: string, ship: EntityDict['ship']['Schema'], context: BRC): Promise<string>;
preOrder(ship: EntityDict['ship']['Schema'], context: BRC): Promise<string | void>;
cancelOrder(ship: EntityDict['ship']['Schema'], context: BRC): Promise<void>;
getState(ship: EntityDict['ship']['Schema']): Promise<{
eOrder(ship: EntityDict['ship']['OpSchema'], context: BRC): Promise<string>;
preOrder(ship: EntityDict['ship']['OpSchema'], context: BRC): Promise<string | void>;
cancelOrder(ship: EntityDict['ship']['OpSchema'], context: BRC): Promise<void>;
getState(ship: EntityDict['ship']['OpSchema']): Promise<{
iState: EntityDict['ship']['OpSchema']['iState'];
extraPaths?: EntityDict['ship']['OpSchema']['extraPaths'];
}>;
getPrintInfo(ship: EntityDict['ship']['Schema']): Promise<{
getPrintInfo(ship: EntityDict['ship']['OpSchema']): Promise<{
type: 'html';
data: string;
}>;

View File

@ -173,7 +173,7 @@ const checkers: Checker<EntityDict, 'order', RuntimeCxt>[] = [
// 订单根据receivingMethod决定货品发送动作
entity: 'order',
type: 'row',
action: ['send', 'turnBack', 'receive'],
action: ['package', 'send', 'turnBack', 'receive'],
filter: {
receivingMethod: 'express',
},

View File

@ -9,11 +9,16 @@ import {
} from 'oak-domain/lib/types/DataType';
import { EntityShape } from 'oak-domain/lib/types/Entity';
import { EntityDesc, ActionDef } from 'oak-domain/lib/types';
import { Schema as Ship } from './Ship';
import { Schema as System } from './System';
export interface Schema extends EntityShape {
sort: Decimal<12, 8>; // 优先级高的会被优先使用来下快递
phatom1?: Int<8>;
phatom2?: String<64>;
ships: Ship[];
system: System;
disabled: Boolean;
};
@ -24,7 +29,10 @@ export const entityDesc: EntityDesc<Schema> = {
attr: {
phatom1: '备用属性一',
phatom2: '备用属性二',
disabled: '是否禁用',
sort: '排序',
ships: '关联快递',
system: '所属系统',
},
},
},

View File

@ -52,16 +52,17 @@ export const IActionDef: ActionDef<IAction, IState> = {
is: 'unpaid',
};
export type GState = 'staging' | 'shipped' | 'unshipped' | 'received' | 'taken' | 'taking';
export type GAction = 'send' | 'receive' | 'store' | 'take' | 'startTaking' | 'cancelTaking' | 'completeTaking' | 'turnBack' | 'unship';
export type GState = 'staging' | 'shipping' | 'packaged' | 'unshipped' | 'received' | 'taken' | 'taking';
export type GAction = 'package' | 'send' | 'receive' | 'store' | 'take' | 'startTaking' | 'cancelTaking' | 'completeTaking' | 'turnBack' | 'unship';
export const GActionDef: ActionDef<GAction, GState> = {
stm: {
send: ['unshipped', 'shipped'],
receive: ['shipped', 'received'],
store: [['unshipped', 'shipped'], 'staging'],
unship: [['shipped', 'staging'], 'unshipped'],
turnBack: ['shipped', 'unshipped'],
package: ['unshipped', 'packaged'],
send: ['packaged', 'shipping'],
receive: ['shipping', 'received'],
store: ['unshipped', 'staging'],
unship: [['packaged', 'staging'], 'unshipped'],
turnBack: ['shipping', 'unshipped'],
take: [['staging'], 'taken'],
startTaking: ['staging', 'taking'],
cancelTaking: ['taking', 'staging'],
@ -142,6 +143,7 @@ export const entityDesc: EntityDesc<Schema, Action, '', {
refundAll: '完全退款',
refundNone: '退款失败',
refundPartially: '部分退款',
package: '打包',
send: '发货',
store: '暂存',
take: '提货',
@ -167,7 +169,8 @@ export const entityDesc: EntityDesc<Schema, Action, '', {
},
gState: {
unshipped: '未发货',
shipped: '已发货',
packaged: '已打包',
shipping: '已发货',
received: '已收货',
staging: '寄存中',
taken: '已提货',
@ -218,7 +221,8 @@ export const entityDesc: EntityDesc<Schema, Action, '', {
},
gState: {
unshipped: '#AF601A',
shipped: '#2874A6',
packaged: '#676855',
shipping: '#2874A6',
received: '#1E8449',
staging: '#283747',
taken: '#117A65',

View File

@ -4,18 +4,18 @@ import { EntityDict } from '../oak-app-domain';
import { BRC } from '../types/RuntimeCxt';
import { DATA_SUBSCRIBER_KEYS } from '../config/constants';
import assert from 'assert';
import dayjs from 'dayjs';
import { getShipEntity } from '../utils/shipClazz';
import { getShipState, uploadShippingInfo } from '../utils/ship';
const triggers: Trigger<EntityDict, 'ship', BRC>[] = [
{
name: '当虚拟发货创建后自动发货',
name: '当虚拟或自提类型的ship创建后自动发货',
entity: 'ship',
action: 'create',
when: 'commit',
strict: 'makeSure',
asRoot: true,
check: (operation: EntityDict['ship']['Create']) => (operation as EntityDict['ship']['CreateSingle']).data.type === 'virtual',
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', {
@ -86,7 +86,7 @@ const triggers: Trigger<EntityDict, 'ship', BRC>[] = [
}
} as UpdateTriggerInTxn<EntityDict, 'ship', BRC>,
{
name: '当物流创建时,将对应的order状态变为已发货',
name: '当物流创建时,将对应的receivingMethod为express的order变为packaged状态',
entity: 'ship',
action: 'create',
when: 'after',
@ -98,28 +98,105 @@ const triggers: Trigger<EntityDict, 'ship', BRC>[] = [
gState: 1,
},
filter: {
receivingMethod: 'express',
shipOrder$order: {
shipId: data.id,
}
}
}, { dontCollect: true });
const unshipped = orders.filter(ele => ele.gState === 'unshipped');
if (unshipped.length > 0) {
orders.forEach(
ele => assert(ele.gState === 'unshipped')
);
await context.operate('order', {
id: await generateNewIdAsync(),
action: 'package',
data: {},
filter: {
id: {
$in: orders.map(ele => ele.id!),
},
},
}, option);
return orders.length;
}
} as CreateTrigger<EntityDict, 'ship', BRC>,
{
name: '当物流创建时,赋上对应的物流系统对象',
entity: 'ship',
action: 'create',
when: 'before',
fn: async({ operation }, context) => {
const result = await getShipEntity(context);
if (result) {
const { data } = operation;
if (data instanceof Array) {
data.forEach(
ele => {
ele.entity = result[0],
ele.entityId = result[1];
}
);
}
else {
data.entity = result[0];
data.entityId = result[1];
}
return 1;
}
return 0;
}
} as CreateTrigger<EntityDict, 'ship', BRC>,
{
name: '当物流发货时将对应的order状态变为已发货/提货中',
entity: 'ship',
action: 'ship',
when: 'after',
fn: async ({ operation }, context, option) => {
const { filter } = operation as EntityDict['ship']['Update'];
assert(typeof filter!.id === 'string');
const orders = await context.select('order', {
data: {
id: 1,
gState: 1,
},
filter: {
shipOrder$order: {
shipId: filter!.id,
}
}
}, { dontCollect: true });
const packaged = orders.filter(ele => ele.gState === 'packaged');
if (packaged.length > 0) {
await context.operate('order', {
id: await generateNewIdAsync(),
action: 'ship',
data: {},
filter: {
id: {
$in: unshipped.map(ele => ele.id!),
$in: packaged.map(ele => ele.id!),
},
},
}, option);
}
return unshipped.length;
const staged = orders.filter(ele => ele.gState === 'staging');
if (staged.length > 0) {
await context.operate('order', {
id: await generateNewIdAsync(),
action: 'startTaking',
data: {},
filter: {
id: {
$in: staged.map(ele => ele.id!),
},
},
}, option);
}
assert(staged.length + packaged.length === orders.length);
return orders.length;
}
} as CreateTrigger<EntityDict, 'ship', BRC>
} as UpdateTriggerInTxn<EntityDict, 'ship', BRC>
];
export default triggers;

View File

@ -2,29 +2,20 @@ import { EntityDict } from '../oak-app-domain';
import { BRC } from '../types/RuntimeCxt';
export default interface ShipClazz {
// 绑定bizId
bindBizId(bizId: string): Promise<void>;
// 解绑bizId
unbindBizId(bizId: string): Promise<void>;
// 下单
eOrder(bizId: string, ship: EntityDict['ship']['Schema'], context: BRC): Promise<string>;
// 预下单(上门提)
preOrder(ship: EntityDict['ship']['Schema'], context: BRC): Promise<string | void>;
eOrder(shipId: string, context: BRC): Promise<string>;
// 取消
cancelOrder(ship: EntityDict['ship']['Schema'], context: BRC): Promise<void>;
cancelOrder(shipId: string, context: BRC): Promise<void>;
// 查询状态(及轨迹)
getState(ship: EntityDict['ship']['Schema']): Promise<{
getState(shipId: string): Promise<{
iState: EntityDict['ship']['OpSchema']['iState'];
extraPaths?: EntityDict['ship']['OpSchema']['extraPaths'];
}>;
// 返回打印数据
getPrintInfo(ship: EntityDict['ship']['Schema']): Promise<{
getPrintInfo(shipId: string): Promise<{
type: 'html';
data: string;
}>

View File

@ -0,0 +1,21 @@
import { EntityDict } from "@project/oak-app-domain";
import { BRC } from "@project/types/RuntimeCxt";
import ShipClazz from "@project/types/ShipClazz";
export default class WechatMpShip implements ShipClazz {
eOrder(ship: EntityDict["ship"]["OpSchema"], context: BRC): Promise<string> {
throw new Error("Method not implemented.");
}
preOrder(ship: EntityDict["ship"]["OpSchema"], context: BRC): Promise<string | void> {
throw new Error("Method not implemented.");
}
cancelOrder(ship: EntityDict["ship"]["OpSchema"], context: BRC): Promise<void> {
throw new Error("Method not implemented.");
}
getState(ship: EntityDict["ship"]["OpSchema"]): Promise<{ iState: EntityDict["ship"]["OpSchema"]["iState"]; extraPaths?: EntityDict["ship"]["OpSchema"]["extraPaths"]; }> {
throw new Error("Method not implemented.");
}
getPrintInfo(ship: EntityDict["ship"]["OpSchema"]): Promise<{ type: "html"; data: string; }> {
throw new Error("Method not implemented.");
}
};

View File

@ -21,6 +21,8 @@ export function registerShipClazzEntity<ED extends EntityDict & BaseEntityDict,
const { attributes } = schema[entity];
assert(attributes.bizId && attributes.bizId.type === 'varchar');
assert(attributes.sort && attributes.sort.type === 'decimal');
assert(attributes.systemId && attributes.systemId.type === 'ref' && attributes.systemId.ref === 'system');
assert(attributes.disabled && attributes.disabled.type === 'boolean');
ShipClazzEntityDict[entity as string] = clazzConstructor;
}
@ -42,4 +44,62 @@ export async function getShipClazz(ship: EntityDict['ship']['OpSchema'], context
ShipClazzDict[key] = clazz;
return clazz;
}
/**
* ship时
* @param shipId
* @param context
*/
export async function getShipEntity(context: BRC): Promise<void | [string, string]> {
const systemId = context.getSystemId()!;
assert(systemId);
const entities = Object.keys(ShipClazzEntityDict);
if (!entities.length) {
return;
}
const projection: EntityDict['system']['Projection'] = {
id: 1,
};
entities.forEach(
(ele) => {
Object.assign(projection, {
[`${ele}$system`]: {
$entity: ele,
data: {
id: 1,
sort: 1,
},
filter: {
disabled: false,
},
}
})
}
)
const [system] = await context.select('system', {
data: projection,
filter: {
id: systemId!,
},
}, { dontCollect: true });
let entity = '', entityId = '';
let sort = 0;
for (const e of entities) {
const k = `${e}$system` as keyof EntityDict['system']['Schema'];
const row = system[k][0];
if (row && row.sort > sort) {
sort = row.sort;
entity = e;
entityId = row.id;
}
}
if (entity) {
return [entity, entityId];
}
}