ngx-bit
Version:
A flexible NG-ZORRO helper library
674 lines (664 loc) • 21.5 kB
JavaScript
import * as i0 from '@angular/core';
import { Injectable, Optional, NgModule } from '@angular/core';
import * as i4 from '@angular/router';
import { PRIMARY_OUTLET, Router } from '@angular/router';
import * as i6 from 'ng-zorro-antd/i18n';
import { NzI18nService } from 'ng-zorro-antd/i18n';
import * as i5 from '@angular/common';
import { Location } from '@angular/common';
import { AsyncSubject, Subject, of } from 'rxjs';
import * as i2 from '@angular/common/http';
import { HttpClient } from '@angular/common/http';
import { StorageMap } from '@ngx-pwa/local-storage';
import { filter, switchMap, map } from 'rxjs/operators';
import * as i3 from '@ngx-pwa/local-storage/public-api';
import { NzIconService } from 'ng-zorro-antd/icon';
class BitConfig {
}
BitConfig.ɵprov = i0.ɵɵdefineInjectable({ factory: function BitConfig_Factory() { return new BitConfig(); }, token: BitConfig, providedIn: "root" });
BitConfig.decorators = [
{ type: Injectable, args: [{ providedIn: 'root' },] }
];
class ListByPage {
constructor(curd, storage, option) {
this.curd = curd;
this.storage = storage;
this.option = option;
/**
* 完成初始化
* Complete initialization
*/
this.ready = new AsyncSubject();
/**
* 搜索字段定义
* Search field definition
*/
this.search = {};
/**
* 分页数据
* Paging data
*/
this.data = [];
/**
* 加载状态
* Loading status
*/
this.loading = true;
/**
* 分页限制
* Paging limit
*/
this.limit = 0;
/**
* 分页总数
* Total number of pages
*/
this.totals = 0;
/**
* 分页页码
* Pagination page number
*/
this.index = 1;
/**
* 是否全被选中
* Are all selected
*/
this.checked = false;
/**
* 是否不完全被选中
* Is it not completely selected
*/
this.indeterminate = false;
/**
* 是否可进行批量处理
* Whether it can be batch processed
*/
this.batch = false;
/**
* 被选中的数量
* Number selected
*/
this.checkedNumber = 0;
this.limit = option.limit;
this.order = option.order;
this.storage.get('search:' + option.id).subscribe((data) => {
if (!data) {
for (const value of option.query) {
this.search[value.field] = value;
}
}
else {
this.search = data;
}
this.ready.next(data);
this.ready.complete();
});
}
/**
* 设置数据
* Set data
*/
setData(data) {
this.data = data;
}
/**
* 判断是否包含该字段的搜索条件
* Determine whether to include the search criteria of the field
*/
hasSearch(field) {
return this.search.hasOwnProperty(field);
}
/**
* 主动触发搜索变动之后
* After actively triggering the search change
*/
afterSearch() {
return this.storage.set('search:' + this.option.id, this.search);
}
/**
* 主动触发搜索清空之后
* After actively triggering search and clearing
*/
clearSearch(reset = {}) {
for (const key in this.search) {
if (this.search.hasOwnProperty(key)) {
const search = this.search[key];
if (reset.hasOwnProperty(search.field)) {
search.value = reset[search.field];
}
else {
search.value = '';
}
}
}
return this.storage.delete('search:' + this.option.id);
}
/**
* 更新分页列表状态
* Update the status of the paging list
*/
refreshStatus() {
const allChecked = this.data.every((value) => value.checked === true);
const allUnchecked = this.data.every((value) => !value.checked);
this.checked = this.data.length !== 0 && allChecked;
this.indeterminate = !allChecked && !allUnchecked;
this.batch = this.checked || this.indeterminate;
this.checkedNumber = this.data.filter((value) => value.checked).length;
}
/**
* 更改所有分页列表选中状态
* Change the selected state of all tabbed lists
*/
checkedAll(event) {
this.data.forEach((data) => (data.checked = event));
this.refreshStatus();
}
/**
* 返回所有被选中的列表
* Return all selected lists
*/
getChecked() {
return this.data.filter(value => value.checked);
}
/**
* 获取当前的页码
* Get the current page number
*/
getPage() {
return this.storage.get('page:' + this.option.id);
}
/**
* 主动执行分页页码的持久化记录
* Actively execute persistent records of paging page numbers
*/
persistence() {
this.storage.set('page:' + this.option.id, this.index).subscribe(_ => _);
}
/**
* 返回查询定义数组
* Return query definition array
*/
toQuery() {
return Object.values(this.search);
}
/**
* 返回查询语句
* Return query statement
*/
toQuerySchema() {
return this.curd.getQuerySchema(this.toQuery());
}
}
class BitHttpService {
constructor(bitConfig, http) {
this.http = http;
this.baseUri = bitConfig.url.api + bitConfig.api.namespace + '/';
this.withCredentials = bitConfig.api.withCredentials;
}
/**
* 设置请求拦截器
* Http interceptor
*/
setupInterceptor(operate) {
this.interceptor = operate;
}
/**
* 发起请求客户端
* Http client
*/
req(url, body = {}, method = 'post') {
let httpClient = this.http.request(method, this.baseUri + url, {
body,
withCredentials: this.withCredentials
});
if (this.interceptor) {
httpClient = httpClient.pipe(this.interceptor);
}
return httpClient;
}
}
BitHttpService.ɵprov = i0.ɵɵdefineInjectable({ factory: function BitHttpService_Factory() { return new BitHttpService(i0.ɵɵinject(BitConfig), i0.ɵɵinject(i2.HttpClient)); }, token: BitHttpService, providedIn: "root" });
BitHttpService.decorators = [
{ type: Injectable, args: [{ providedIn: 'root' },] }
];
BitHttpService.ctorParameters = () => [
{ type: BitConfig },
{ type: HttpClient }
];
class BitCurdService {
constructor(bitConfig, http) {
this.http = http;
this.mode = bitConfig.query;
this.curd = bitConfig.curd;
}
/**
* 获取查询语句
* Get query statement
*/
getQuerySchema(options) {
switch (this.mode) {
case 'sql-orm':
return this.common(options);
}
}
/**
* mode: sql-orm
* php: Laravel ORM(Laravel,Lumen,Hyperf), ThinkPHP ORM
* - https://github.com/kainonly/think-bit
* - https://github.com/kainonly/hyperf-curd
* golang: https://github.com/kainonly/gin-curd
*/
common(options) {
const schema = [];
for (const search of options) {
if (search.value !== null &&
typeof search.value === 'object' &&
Object.keys(search.value).length === 0) {
continue;
}
if (typeof search.value === 'string') {
search.value = search.value.trim();
}
const exclude = search.exclude ? search.exclude : ['', 0, null];
if (!exclude.includes(search.value)) {
let value = search.value;
if (search.op === 'like') {
value = `%${value}%`;
}
if (search.format !== undefined && search.format === 'unixtime') {
value = Array.isArray(value) ?
value.map(v => Math.trunc(v.getTime() / 1000)) : Math.trunc(value.getTime() / 1000);
}
schema.push([search.field, search.op, value]);
}
}
return schema;
}
}
BitCurdService.ɵprov = i0.ɵɵdefineInjectable({ factory: function BitCurdService_Factory() { return new BitCurdService(i0.ɵɵinject(BitConfig), i0.ɵɵinject(BitHttpService)); }, token: BitCurdService, providedIn: "root" });
BitCurdService.decorators = [
{ type: Injectable, args: [{ providedIn: 'root' },] }
];
BitCurdService.ctorParameters = () => [
{ type: BitConfig },
{ type: BitHttpService }
];
class BitService {
constructor(bitConfig, curd, storage, router, location, nzI18nService) {
this.curd = curd;
this.storage = storage;
this.router = router;
this.location = location;
this.nzI18nService = nzI18nService;
/**
* 公共语言包
* Common language pack
*/
this.language = new Map();
/**
* 语言包 ID 状态
* Language ID changed
*/
this.localeChanged = new Subject();
/**
* 语言包引用
* Language pack reference
*/
this.l = {};
/**
* 国际化 ID 状态
* I18n ID changed
*/
this.i18nChanged = new Subject();
/**
* 国际化包含语言 ID
* I18n includes languages ID
*/
this.i18nContain = [];
/**
* 国际化输入提示状态
* I18n tooltip status
*/
this.i18nTooltip = {};
this.static = bitConfig.url.static;
this.uploads = bitConfig.url.api + bitConfig.api.upload;
this.localeDefault = bitConfig.locale.default;
this.localeMapping = bitConfig.locale.mapping;
this.localeBind = bitConfig.locale.bind;
this.i18nDefault = bitConfig.i18n.default;
this.i18n = bitConfig.i18n.default;
this.i18nContain = bitConfig.i18n.contain;
this.i18nSwitch = bitConfig.i18n.switch;
this.pageDefault = bitConfig.page;
}
/**
* 路由导航
* Route navigation
*/
open(path, extras) {
if (path.length === 0) {
return;
}
const url = this.router.url;
if (url !== '/') {
const primary = this.router.parseUrl(url).root.children[PRIMARY_OUTLET];
const segments = primary.segments;
if (segments.length > 1) {
const key = segments[0].path;
this.storage.set('history:' + key, segments.splice(1)).subscribe(_ => _);
}
}
const commands = [];
path.forEach(value => {
if (typeof value === 'string') {
commands.push(...value.split('/'));
}
else {
commands.push(value);
}
});
this.router.navigate(commands, extras);
}
/**
* 导航历史
* Navigation history
*/
history(key) {
this.storage.get('history:' + key).subscribe((segments) => {
const commands = [key];
if (segments && segments.length !== 0) {
commands.push(...segments.map(v => v.path));
this.storage.delete('history:' + key).subscribe(_ => _);
}
this.router.navigate(commands);
});
}
/**
* 导航返回
* Navigate back
*/
back() {
this.location.back();
this.resetI18n();
}
/**
* 初始化语言包
* Setup language pack
*/
setupLocale() {
this.l = {};
this.setLocale(localStorage.getItem('locale') || this.localeDefault);
}
/**
* 载入语言包
* Registered language pack
*/
registerLocales(packer) {
Promise.resolve(packer).then(result => {
if (!result.default) {
return;
}
this.language = new Map([...this.language, ...Object.entries(result.default)]);
const index = this.localeDefault.indexOf(this.locale);
for (const [key, data] of this.language.entries()) {
this.l[key] = data[index];
}
});
}
/**
* 设置语言包 ID
* Set language ID
*/
setLocale(locale) {
this.locale = locale;
localStorage.setItem('locale', locale);
const index = this.localeMapping.indexOf(this.locale);
for (const [key, data] of this.language.entries()) {
this.l[key] = data[index];
}
this.nzI18nService.setLocale(this.localeBind[index]);
this.localeChanged.next(locale);
}
/**
* 国际化 ID 是否相等
* Are the I18n IDs equal
*/
equalI18n(i18n) {
return this.i18n === i18n;
}
/**
* 重置国际化 ID
* Reset I18n ID
*/
resetI18n() {
this.i18n = this.i18nDefault;
}
/**
* 生成 I18n FormGroup
* Generate I18n FormGroup
*/
i18nGroup(options) {
const controls = {};
if (options) {
for (const ID of this.i18nContain) {
controls[ID] = [null, [], []];
if (options.value !== undefined && options.value.hasOwnProperty(ID)) {
controls[ID][0] = options.value[ID];
}
if (options.validate !== undefined && options.validate.hasOwnProperty(ID)) {
controls[ID][1] = options.validate[ID];
}
if (options.asyncValidate !== undefined && options.asyncValidate.hasOwnProperty(ID)) {
controls[ID][2] = options.asyncValidate[ID];
}
}
}
return controls;
}
/**
* 解析国际化数据
* Parse i18n string json
*/
i18nParse(text) {
const json = JSON.parse(text);
const data = {};
for (const ID of this.i18nContain) {
if (json.hasOwnProperty(ID)) {
data[ID] = json[ID];
}
}
return data;
}
/**
* 生产分页数据对象
* Factory list by page
*/
listByPage(option) {
option.limit = option.limit || this.pageDefault;
return new ListByPage(this.curd, this.storage, option);
}
/**
* 清除应用本地存储
* Clear app local storage
*/
clear() {
this.storage.keys().pipe(filter(v => ['resource', 'router'].includes(v) ||
v.search(/^search:\S+$/) !== -1 ||
v.search(/^page:\S+$/) !== -1 ||
v.search(/^cross:\S+$/) !== -1), switchMap(key => this.storage.delete(key))).subscribe(_ => _);
}
}
BitService.ɵprov = i0.ɵɵdefineInjectable({ factory: function BitService_Factory() { return new BitService(i0.ɵɵinject(BitConfig), i0.ɵɵinject(BitCurdService, 8), i0.ɵɵinject(i3.StorageMap, 8), i0.ɵɵinject(i4.Router, 8), i0.ɵɵinject(i5.Location, 8), i0.ɵɵinject(i6.NzI18nService, 8)); }, token: BitService, providedIn: "root" });
BitService.decorators = [
{ type: Injectable, args: [{ providedIn: 'root' },] }
];
BitService.ctorParameters = () => [
{ type: BitConfig },
{ type: BitCurdService, decorators: [{ type: Optional }] },
{ type: StorageMap, decorators: [{ type: Optional }] },
{ type: Router, decorators: [{ type: Optional }] },
{ type: Location, decorators: [{ type: Optional }] },
{ type: NzI18nService, decorators: [{ type: Optional }] }
];
class BitCurdCommonService extends BitCurdService {
/**
* 获取单条数据请求
* Get a single data request
*/
get(model, condition, order, path) {
let http;
const url = path || this.curd.get;
if (Array.isArray(condition)) {
http = this.http.req(model + url, {
where: this.getQuerySchema(condition),
order
});
}
else {
http = this.http.req(model + url, {
id: condition
});
}
return http.pipe(map(res => !res.error ? res.data : null));
}
/**
* 获取分页数据请求
* Get pagination data request
*/
lists(model, factory, option, path) {
const url = path || this.curd.lists;
if (option.refresh || option.persistence) {
if (option.refresh) {
factory.index = 1;
}
factory.persistence();
}
return factory.getPage().pipe(switchMap(index => {
factory.index = index ? index : 1;
return this.http.req(model + url, {
page: {
limit: factory.limit,
index: factory.index
},
where: factory.toQuerySchema(),
order: factory.order
});
}), map(res => {
factory.totals = !res.error ? res.data.total : 0;
factory.loading = false;
factory.checked = false;
factory.indeterminate = false;
factory.batch = false;
factory.checkedNumber = 0;
return !res.error ? res.data.lists : null;
}));
}
/**
* 获取原始列表数据请求
* Get original list data request
*/
originLists(model, condition = [], order, path) {
const url = path || this.curd.originLists;
return this.http.req(model + url, {
where: this.getQuerySchema(condition),
order
}).pipe(map(res => !res.error ? res.data : null));
}
/**
* 新增数据请求
* New data request
*/
add(model, data, path) {
const url = path || this.curd.add;
return this.http.req(model + url, data);
}
/**
* 修改数据请求
* Modify data request
*/
edit(model, data, condition, path) {
const url = path || this.curd.edit;
data.switch = false;
return !condition ?
this.http.req(model + url, data) :
this.http.req(model + url, Object.assign(data, {
where: this.getQuerySchema(condition)
}));
}
/**
* 状态切换请求
* State switch request
*/
status(model, data, field = 'status', extra, path) {
const url = path || this.curd.status;
const body = {
id: data.id,
switch: true,
[field]: !data[field]
};
if (extra !== undefined) {
Object.assign(body, extra);
}
return this.http.req(model + url, body).pipe(map((res) => {
if (!res.error) {
data[field] = !data[field];
}
return res;
}));
}
/**
* 删除数据请求
* Delete data request
*/
delete(model, id, condition, path) {
const url = path || this.curd.delete;
if (id !== undefined) {
return this.http.req(model + url, {
id
});
}
if (condition !== undefined) {
return this.http.req(model + url, {
where: this.getQuerySchema(condition)
});
}
return of(false);
}
}
BitCurdCommonService.ɵprov = i0.ɵɵdefineInjectable({ factory: function BitCurdCommonService_Factory() { return new BitCurdCommonService(i0.ɵɵinject(BitConfig), i0.ɵɵinject(BitHttpService)); }, token: BitCurdCommonService, providedIn: "root" });
BitCurdCommonService.decorators = [
{ type: Injectable, args: [{ providedIn: 'root' },] }
];
class BitModule {
constructor(config, nzIcon) {
var _a;
nzIcon.changeAssetsSource((_a = config === null || config === void 0 ? void 0 : config.url) === null || _a === void 0 ? void 0 : _a.icon);
}
static forRoot(config) {
return {
ngModule: BitModule,
providers: [
{
provide: BitConfig,
useValue: config
},
BitService,
BitHttpService,
NzIconService,
StorageMap
]
};
}
}
BitModule.decorators = [
{ type: NgModule }
];
BitModule.ctorParameters = () => [
{ type: BitConfig },
{ type: NzIconService }
];
/**
* Generated bundle index. Do not edit.
*/
export { BitConfig, BitCurdCommonService, BitCurdService, BitHttpService, BitModule, BitService, ListByPage };
//# sourceMappingURL=ngx-bit.js.map