oak-frontend-base/lib/platforms/wechatMp/index.js

663 lines
25 KiB
JavaScript

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.initialize = void 0;
require("./polyfill");
const types_1 = require("oak-domain/lib/types");
const initialize_1 = require("../../initialize");
const assert_1 = __importDefault(require("assert"));
const lodash_1 = require("lodash");
const index_1 = require("./i18n/index");
;
function callPicker(features, attr, params, entity, parent) {
const relation = features.cache.judgeRelation(entity, attr);
let subEntity;
if (relation === 2) {
subEntity = attr;
}
else {
(0, assert_1.default)(typeof relation === 'string');
subEntity = relation;
}
let url = `/pages/pickers/${subEntity}/index?oakIsPicker=true&oakParentEntity=${entity}&oakParent=${parent}&oakPath=${attr}`;
for (const k in params) {
url += `&${k}=${JSON.stringify(params[k])}`;
}
wx.navigateTo({
url,
});
}
function makeComponentMethods(features, doSubscribe, formData, exceptionRouterDict) {
return {
t(key, params) {
const i18nInstance = (0, index_1.getI18nInstance)();
if (!i18nInstance) {
throw new Error('[i18n] ensure run initI18n() in app.js before using I18n library');
}
return i18nInstance.getString(key, params);
},
subscribe() {
if (!this.subscribed) {
this.subscribed = doSubscribe(() => this.reRender());
}
},
unsubscribe() {
if (this.subscribed) {
this.subscribed();
this.subscribed = undefined;
}
},
async reRender(extra) {
if (this.data.oakFullpath) {
const rows = await features.runningTree.getFreshValue(this.data.oakFullpath);
const data = await formData.call(this, {
data: rows,
features,
params: this.data,
});
for (const k in data) {
if (data[k] === undefined) {
(0, lodash_1.assign)(data, {
[k]: null,
});
}
}
const dirty = features.runningTree.isDirty(this.data.oakFullpath);
(0, lodash_1.assign)(data, { oakDirty: dirty });
if (this.data.newOakActions) {
const oakLegalActions = [];
for (const action of this.data.newOakActions) {
try {
await features.runningTree.testAction(this.data.oakFullpath, action);
oakLegalActions.push(action);
}
catch (e) {
if (e instanceof types_1.OakInputIllegalException) {
oakLegalActions.push(action);
}
}
}
(0, lodash_1.assign)(data, {
oakLegalActions,
});
}
if (extra) {
(0, lodash_1.assign)(data, extra);
}
this.setData(data);
}
},
pushNode(path, options) {
const path2 = path ? `${this.data.oakFullpath}.${path}` : this.data.oakFullpath;
features.runningTree.pushNode(path2, options || {});
},
removeNode(parent, path) {
features.runningTree.removeNode(parent, path);
},
async getFilters() {
const namedFilters = features.runningTree.getNamedFilters(this.data.oakFullpath);
const filters = await Promise.all(namedFilters.map(({ filter }) => {
if (typeof filter === 'function') {
return filter();
}
return filter;
}));
return filters;
},
async getFilterByName(name) {
const filter = features.runningTree.getNamedFilterByName(this.data.oakFullpath, name);
if (filter?.filter) {
if (typeof filter.filter === 'function') {
return filter.filter();
}
return filter.filter;
}
return;
},
addNamedFilter(namedFilter, refresh = false) {
return features.runningTree.addNamedFilter(this.data.oakFullpath, namedFilter, refresh);
},
removeNamedFilter(namedFilter, refresh = false) {
return features.runningTree.removeNamedFilter(this.data.oakFullpath, namedFilter, refresh);
},
removeNamedFilterByName(name, refresh = false) {
return features.runningTree.removeNamedFilterByName(this.data.oakFullpath, name, refresh);
},
setNamedSorters(namedSorters) {
return features.runningTree.setNamedSorters(this.data.oakFullpath, namedSorters);
},
async getSorters() {
const namedSorters = features.runningTree.getNamedSorters(this.data.oakFullpath);
const sorters = await Promise.all(namedSorters.map(({ sorter }) => {
if (typeof sorter === 'function') {
return sorter();
}
return sorter;
}));
return sorters;
},
async getSorterByName(name) {
const sorter = features.runningTree.getNamedSorterByName(this.data.oakFullpath, name);
if (sorter?.sorter) {
if (typeof sorter.sorter === 'function') {
return sorter.sorter();
}
return sorter.sorter;
}
return;
},
addNamedSorter(namedSorter, refresh = false) {
return features.runningTree.addNamedSorter(this.data.oakFullpath, namedSorter, refresh);
},
removeNamedSorter(namedSorter, refresh = false) {
return features.runningTree.removeNamedSorter(this.data.oakFullpath, namedSorter, refresh);
},
removeNamedSorterByName(name, refresh = false) {
return features.runningTree.removeNamedSorterByName(this.data.oakFullpath, name, refresh);
},
resetUpdateData() {
return features.runningTree.resetUpdateData(this.data.oakFullpath);
},
setUpdateData(attr, value) {
if (this.data.oakExecuting) {
return;
}
return features.runningTree.setUpdateData(this.data.oakFullpath, attr, value);
},
callPicker(attr, params) {
if (this.data.oakExecuting) {
return;
}
return callPicker(features, attr, params, this.data.oakEntity, this.data.oakFullpath);
},
setFilters(filters) {
return features.runningTree.setNamedFilters(this.data.oakFullpath, filters);
},
navigateTo(options) {
const { url, events, fail, complete, success, ...rest } = options;
let url2 = url.includes('?') ? url.concat(`&oakFrom=${this.data.oakFullpath}`) : url.concat(`?oakFrom=${this.data.oakFullpath}`);
for (const param in rest) {
const param2 = param;
url2 += `&${param}=${typeof rest[param2] === 'string' ? rest[param2] : JSON.stringify(rest[param2])}`;
}
(0, lodash_1.assign)(options, {
url: url2
});
return wx.navigateTo(options);
},
async execute(action, legalExceptions) {
if (this.data.oakExecuting) {
return;
}
this.setData({
oakExecuting: true,
oakFocused: {},
});
try {
const result = await features.runningTree.execute(this.data.oakFullpath, action);
this.setData({ oakExecuting: false });
this.setData({
oakError: {
type: 'success',
msg: '操作成功',
},
});
return result;
}
catch (err) {
if (err instanceof types_1.OakException) {
if (err instanceof types_1.OakInputIllegalException) {
const attr = err.getAttributes()[0];
this.setData({
oakFocused: {
[attr]: true,
},
oakExecuting: false,
oakError: {
type: 'warning',
msg: err.message,
},
});
}
else {
const { name } = err.constructor;
const handler = exceptionRouterDict[name];
if (legalExceptions && legalExceptions.includes(name)) {
// 如果调用时就知道有异常,直接抛出
this.setData({
oakExecuting: false,
});
throw err;
}
else if (handler) {
const { hidden, level, handler: fn, router } = handler;
if (!hidden) {
this.setData({
oakExecuting: false,
oakError: {
type: level,
msg: err.message,
},
});
}
else {
this.setData({
oakExecuting: false,
});
}
if (fn) {
fn(err);
return;
}
else if (router) {
this.setData({
oakExecuting: false,
});
this.navigateTo({
url: router,
});
}
}
else {
this.setData({
oakExecuting: false,
oakError: {
type: 'warning',
msg: err.message,
},
});
}
}
}
else {
this.setData({
oakExecuting: false,
oakError: {
type: 'error',
msg: err.message,
},
});
}
throw err;
}
},
};
}
function createPageOptions(options, doSubscribe, features, exceptionRouterDict) {
const { formData, isList, pagination } = options;
const componentOptions = {
properties: {
oakEntity: String,
oakId: String,
oakPath: String,
oakParent: String,
oakProjection: String,
oakFilters: String,
oakSorters: String,
oakIsPicker: Boolean,
oakParentEntity: String,
oakFrom: String,
oakActions: String,
newOakActions: Array,
},
methods: {
async refresh() {
if (options.projection && this.data.oakFullpath) {
await features.runningTree.refresh(this.data.oakFullpath);
}
},
async onPullDownRefresh() {
if (options.projection) {
await this.refresh();
}
},
async setForeignKey(id, goBackDelta = -1) {
if (this.data.oakExecuting) {
return;
}
const { oakIsPicker, oakParent, oakPath } = this.data;
(0, assert_1.default)(oakIsPicker);
await features.runningTree.setForeignKey(oakParent, oakPath, id);
if (goBackDelta !== 0) {
wx.navigateBack({
delta: goBackDelta,
});
}
},
onForeignKeyPicked(input) {
const { id } = input.currentTarget.dataset;
this.setForeignKey(id);
},
async onLoad(options2) {
console.log('onLoad1111');
const { oakId, oakEntity, oakPath, oakProjection, oakParent, oakSorters, oakFilters, oakIsPicker, oakFrom, oakActions, ...rest } = this.data;
(0, assert_1.default)(!(isList && oakId));
const filters = [];
if (oakFilters?.length > 0) {
// 这里在跳页面的时候用this.navigate应该可以限制传过来的filter的格式
const oakFilters2 = JSON.parse(oakFilters);
filters.push(...oakFilters2);
}
else if (options.filters) {
for (const ele of options.filters) {
const { filter, "#name": name } = ele;
filters.push({
filter: typeof filter === 'function' ? await filter({
features,
rest,
onLoadOptions: options2,
}) : filter,
['#name']: name,
});
}
}
let proj = oakProjection && JSON.parse(oakProjection);
if (!proj && options.projection) {
const { projection } = options;
proj = typeof projection === 'function' ? () => projection({
features,
rest,
onLoadOptions: options2,
}) : projection;
}
let sorters = [];
if (oakSorters?.length > 0) {
// 这里在跳页面的时候用this.navigate应该可以限制传过来的sorter的格式
const oakSorters2 = JSON.parse(oakSorters);
sorters.push(...oakSorters2);
}
else if (options.sorters) {
for (const ele of options.sorters) {
const { sorter, "#name": name } = ele;
sorters.push({
sorter: typeof sorter === 'function' ? await sorter({
features,
rest,
onLoadOptions: options2,
}) : sorter,
['#name']: name,
});
}
}
const path2 = oakParent ? `${oakParent}:${oakPath || options.path}` : oakPath || options.path;
const node = await features.runningTree.createNode({
path: path2,
entity: (oakEntity || options.entity),
isList,
isPicker: oakIsPicker,
projection: proj,
pagination,
filters,
sorters,
id: oakId,
});
// const oakFullpath = oakParent ? `${oakParent}.${oakPath || options.path}` : oakPath || options.path;
this.setData({
oakEntity: node.getEntity(),
oakFullpath: path2,
oakFrom,
newOakActions: oakActions && JSON.parse(oakActions).length > 0 ? JSON.parse(oakActions) : options.actions || [],
});
if (this.isReady) {
this.refresh();
}
},
...makeComponentMethods(features, doSubscribe, formData, exceptionRouterDict),
},
lifetimes: {
created() {
this.features = features;
this.isReady = false;
},
attached() {
this.subscribe();
// const i18nInstance = getI18nInstance();
// if (i18nInstance) {
// (this as any).setData({
// [CURRENT_LOCALE_KEY]: i18nInstance.currentLocale,
// [CURRENT_LOCALE_DATA]: i18nInstance.translations,
// });
// }
},
ready() {
this.refresh();
this.isReady = true;
},
detached() {
features.runningTree.destroyNode(this.data.oakFullpath);
this.unsubscribe();
// await context.rollback();
},
},
pageLifetimes: {
show() {
this.reRender();
this.subscribe();
},
hide() {
this.unsubscribe();
}
},
};
return componentOptions;
}
function createComponentOptions(options, features, doSubscribe, exceptionRouterDict) {
const { formData } = options;
const componentOptions = {
properties: {
oakEntity: String,
oakPath: String,
oakParent: String,
},
observers: {
"oakPath": function (path) {
return this.onPropsChanged({
path,
});
},
"oakParent": function (parent) {
return this.onPropsChanged({
parent,
});
}
},
methods: {
async onPropsChanged(options) {
const path2 = options.hasOwnProperty('path') ? options.path : this.data.oakPath;
const parent2 = options.hasOwnProperty('parent') ? options.parent : this.data.oakParent;
if (path2 && parent2) {
const oakFullpath2 = `${parent2}.${path2}`;
if (oakFullpath2 !== this.data.oakFullpath) {
this.setData({
oakFullpath: oakFullpath2,
});
this.reRender();
}
}
},
...makeComponentMethods(features, doSubscribe, formData, exceptionRouterDict)
},
lifetimes: {
async created() {
this.features = features;
},
async ready() {
const { oakPath, oakParent } = this.data;
if (oakParent && oakPath) {
const oakFullpath = `${oakParent}.${oakPath}`;
this.setData({
oakFullpath,
});
this.reRender();
}
},
async attached() {
this.subscribe();
// const i18nInstance = getI18nInstance();
// if (i18nInstance) {
// (this as any).setData({
// [CURRENT_LOCALE_KEY]: i18nInstance.currentLocale,
// [CURRENT_LOCALE_DATA]: i18nInstance.translations,
// });
// }
},
async detached() {
this.unsubscribe();
// await context.rollback();
},
},
pageLifetimes: {
show() {
this.reRender();
this.subscribe();
},
hide() {
this.unsubscribe();
}
},
};
return componentOptions;
}
function mergeLifetimes(lifetimes) {
return {
async created() {
for (const ele of lifetimes) {
if (ele.created) {
await ele.created.call(this);
}
}
},
async attached() {
for (const ele of lifetimes) {
if (ele.attached) {
await ele.attached.call(this);
}
}
},
async detached() {
for (const ele of lifetimes) {
if (ele.detached) {
await ele.detached.call(this);
}
}
},
async ready() {
for (const ele of lifetimes) {
if (ele.ready) {
await ele.ready.call(this);
}
}
},
async moved() {
for (const ele of lifetimes) {
if (ele.moved) {
await ele.moved.call(this);
}
}
},
async error(err) {
for (const ele of lifetimes) {
if (ele.error) {
await ele.error.call(this, err);
}
}
},
};
}
function mergePageLifetimes(lifetimes) {
return {
async show() {
for (const ele of lifetimes) {
if (ele.show) {
await ele.show.call(this);
}
}
},
async hide() {
for (const ele of lifetimes) {
if (ele.hide) {
await ele.hide.call(this);
}
}
},
async resize(size) {
for (const ele of lifetimes) {
if (ele.resize) {
await ele.resize.call(this, size);
}
}
},
};
}
function mergeMethods(methods) {
const merged = {};
const names = (0, lodash_1.union)(...(methods.map(ele => Object.keys(ele))));
for (const name of names) {
Object.assign(merged, {
[name]: function () {
let result;
for (const m of methods) {
if (m[name]) {
result = m[name].apply(this, arguments);
}
}
return result;
}
});
}
return merged;
}
function initialize(storageSchema, createFeatures, createContext, exceptionRouters = [], triggers, checkers, watchers, aspectDict, initialData, actionDict) {
const { subscribe, features } = (0, initialize_1.initialize)(storageSchema, createFeatures, createContext, triggers, checkers, watchers, aspectDict, initialData, actionDict);
const exceptionRouterDict = {};
for (const router of exceptionRouters) {
(0, lodash_1.assign)(exceptionRouterDict, {
[router[0].name]: router[1],
});
}
return {
OakPage: (options, componentOptions = {}) => {
const oakOptions = createPageOptions(options, subscribe, features, exceptionRouterDict);
const { properties, pageLifetimes, lifetimes, methods, data, observers } = oakOptions;
const { properties: p2, pageLifetimes: pl2, lifetimes: l2, methods: m2, data: d2, observers: o2, ...restOptions } = componentOptions;
const pls = [pageLifetimes];
if (pl2) {
pls.push(pl2);
}
const ls = [lifetimes];
if (l2) {
ls.push(l2);
}
return Component({
data: (0, lodash_1.assign)({}, d2, data),
properties: (0, lodash_1.assign)({}, p2, properties),
observers: (0, lodash_1.assign)({}, o2, observers),
methods: (m2 ? mergeMethods([methods, m2]) : methods),
pageLifetimes: mergePageLifetimes(pls),
lifetimes: mergeLifetimes(ls),
...restOptions,
});
},
OakComponent: (options, componentOptions = {}) => {
const oakOptions = createComponentOptions(options, features, subscribe, exceptionRouterDict);
const { properties, pageLifetimes, lifetimes, methods, data, observers } = oakOptions;
const { properties: p2, pageLifetimes: pl2, lifetimes: l2, methods: m2, data: d2, observers: o2, ...restOptions } = componentOptions;
const pls = [pageLifetimes, pl2].filter(ele => !!ele);
const ls = [lifetimes, l2].filter(ele => !!ele);
return Component({
data: (0, lodash_1.assign)({}, d2, data),
properties: (0, lodash_1.assign)({}, p2, properties),
observers: (0, lodash_1.assign)({}, o2, observers),
methods: (m2 ? mergeMethods([methods, m2]) : methods),
pageLifetimes: mergePageLifetimes(pls),
lifetimes: mergeLifetimes(ls),
...restOptions,
});
},
features,
};
}
exports.initialize = initialize;