wechatQrCode的逻辑实现(部分)
This commit is contained in:
parent
b0ff174e44
commit
2f580ad8eb
|
|
@ -6,12 +6,18 @@ export declare abstract class GeneralRuntimeContext<ED extends EntityDict> exten
|
||||||
private getTokenFn;
|
private getTokenFn;
|
||||||
private scene;
|
private scene;
|
||||||
constructor(store: RowStore<ED, GeneralRuntimeContext<ED>>, appId: string, getToken: () => Promise<string | undefined>, scene: string);
|
constructor(store: RowStore<ED, GeneralRuntimeContext<ED>>, appId: string, getToken: () => Promise<string | undefined>, scene: string);
|
||||||
|
getApplicationId(): string;
|
||||||
getApplication(): Promise<import("oak-domain/lib/types").SelectRowShape<import("oak-app-domain/Application/Schema").Schema, {
|
getApplication(): Promise<import("oak-domain/lib/types").SelectRowShape<import("oak-app-domain/Application/Schema").Schema, {
|
||||||
id: 1;
|
id: 1;
|
||||||
name: 1;
|
name: 1;
|
||||||
config: 1;
|
config: 1;
|
||||||
type: 1;
|
type: 1;
|
||||||
systemId: 1;
|
systemId: 1;
|
||||||
|
system: {
|
||||||
|
id: 1;
|
||||||
|
name: 1;
|
||||||
|
config: 1;
|
||||||
|
};
|
||||||
}>>;
|
}>>;
|
||||||
getToken(): Promise<import("oak-domain/lib/types").SelectRowShape<ED["token"]["Schema"], {
|
getToken(): Promise<import("oak-domain/lib/types").SelectRowShape<ED["token"]["Schema"], {
|
||||||
id: 1;
|
id: 1;
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,9 @@ class GeneralRuntimeContext extends UniversalContext_1.UniversalContext {
|
||||||
this.getTokenFn = getToken;
|
this.getTokenFn = getToken;
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
}
|
}
|
||||||
|
getApplicationId() {
|
||||||
|
return this.applicationId;
|
||||||
|
}
|
||||||
async getApplication() {
|
async getApplication() {
|
||||||
const { result: [application] } = await this.rowStore.select('application', {
|
const { result: [application] } = await this.rowStore.select('application', {
|
||||||
data: {
|
data: {
|
||||||
|
|
@ -20,6 +23,11 @@ class GeneralRuntimeContext extends UniversalContext_1.UniversalContext {
|
||||||
config: 1,
|
config: 1,
|
||||||
type: 1,
|
type: 1,
|
||||||
systemId: 1,
|
systemId: 1,
|
||||||
|
system: {
|
||||||
|
id: 1,
|
||||||
|
name: 1,
|
||||||
|
config: 1,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
filter: {
|
filter: {
|
||||||
id: this.applicationId,
|
id: this.applicationId,
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ async function getUploadInfo(params, context) {
|
||||||
}, context);
|
}, context);
|
||||||
try {
|
try {
|
||||||
const { config: systemConfig } = system;
|
const { config: systemConfig } = system;
|
||||||
const originConfig = systemConfig?.Cos[origin];
|
const originConfig = systemConfig.Cos[origin];
|
||||||
const instance = new ExternalUploadClazz[origin](originConfig);
|
const instance = new ExternalUploadClazz[origin](originConfig);
|
||||||
const uploadInfo = await instance.getUploadInfo(fileName);
|
const uploadInfo = await instance.getUploadInfo(fileName);
|
||||||
return uploadInfo;
|
return uploadInfo;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { EntityDict } from "oak-app-domain";
|
||||||
|
import { WechatQrCodeProps } from 'oak-app-domain/WechatQrCode/Schema';
|
||||||
|
import { GeneralRuntimeContext } from "../RuntimeContext";
|
||||||
|
export declare function createWechatQrCode<ED extends EntityDict, T extends keyof ED, Cxt extends GeneralRuntimeContext<ED>>(options: {
|
||||||
|
entity: T;
|
||||||
|
entityId: string;
|
||||||
|
applicationId: string;
|
||||||
|
tag?: string;
|
||||||
|
lifetimeLength?: number;
|
||||||
|
permanent?: boolean;
|
||||||
|
props: WechatQrCodeProps;
|
||||||
|
}, context: Cxt): Promise<Omit<Omit<import("oak-app-domain/WechatQrCode/Schema").OpSchema, "applicationId" | "entity" | "entityId">, import("oak-domain/lib/types").InstinctiveAttributes> & {
|
||||||
|
id: string;
|
||||||
|
} & {
|
||||||
|
applicationId: string;
|
||||||
|
application?: import("oak-app-domain/Application/Schema").UpdateOperation | undefined;
|
||||||
|
} & {
|
||||||
|
[K: string]: any;
|
||||||
|
} & {
|
||||||
|
[k: string]: any;
|
||||||
|
}>;
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
"use strict";
|
||||||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.createWechatQrCode = void 0;
|
||||||
|
const assert_1 = __importDefault(require("assert"));
|
||||||
|
async function createWechatQrCode(options, context) {
|
||||||
|
const { entity, entityId, applicationId, tag, lifetimeLength, permanent, props } = options;
|
||||||
|
const { type: appType, config } = await context.getApplication();
|
||||||
|
if (appType === 'wechatMp') {
|
||||||
|
const { qrCodePrefix } = config;
|
||||||
|
const id = await generateNewId();
|
||||||
|
if (qrCodePrefix) {
|
||||||
|
// 设置了域名跳转,优先使用域名 + id来生成对应的ur
|
||||||
|
const data = {
|
||||||
|
id,
|
||||||
|
type: 'wechatMpDomainUrl',
|
||||||
|
tag,
|
||||||
|
entity,
|
||||||
|
entityId,
|
||||||
|
applicationId,
|
||||||
|
permanent: true,
|
||||||
|
url: `${qrCodePrefix}/id`,
|
||||||
|
expired: false,
|
||||||
|
props,
|
||||||
|
};
|
||||||
|
await context.rowStore.operate('wechatQrCode', {
|
||||||
|
action: 'create',
|
||||||
|
data,
|
||||||
|
}, context);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// 没有域名跳转,使用小程序码
|
||||||
|
// todo这里如果有同组的公众号,应该优先使用公众号的关注链接
|
||||||
|
const data = {
|
||||||
|
id,
|
||||||
|
type: 'wechatMpWxaCode',
|
||||||
|
tag,
|
||||||
|
entity,
|
||||||
|
entityId,
|
||||||
|
applicationId,
|
||||||
|
permanent: false,
|
||||||
|
expired: false,
|
||||||
|
props,
|
||||||
|
};
|
||||||
|
await context.rowStore.operate('wechatQrCode', {
|
||||||
|
action: 'create',
|
||||||
|
data,
|
||||||
|
}, context);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(0, assert_1.default)(appType === 'wechatPublic');
|
||||||
|
// 还未实现,记得
|
||||||
|
throw new Error('method not implemented yet');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.createWechatQrCode = createWechatQrCode;
|
||||||
|
|
@ -1,2 +1,7 @@
|
||||||
export declare const ROOT_ROLE_ID = "oak-root-role";
|
export declare const ROOT_ROLE_ID = "oak-root-role";
|
||||||
export declare const ROOT_USER_ID = "oak-root-user";
|
export declare const ROOT_USER_ID = "oak-root-user";
|
||||||
|
export declare const DefaultConfig: {
|
||||||
|
userEntityGrant: {
|
||||||
|
lifetimeLength: number;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.ROOT_USER_ID = exports.ROOT_ROLE_ID = void 0;
|
exports.DefaultConfig = exports.ROOT_USER_ID = exports.ROOT_ROLE_ID = void 0;
|
||||||
exports.ROOT_ROLE_ID = 'oak-root-role';
|
exports.ROOT_ROLE_ID = 'oak-root-role';
|
||||||
exports.ROOT_USER_ID = 'oak-root-user';
|
exports.ROOT_USER_ID = 'oak-root-user';
|
||||||
|
exports.DefaultConfig = {
|
||||||
|
userEntityGrant: {
|
||||||
|
lifetimeLength: 3600 * 1000,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ export declare type WechatMpConfig = {
|
||||||
type: 'wechatMp';
|
type: 'wechatMp';
|
||||||
appId: string;
|
appId: string;
|
||||||
appSecret: string;
|
appSecret: string;
|
||||||
|
qrCodePrefix?: string;
|
||||||
};
|
};
|
||||||
export declare type WebConfig = {
|
export declare type WebConfig = {
|
||||||
type: 'web';
|
type: 'web';
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { String, Text } from 'oak-domain/lib/types/DataType';
|
import { String, Text } from 'oak-domain/lib/types/DataType';
|
||||||
import { EntityShape } from 'oak-domain/lib/types/Entity';
|
import { EntityShape } from 'oak-domain/lib/types/Entity';
|
||||||
export declare type SystemConfig = {
|
export declare type SystemConfig = {
|
||||||
Cos: {
|
Cos?: {
|
||||||
qiniu: {
|
qiniu?: {
|
||||||
accessKey: string;
|
accessKey: string;
|
||||||
secretKey: string;
|
secretKey: string;
|
||||||
uploadHost: string;
|
uploadHost: string;
|
||||||
|
|
@ -10,11 +10,14 @@ export declare type SystemConfig = {
|
||||||
domain: string;
|
domain: string;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
Map: {
|
Map?: {
|
||||||
amap: {
|
amap?: {
|
||||||
webApiKey: string;
|
webApiKey: string;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
UserEntityGrant?: {
|
||||||
|
lifetimeLength: number;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
export interface Schema extends EntityShape {
|
export interface Schema extends EntityShape {
|
||||||
name: String<32>;
|
name: String<32>;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { String, Text } from 'oak-domain/lib/types/DataType';
|
import { String, Text, Datetime } from 'oak-domain/lib/types/DataType';
|
||||||
import { EntityShape } from 'oak-domain/lib/types/Entity';
|
import { EntityShape } from 'oak-domain/lib/types/Entity';
|
||||||
import { Schema as User } from './User';
|
import { Schema as User } from './User';
|
||||||
import { Schema as WechatQrCode } from './WechatQrCode';
|
import { Schema as WechatQrCode } from './WechatQrCode';
|
||||||
|
|
@ -8,8 +8,9 @@ export interface Schema extends EntityShape {
|
||||||
relation: String<32>;
|
relation: String<32>;
|
||||||
action: String<32>;
|
action: String<32>;
|
||||||
remark?: Text;
|
remark?: Text;
|
||||||
uuid: String<32>;
|
|
||||||
granter: User;
|
granter: User;
|
||||||
grantee?: User;
|
grantee?: User;
|
||||||
files: Array<WechatQrCode>;
|
files: Array<WechatQrCode>;
|
||||||
|
expiresAt?: Datetime;
|
||||||
|
expired?: Boolean;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,5 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
const IActionDef = {
|
|
||||||
stm: {
|
|
||||||
confirm: ['init', 'expire'],
|
|
||||||
},
|
|
||||||
is: 'init'
|
|
||||||
};
|
|
||||||
const indexes = [
|
const indexes = [
|
||||||
{
|
{
|
||||||
name: 'index_entity_entityId',
|
name: 'index_entity_entityId',
|
||||||
|
|
@ -22,8 +16,11 @@ const indexes = [
|
||||||
name: 'index_uuid',
|
name: 'index_uuid',
|
||||||
attributes: [
|
attributes: [
|
||||||
{
|
{
|
||||||
name: 'uuid',
|
name: 'expired',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'expiresAt',
|
||||||
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,22 @@
|
||||||
import { String, Text, Datetime, Boolean } from 'oak-domain/lib/types/DataType';
|
import { String, Text, Datetime, Boolean } from 'oak-domain/lib/types/DataType';
|
||||||
import { EntityShape } from 'oak-domain/lib/types/Entity';
|
import { EntityShape } from 'oak-domain/lib/types/Entity';
|
||||||
import { Schema as Application } from './Application';
|
import { Schema as Application } from './Application';
|
||||||
|
export declare type WechatQrCodeProps = {
|
||||||
|
pathname: string;
|
||||||
|
props?: Record<string, any>;
|
||||||
|
state?: Record<string, any>;
|
||||||
|
};
|
||||||
export interface Schema extends EntityShape {
|
export interface Schema extends EntityShape {
|
||||||
entity: String<32>;
|
entity: String<32>;
|
||||||
entityId: String<64>;
|
entityId: String<64>;
|
||||||
type?: String<32>;
|
type: 'wechatMpDomainUrl' | 'wechatMpWxaCode' | 'wechatPublic' | 'wechatPublicForMp';
|
||||||
expiresAt: Datetime;
|
tag?: String<32>;
|
||||||
expired: Boolean;
|
expiresAt?: Datetime;
|
||||||
autoExtend: Boolean;
|
expired?: Boolean;
|
||||||
sceneStr?: Text;
|
|
||||||
ticket?: Text;
|
ticket?: Text;
|
||||||
url?: String<64>;
|
url?: String<64>;
|
||||||
isPermanent: Boolean;
|
permanent: Boolean;
|
||||||
buffer?: Text;
|
buffer?: Text;
|
||||||
application: Application;
|
application: Application;
|
||||||
props?: Object;
|
props: WechatQrCodeProps;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
const indexes = [
|
const indexes = [
|
||||||
{
|
{
|
||||||
name: 'index_entity_entityId',
|
name: 'index_entity_entityId_tag',
|
||||||
attributes: [
|
attributes: [
|
||||||
{
|
{
|
||||||
name: 'entity',
|
name: 'entity',
|
||||||
|
|
@ -10,6 +10,9 @@ const indexes = [
|
||||||
{
|
{
|
||||||
name: 'entityId',
|
name: 'entityId',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'tag',
|
||||||
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { Feature } from 'oak-frontend-base';
|
||||||
import { Aspect, Context, DeduceCreateOperationData } from 'oak-domain/lib/types';
|
import { Aspect, Context, DeduceCreateOperationData } from 'oak-domain/lib/types';
|
||||||
export declare class ExtraFile<ED extends EntityDict, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>> extends Feature<ED, Cxt, AD> {
|
export declare class ExtraFile<ED extends EntityDict, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>> extends Feature<ED, Cxt, AD> {
|
||||||
constructor();
|
constructor();
|
||||||
upload(extraFile: DeduceCreateOperationData<ED['extraFile']['Schema']>, scene: string): Promise<{
|
upload(extraFile: DeduceCreateOperationData<EntityDict['extraFile']['OpSchema']>, scene: string): Promise<{
|
||||||
url: string;
|
url: string;
|
||||||
bucket: string;
|
bucket: string;
|
||||||
}>;
|
}>;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { EntityDict as BaseEntityDict } from 'oak-app-domain/EntityDict';
|
import { EntityDict as BaseEntityDict } from 'oak-app-domain/EntityDict';
|
||||||
import { Trigger } from 'oak-domain/lib/types';
|
import { Trigger } from 'oak-domain/lib/types';
|
||||||
declare const _default: (Trigger<BaseEntityDict, "address", import("..").GeneralRuntimeContext<BaseEntityDict>> | Trigger<BaseEntityDict, "user", import("..").GeneralRuntimeContext<BaseEntityDict>> | Trigger<BaseEntityDict, "userEntityGrant", import("..").GeneralRuntimeContext<BaseEntityDict>>)[];
|
declare const _default: (Trigger<BaseEntityDict, "address", import("..").GeneralRuntimeContext<BaseEntityDict>> | Trigger<BaseEntityDict, "user", import("..").GeneralRuntimeContext<BaseEntityDict>> | Trigger<BaseEntityDict, "userEntityGrant", import("..").GeneralRuntimeContext<BaseEntityDict>> | Trigger<BaseEntityDict, "wechatQrCode", import("..").GeneralRuntimeContext<BaseEntityDict>>)[];
|
||||||
export default _default;
|
export default _default;
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
const address_1 = __importDefault(require("./address"));
|
const address_1 = __importDefault(require("./address"));
|
||||||
const user_1 = __importDefault(require("./user"));
|
const user_1 = __importDefault(require("./user"));
|
||||||
const userEntityGrant_1 = __importDefault(require("./userEntityGrant"));
|
const userEntityGrant_1 = __importDefault(require("./userEntityGrant"));
|
||||||
exports.default = [...address_1.default, ...user_1.default, ...userEntityGrant_1.default];
|
const wechatQrCode_1 = __importDefault(require("./wechatQrCode"));
|
||||||
|
exports.default = [...address_1.default, ...user_1.default, ...userEntityGrant_1.default, ...wechatQrCode_1.default];
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
const lodash_1 = require("lodash");
|
const lodash_1 = require("lodash");
|
||||||
const types_1 = require("oak-domain/lib/types");
|
const types_1 = require("oak-domain/lib/types");
|
||||||
const assert_1 = __importDefault(require("assert"));
|
const assert_1 = __importDefault(require("assert"));
|
||||||
|
const constants_1 = require("../constants");
|
||||||
|
const wechatQrCode_1 = require("../aspects/wechatQrCode");
|
||||||
const triggers = [
|
const triggers = [
|
||||||
{
|
{
|
||||||
name: '当创建userEntityGrant时,查询是否有未过期的实体',
|
name: '当创建userEntityGrant时,查询是否有未过期可重用的对象',
|
||||||
entity: 'userEntityGrant',
|
entity: 'userEntityGrant',
|
||||||
action: 'create',
|
action: 'create',
|
||||||
when: 'before',
|
when: 'before',
|
||||||
|
|
@ -16,8 +18,9 @@ const triggers = [
|
||||||
const { data, filter } = operation;
|
const { data, filter } = operation;
|
||||||
const fn = async (userEntityGrantData) => {
|
const fn = async (userEntityGrantData) => {
|
||||||
const { userId } = (await context.getToken());
|
const { userId } = (await context.getToken());
|
||||||
|
const { id: applicationId, config: appConfig, system: { config: SystemConfig } } = (await context.getApplication());
|
||||||
(0, assert_1.default)(userId);
|
(0, assert_1.default)(userId);
|
||||||
const { action, entity, entityId, relation } = userEntityGrantData;
|
const { action, entity, entityId, relation, id } = userEntityGrantData;
|
||||||
const { result } = await context.rowStore.select('userEntityGrant', {
|
const { result } = await context.rowStore.select('userEntityGrant', {
|
||||||
data: {
|
data: {
|
||||||
id: 1,
|
id: 1,
|
||||||
|
|
@ -25,11 +28,14 @@ const triggers = [
|
||||||
entity: 1,
|
entity: 1,
|
||||||
entityId: 1,
|
entityId: 1,
|
||||||
relation: 1,
|
relation: 1,
|
||||||
iState: 1,
|
expired: 1,
|
||||||
granterId: 1,
|
granterId: 1,
|
||||||
},
|
},
|
||||||
filter: {
|
filter: {
|
||||||
iState: 'init',
|
expired: false,
|
||||||
|
expiresAt: {
|
||||||
|
$gt: Date.now() - 600 * 1000,
|
||||||
|
},
|
||||||
action,
|
action,
|
||||||
entity,
|
entity,
|
||||||
entityId,
|
entityId,
|
||||||
|
|
@ -42,9 +48,26 @@ const triggers = [
|
||||||
if (result.length) {
|
if (result.length) {
|
||||||
throw new types_1.OakCongruentRowExists(result[0], '有可重用的userEntityGrant');
|
throw new types_1.OakCongruentRowExists(result[0], '有可重用的userEntityGrant');
|
||||||
}
|
}
|
||||||
|
const expiresAt = Date.now() + (SystemConfig.UserEntityGrant?.lifetimeLength || constants_1.DefaultConfig.userEntityGrant.lifetimeLength);
|
||||||
(0, lodash_1.assign)(userEntityGrantData, {
|
(0, lodash_1.assign)(userEntityGrantData, {
|
||||||
granterId: userId,
|
granterId: userId,
|
||||||
|
expiresAt,
|
||||||
|
expired: false,
|
||||||
});
|
});
|
||||||
|
// 如果是微信体系的应用,为之创建一个默认的weChatQrCode
|
||||||
|
if (['wechatPublic', 'wechatMp'].includes(appConfig.type)) {
|
||||||
|
await (0, wechatQrCode_1.createWechatQrCode)({
|
||||||
|
entity: 'userEntityGrant',
|
||||||
|
entityId: id,
|
||||||
|
applicationId,
|
||||||
|
props: {
|
||||||
|
pathname: 'pages/userEntityGrant/confirm',
|
||||||
|
props: {
|
||||||
|
oakId: id,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}, context);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
if (data instanceof Array) {
|
if (data instanceof Array) {
|
||||||
(0, assert_1.default)('授权不存在一对多的情况');
|
(0, assert_1.default)('授权不存在一对多的情况');
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { EntityDict } from 'oak-app-domain/EntityDict';
|
||||||
|
import { Trigger } from 'oak-domain/lib/types/Trigger';
|
||||||
|
import { GeneralRuntimeContext } from '../RuntimeContext';
|
||||||
|
declare const triggers: Trigger<EntityDict, 'wechatQrCode', GeneralRuntimeContext<EntityDict>>[];
|
||||||
|
export default triggers;
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
"use strict";
|
||||||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
const assert_1 = __importDefault(require("assert"));
|
||||||
|
const oak_wechat_sdk_1 = require("oak-wechat-sdk");
|
||||||
|
const uuid_1 = require("oak-domain/lib/utils/uuid");
|
||||||
|
const lodash_1 = require("lodash");
|
||||||
|
const triggers = [
|
||||||
|
{
|
||||||
|
name: '选择userEntityGrant时,动态生成需要的数据',
|
||||||
|
entity: 'wechatQrCode',
|
||||||
|
action: 'select',
|
||||||
|
when: 'after',
|
||||||
|
fn: async ({ result }, context, params) => {
|
||||||
|
let count = 0;
|
||||||
|
const application = await context.getApplication();
|
||||||
|
const { type, config } = application;
|
||||||
|
(0, assert_1.default)(type === 'wechatMp' || config.type === 'wechatMp');
|
||||||
|
const config2 = config;
|
||||||
|
const { appId, appSecret } = config2;
|
||||||
|
for (const code of result) {
|
||||||
|
const { type, expired, url, id } = code;
|
||||||
|
if (type === 'wechatMpWxaCode') {
|
||||||
|
// 小程序码去实时获取(暂时不考虑缓存)
|
||||||
|
const wechatInstance = oak_wechat_sdk_1.WechatSDK.getInstance(appId, appSecret, 'wechatMp');
|
||||||
|
const buffer = await wechatInstance.getMpUnlimitWxaCode({
|
||||||
|
scene: (0, uuid_1.shrinkUuidTo32Bytes)(id),
|
||||||
|
page: 'pages/index/index', // todo,这里用其它的页面微信服务器拒绝,因为没发布。应该是 pages/wechatQrCode/scan/index
|
||||||
|
});
|
||||||
|
// 把arrayBuffer转成字符串返回
|
||||||
|
const str = String.fromCharCode(...new Uint8Array(buffer));
|
||||||
|
(0, lodash_1.assign)(code, {
|
||||||
|
buffer: str,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (expired) {
|
||||||
|
// 如果过期了,在这里生成新的临时码并修改值(公众号)
|
||||||
|
throw new Error('not implemented yet');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
];
|
||||||
|
exports.default = triggers;
|
||||||
|
|
@ -17,6 +17,10 @@ export abstract class GeneralRuntimeContext<ED extends EntityDict> extends Unive
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getApplicationId() {
|
||||||
|
return this.applicationId;
|
||||||
|
}
|
||||||
|
|
||||||
async getApplication () {
|
async getApplication () {
|
||||||
const { result: [application] } = await this.rowStore.select('application', {
|
const { result: [application] } = await this.rowStore.select('application', {
|
||||||
data: {
|
data: {
|
||||||
|
|
@ -24,12 +28,28 @@ export abstract class GeneralRuntimeContext<ED extends EntityDict> extends Unive
|
||||||
name: 1,
|
name: 1,
|
||||||
config: 1,
|
config: 1,
|
||||||
type: 1,
|
type: 1,
|
||||||
systemId: 1,
|
systemId: 1,
|
||||||
|
system: {
|
||||||
|
id: 1,
|
||||||
|
name: 1,
|
||||||
|
config: 1,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
filter: {
|
filter: {
|
||||||
id: this.applicationId,
|
id: this.applicationId,
|
||||||
}
|
}
|
||||||
}, this) as SelectionResult<EntityDict['application']['Schema'], {id: 1, name: 1, config: 1, type: 1, systemId: 1}>;
|
}, this) as SelectionResult<EntityDict['application']['Schema'], {
|
||||||
|
id: 1,
|
||||||
|
name: 1,
|
||||||
|
config: 1,
|
||||||
|
type: 1,
|
||||||
|
systemId: 1,
|
||||||
|
system: {
|
||||||
|
id: 1,
|
||||||
|
name: 1,
|
||||||
|
config: 1,
|
||||||
|
},
|
||||||
|
}>;
|
||||||
|
|
||||||
return application;
|
return application;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ export async function getUploadInfo<ED extends EntityDict, Cxt extends GeneralRu
|
||||||
}, context);
|
}, context);
|
||||||
try {
|
try {
|
||||||
const { config: systemConfig } = system;
|
const { config: systemConfig } = system;
|
||||||
const originConfig = (systemConfig as SystemConfig)?.Cos[
|
const originConfig = (systemConfig as SystemConfig).Cos![
|
||||||
origin as keyof typeof systemConfig
|
origin as keyof typeof systemConfig
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
import assert from "assert";
|
||||||
|
import { EntityDict } from "oak-app-domain";
|
||||||
|
import { WechatMpConfig } from "oak-app-domain/Application/Schema";
|
||||||
|
import { CreateOperationData as CreateWechatQrcodeData, WechatQrCodeProps } from 'oak-app-domain/WechatQrCode/Schema';
|
||||||
|
import { GeneralRuntimeContext } from "../RuntimeContext";
|
||||||
|
|
||||||
|
export async function createWechatQrCode<ED extends EntityDict, T extends keyof ED, Cxt extends GeneralRuntimeContext<ED>>(options: {
|
||||||
|
entity: T;
|
||||||
|
entityId: string;
|
||||||
|
applicationId: string;
|
||||||
|
tag?: string;
|
||||||
|
lifetimeLength?: number;
|
||||||
|
permanent?: boolean;
|
||||||
|
props: WechatQrCodeProps;
|
||||||
|
}, context: Cxt) {
|
||||||
|
const { entity, entityId, applicationId, tag, lifetimeLength, permanent, props } = options;
|
||||||
|
const { type: appType, config } = await context.getApplication();
|
||||||
|
|
||||||
|
if (appType === 'wechatMp') {
|
||||||
|
const { qrCodePrefix } = (<WechatMpConfig>config);
|
||||||
|
const id = await generateNewId();
|
||||||
|
if (qrCodePrefix) {
|
||||||
|
// 设置了域名跳转,优先使用域名 + id来生成对应的ur
|
||||||
|
const data: CreateWechatQrcodeData = {
|
||||||
|
id,
|
||||||
|
type: 'wechatMpDomainUrl',
|
||||||
|
tag,
|
||||||
|
entity,
|
||||||
|
entityId,
|
||||||
|
applicationId,
|
||||||
|
permanent: true,
|
||||||
|
url: `${qrCodePrefix}/id`,
|
||||||
|
expired: false,
|
||||||
|
props,
|
||||||
|
};
|
||||||
|
await context.rowStore.operate('wechatQrCode', {
|
||||||
|
action: 'create',
|
||||||
|
data,
|
||||||
|
}, context);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// 没有域名跳转,使用小程序码
|
||||||
|
// todo这里如果有同组的公众号,应该优先使用公众号的关注链接
|
||||||
|
const data: CreateWechatQrcodeData = {
|
||||||
|
id,
|
||||||
|
type: 'wechatMpWxaCode',
|
||||||
|
tag,
|
||||||
|
entity,
|
||||||
|
entityId,
|
||||||
|
applicationId,
|
||||||
|
permanent: false,
|
||||||
|
expired: false,
|
||||||
|
props,
|
||||||
|
};
|
||||||
|
|
||||||
|
await context.rowStore.operate('wechatQrCode', {
|
||||||
|
action: 'create',
|
||||||
|
data,
|
||||||
|
}, context);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert(appType === 'wechatPublic');
|
||||||
|
// 还未实现,记得
|
||||||
|
throw new Error('method not implemented yet');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,2 +1,8 @@
|
||||||
export const ROOT_ROLE_ID = 'oak-root-role';
|
export const ROOT_ROLE_ID = 'oak-root-role';
|
||||||
export const ROOT_USER_ID = 'oak-root-user';
|
export const ROOT_USER_ID = 'oak-root-user';
|
||||||
|
|
||||||
|
export const DefaultConfig = {
|
||||||
|
userEntityGrant: {
|
||||||
|
lifetimeLength: 3600 * 1000,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -7,6 +7,7 @@ export type WechatMpConfig = {
|
||||||
type: 'wechatMp';
|
type: 'wechatMp';
|
||||||
appId: string;
|
appId: string;
|
||||||
appSecret: string;
|
appSecret: string;
|
||||||
|
qrCodePrefix?: string; // 扫描二维码跳转的前缀(在小程序后台配置,必须统一跳转到weCharQrCode/scan/index)
|
||||||
};
|
};
|
||||||
|
|
||||||
export type WebConfig = {
|
export type WebConfig = {
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ import { String, Int, Datetime, Image, Boolean, Text } from 'oak-domain/lib/type
|
||||||
import { EntityShape } from 'oak-domain/lib/types/Entity';
|
import { EntityShape } from 'oak-domain/lib/types/Entity';
|
||||||
|
|
||||||
export type SystemConfig = {
|
export type SystemConfig = {
|
||||||
Cos: {
|
Cos?: {
|
||||||
qiniu: {
|
qiniu?: {
|
||||||
accessKey: string;
|
accessKey: string;
|
||||||
secretKey: string;
|
secretKey: string;
|
||||||
uploadHost: string; //七牛上传域名
|
uploadHost: string; //七牛上传域名
|
||||||
|
|
@ -11,11 +11,14 @@ export type SystemConfig = {
|
||||||
domain: string;
|
domain: string;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
Map: {
|
Map?: {
|
||||||
amap: {
|
amap?: {
|
||||||
webApiKey: string; // 高德访问rest服务接口的key
|
webApiKey: string; // 高德访问rest服务接口的key
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
UserEntityGrant?: {
|
||||||
|
lifetimeLength: number; // 授权的过期时间(ms)
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface Schema extends EntityShape {
|
export interface Schema extends EntityShape {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
import { String, Text } from 'oak-domain/lib/types/DataType';
|
import { String, Text, Datetime } from 'oak-domain/lib/types/DataType';
|
||||||
import { EntityShape } from 'oak-domain/lib/types/Entity';
|
import { EntityShape } from 'oak-domain/lib/types/Entity';
|
||||||
import { Index } from 'oak-domain/lib/types/Storage';
|
import { Index } from 'oak-domain/lib/types/Storage';
|
||||||
import { Schema as User } from './User';
|
import { Schema as User } from './User';
|
||||||
import { Schema as WechatQrCode } from './WechatQrCode';
|
import { Schema as WechatQrCode } from './WechatQrCode';
|
||||||
import { ActionDef } from 'oak-domain/lib/types/Action';
|
|
||||||
|
|
||||||
export interface Schema extends EntityShape {
|
export interface Schema extends EntityShape {
|
||||||
entity: String<32>;
|
entity: String<32>;
|
||||||
|
|
@ -11,24 +10,13 @@ export interface Schema extends EntityShape {
|
||||||
relation: String<32>;
|
relation: String<32>;
|
||||||
action: String<32>;
|
action: String<32>;
|
||||||
remark?: Text;
|
remark?: Text;
|
||||||
uuid: String<32>;
|
|
||||||
granter: User;
|
granter: User;
|
||||||
grantee?: User;
|
grantee?: User;
|
||||||
files: Array<WechatQrCode>;
|
files: Array<WechatQrCode>;
|
||||||
|
expiresAt?: Datetime;
|
||||||
|
expired?: Boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
type IAction = 'confirm';
|
|
||||||
type IState = | 'init'| 'expire';
|
|
||||||
|
|
||||||
const IActionDef: ActionDef<IAction, IState> = {
|
|
||||||
stm: {
|
|
||||||
confirm: ['init', 'expire'],
|
|
||||||
},
|
|
||||||
is: 'init'
|
|
||||||
};
|
|
||||||
|
|
||||||
type Action = IAction;
|
|
||||||
|
|
||||||
const indexes: Index<Schema>[] = [
|
const indexes: Index<Schema>[] = [
|
||||||
{
|
{
|
||||||
name: 'index_entity_entityId',
|
name: 'index_entity_entityId',
|
||||||
|
|
@ -45,8 +33,11 @@ const indexes: Index<Schema>[] = [
|
||||||
name: 'index_uuid',
|
name: 'index_uuid',
|
||||||
attributes: [
|
attributes: [
|
||||||
{
|
{
|
||||||
name: 'uuid',
|
name: 'expired',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'expiresAt',
|
||||||
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -3,25 +3,30 @@ import { EntityShape } from 'oak-domain/lib/types/Entity';
|
||||||
import { Index } from 'oak-domain/lib/types/Storage';
|
import { Index } from 'oak-domain/lib/types/Storage';
|
||||||
import { Schema as Application } from './Application';
|
import { Schema as Application } from './Application';
|
||||||
|
|
||||||
|
export type WechatQrCodeProps = {
|
||||||
|
pathname: string;
|
||||||
|
props?: Record<string, any>;
|
||||||
|
state?: Record<string, any>;
|
||||||
|
};
|
||||||
|
|
||||||
export interface Schema extends EntityShape {
|
export interface Schema extends EntityShape {
|
||||||
entity: String<32>;
|
entity: String<32>;
|
||||||
entityId: String<64>;
|
entityId: String<64>;
|
||||||
type?: String<32>; //类型
|
type: 'wechatMpDomainUrl' | 'wechatMpWxaCode' | 'wechatPublic' | 'wechatPublicForMp',
|
||||||
expiresAt: Datetime; // 过期时间
|
tag?: String<32>; // 调用者加的tag
|
||||||
expired: Boolean; //是否过期
|
expiresAt?: Datetime; // 过期时间
|
||||||
autoExtend: Boolean;
|
expired?: Boolean; //是否过期
|
||||||
sceneStr?: Text;
|
|
||||||
ticket?: Text;
|
ticket?: Text;
|
||||||
url?: String<64>;
|
url?: String<64>;
|
||||||
isPermanent: Boolean; //是否永久码
|
permanent: Boolean; //是否永久码
|
||||||
buffer?: Text; // 若没有url,使用buffer存储生成的小程序码数据(base64)
|
buffer?: Text; // 若没有url,使用buffer存储生成的小程序码数据(base64)
|
||||||
application: Application;
|
application: Application;
|
||||||
props?: Object;
|
props: WechatQrCodeProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
const indexes: Index<Schema>[] = [
|
const indexes: Index<Schema>[] = [
|
||||||
{
|
{
|
||||||
name: 'index_entity_entityId',
|
name: 'index_entity_entityId_tag',
|
||||||
attributes: [
|
attributes: [
|
||||||
{
|
{
|
||||||
name: 'entity',
|
name: 'entity',
|
||||||
|
|
@ -29,6 +34,9 @@ const indexes: Index<Schema>[] = [
|
||||||
{
|
{
|
||||||
name: 'entityId',
|
name: 'entityId',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'tag',
|
||||||
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ export class ExtraFile<
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
@Action
|
@Action
|
||||||
async upload(extraFile: DeduceCreateOperationData<ED['extraFile']['Schema']>, scene: string) {
|
async upload(extraFile: DeduceCreateOperationData<EntityDict['extraFile']['OpSchema']>, scene: string) {
|
||||||
try {
|
try {
|
||||||
const { origin, extra1: filePath, filename: fileName } = extraFile;
|
const { origin, extra1: filePath, filename: fileName } = extraFile;
|
||||||
const uploadInfo =
|
const uploadInfo =
|
||||||
|
|
|
||||||
|
|
@ -4,5 +4,6 @@ import { Trigger } from 'oak-domain/lib/types';
|
||||||
import addressTriggers from './address';
|
import addressTriggers from './address';
|
||||||
import userTriggers from './user';
|
import userTriggers from './user';
|
||||||
import userEntityGrantTriggers from './userEntityGrant';
|
import userEntityGrantTriggers from './userEntityGrant';
|
||||||
|
import wechatQrCodeTriggers from './wechatQrCode';
|
||||||
|
|
||||||
export default [...addressTriggers, ...userTriggers, ...userEntityGrantTriggers];
|
export default [...addressTriggers, ...userTriggers, ...userEntityGrantTriggers, ...wechatQrCodeTriggers];
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,12 @@ import { CreateOperationData as CreateUserEntityGrantData } from 'oak-app-domain
|
||||||
import { assign, keys } from 'lodash';
|
import { assign, keys } from 'lodash';
|
||||||
import { OakCongruentRowExists } from 'oak-domain/lib/types';
|
import { OakCongruentRowExists } from 'oak-domain/lib/types';
|
||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
|
import { DefaultConfig } from '../constants';
|
||||||
|
import { createWechatQrCode } from '../aspects/wechatQrCode';
|
||||||
|
|
||||||
const triggers: Trigger<EntityDict, 'userEntityGrant', GeneralRuntimeContext<EntityDict>>[] = [
|
const triggers: Trigger<EntityDict, 'userEntityGrant', GeneralRuntimeContext<EntityDict>>[] = [
|
||||||
{
|
{
|
||||||
name: '当创建userEntityGrant时,查询是否有未过期的实体',
|
name: '当创建userEntityGrant时,查询是否有未过期可重用的对象',
|
||||||
entity: 'userEntityGrant',
|
entity: 'userEntityGrant',
|
||||||
action: 'create',
|
action: 'create',
|
||||||
when: 'before',
|
when: 'before',
|
||||||
|
|
@ -17,8 +19,9 @@ const triggers: Trigger<EntityDict, 'userEntityGrant', GeneralRuntimeContext<Ent
|
||||||
const { data, filter } = operation;
|
const { data, filter } = operation;
|
||||||
const fn = async (userEntityGrantData: CreateUserEntityGrantData) => {
|
const fn = async (userEntityGrantData: CreateUserEntityGrantData) => {
|
||||||
const { userId } = (await context.getToken())!;
|
const { userId } = (await context.getToken())!;
|
||||||
|
const { id: applicationId, config: appConfig, system: { config: SystemConfig }} = (await context.getApplication());
|
||||||
assert(userId);
|
assert(userId);
|
||||||
const { action, entity, entityId, relation} = userEntityGrantData;
|
const { action, entity, entityId, relation, id } = userEntityGrantData;
|
||||||
const { result } = await context.rowStore.select('userEntityGrant', {
|
const { result } = await context.rowStore.select('userEntityGrant', {
|
||||||
data: {
|
data: {
|
||||||
id: 1,
|
id: 1,
|
||||||
|
|
@ -26,11 +29,14 @@ const triggers: Trigger<EntityDict, 'userEntityGrant', GeneralRuntimeContext<Ent
|
||||||
entity: 1,
|
entity: 1,
|
||||||
entityId: 1,
|
entityId: 1,
|
||||||
relation: 1,
|
relation: 1,
|
||||||
iState: 1,
|
expired: 1,
|
||||||
granterId: 1,
|
granterId: 1,
|
||||||
},
|
},
|
||||||
filter: {
|
filter: {
|
||||||
iState: 'init',
|
expired: false,
|
||||||
|
expiresAt: {
|
||||||
|
$gt: Date.now() - 600 * 1000,
|
||||||
|
}, // 至少有10分钟有效期的
|
||||||
action,
|
action,
|
||||||
entity,
|
entity,
|
||||||
entityId,
|
entityId,
|
||||||
|
|
@ -44,9 +50,27 @@ const triggers: Trigger<EntityDict, 'userEntityGrant', GeneralRuntimeContext<Ent
|
||||||
throw new OakCongruentRowExists(result[0] as any, '有可重用的userEntityGrant');
|
throw new OakCongruentRowExists(result[0] as any, '有可重用的userEntityGrant');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const expiresAt = Date.now() + (SystemConfig.UserEntityGrant?.lifetimeLength || DefaultConfig.userEntityGrant.lifetimeLength);
|
||||||
|
|
||||||
assign(userEntityGrantData, {
|
assign(userEntityGrantData, {
|
||||||
granterId: userId,
|
granterId: userId,
|
||||||
|
expiresAt,
|
||||||
|
expired: false,
|
||||||
});
|
});
|
||||||
|
// 如果是微信体系的应用,为之创建一个默认的weChatQrCode
|
||||||
|
if (['wechatPublic', 'wechatMp'].includes(appConfig.type)) {
|
||||||
|
await createWechatQrCode({
|
||||||
|
entity: 'userEntityGrant',
|
||||||
|
entityId: id,
|
||||||
|
applicationId,
|
||||||
|
props: {
|
||||||
|
pathname: 'pages/userEntityGrant/confirm',
|
||||||
|
props: {
|
||||||
|
oakId: id,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}, context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (data instanceof Array) {
|
if (data instanceof Array) {
|
||||||
assert('授权不存在一对多的情况')
|
assert('授权不存在一对多的情况')
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
import { EntityDict } from 'oak-app-domain/EntityDict';
|
||||||
|
import { SelectTriggerAfter, Trigger } from 'oak-domain/lib/types/Trigger';
|
||||||
|
import { GeneralRuntimeContext } from '../RuntimeContext';
|
||||||
|
|
||||||
|
import assert from 'assert';
|
||||||
|
import { WechatSDK } from 'oak-wechat-sdk';
|
||||||
|
import { WechatMpConfig } from 'oak-app-domain/Application/Schema';
|
||||||
|
import { shrinkUuidTo32Bytes } from 'oak-domain/lib/utils/uuid';
|
||||||
|
import { assign } from 'lodash';
|
||||||
|
|
||||||
|
const triggers: Trigger<EntityDict, 'wechatQrCode', GeneralRuntimeContext<EntityDict>>[] = [
|
||||||
|
{
|
||||||
|
name: '选择userEntityGrant时,动态生成需要的数据',
|
||||||
|
entity: 'wechatQrCode',
|
||||||
|
action: 'select',
|
||||||
|
when: 'after',
|
||||||
|
fn: async ({ result }, context, params) => {
|
||||||
|
let count = 0;
|
||||||
|
const application = await context.getApplication();
|
||||||
|
const { type, config } = application;
|
||||||
|
|
||||||
|
assert(type === 'wechatMp' || config.type === 'wechatMp');
|
||||||
|
const config2 = config as WechatMpConfig;
|
||||||
|
const { appId, appSecret } = config2;
|
||||||
|
for (const code of result) {
|
||||||
|
const { type, expired, url, id } = code;
|
||||||
|
if (type === 'wechatMpWxaCode') {
|
||||||
|
// 小程序码去实时获取(暂时不考虑缓存)
|
||||||
|
const wechatInstance = WechatSDK.getInstance(appId, appSecret, 'wechatMp');
|
||||||
|
const buffer = await wechatInstance.getMpUnlimitWxaCode({
|
||||||
|
scene: shrinkUuidTo32Bytes(id),
|
||||||
|
page: 'pages/index/index', // todo,这里用其它的页面微信服务器拒绝,因为没发布。应该是 pages/wechatQrCode/scan/index
|
||||||
|
});
|
||||||
|
// 把arrayBuffer转成字符串返回
|
||||||
|
const str = String.fromCharCode(...new Uint8Array(buffer));
|
||||||
|
assign(code, {
|
||||||
|
buffer: str,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (expired) {
|
||||||
|
// 如果过期了,在这里生成新的临时码并修改值(公众号)
|
||||||
|
throw new Error('not implemented yet');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
} as SelectTriggerAfter<EntityDict, 'wechatQrCode', GeneralRuntimeContext<EntityDict>>,
|
||||||
|
];
|
||||||
|
export default triggers;
|
||||||
|
|
@ -131,7 +131,8 @@ OakComponent({
|
||||||
filename: filename,
|
filename: filename,
|
||||||
},
|
},
|
||||||
beforeExecute: async (updateData) => {
|
beforeExecute: async (updateData) => {
|
||||||
const { url, bucket } = await this.features.extraFile.upload(updateData as DeduceCreateOperationData<EntityDict['extraFile']['Schema']>, "extraFile:gallery:upload");
|
const { url, bucket } = await this.features.extraFile.upload(
|
||||||
|
updateData as DeduceCreateOperationData<EntityDict['extraFile']['Schema']>, "extraFile:gallery:upload");
|
||||||
Object.assign(updateData, {
|
Object.assign(updateData, {
|
||||||
bucket,
|
bucket,
|
||||||
extra1: url,
|
extra1: url,
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ OakPage({
|
||||||
relation: 1,
|
relation: 1,
|
||||||
action: 1,
|
action: 1,
|
||||||
remark: 1,
|
remark: 1,
|
||||||
uuid: 1,
|
|
||||||
granterId: 1,
|
granterId: 1,
|
||||||
granteeId: 1,
|
granteeId: 1,
|
||||||
wechatQrCode$entity: {
|
wechatQrCode$entity: {
|
||||||
|
|
@ -21,15 +20,9 @@ OakPage({
|
||||||
type: 1,//类型
|
type: 1,//类型
|
||||||
expiresAt: 1,// 过期时间
|
expiresAt: 1,// 过期时间
|
||||||
expired: 1, //是否过期
|
expired: 1, //是否过期
|
||||||
autoExtend: 1,
|
|
||||||
sceneStr: 1,
|
|
||||||
ticket: 1,
|
ticket: 1,
|
||||||
url: 1,
|
url: 1,
|
||||||
isPermanent: 1, //是否永久码
|
buffer: 1,
|
||||||
},
|
|
||||||
filter: {
|
|
||||||
entity: 'userEntityGrant',
|
|
||||||
expired: false,
|
|
||||||
},
|
},
|
||||||
indexFrom: 0,
|
indexFrom: 0,
|
||||||
count: 1,
|
count: 1,
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ OakPage({
|
||||||
relation: 1,
|
relation: 1,
|
||||||
action: 1,
|
action: 1,
|
||||||
remark: 1,
|
remark: 1,
|
||||||
uuid: 1,
|
|
||||||
granterId: 1,
|
granterId: 1,
|
||||||
granteeId: 1,
|
granteeId: 1,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue