UNPKG

ohayolibs

Version:

Ohayo is a set of essential modules for ohayojp.

217 lines (198 loc) 6.31 kB
import { Injectable, OnDestroy } from '@angular/core'; import { OhayoConfigService, OhayoLodopConfig, LazyService } from '@ohayo/util'; import { NzSafeAny } from 'ng-zorro-antd/core/types'; import { Observable, of, Subject } from 'rxjs'; import { Lodop, LodopPrintResult, LodopResult } from './lodop.types'; @Injectable({ providedIn: 'root' }) export class LodopService implements OnDestroy { private defaultConfig: OhayoLodopConfig; private _cog: OhayoLodopConfig; private pending = false; private _lodop: Lodop | null = null; private _init = new Subject<LodopResult>(); private _events = new Subject<LodopPrintResult>(); private printBuffer: any[] = []; constructor(private scriptSrv: LazyService, configSrv: OhayoConfigService) { this.defaultConfig = configSrv.merge('lodop', { url: '//localhost:8443/CLodopfuncs.js', name: 'CLODOP', companyName: '', checkMaxCount: 100, })!; this.cog = this.defaultConfig; } /** * 获取或重新设置配置 * * **注:**重新设置会倒置重新加载脚本资源 */ get cog(): OhayoLodopConfig { return this._cog; } set cog(value: OhayoLodopConfig) { this._cog = { ...this.defaultConfig, ...value, }; } /** 事件变更通知 */ get events(): Observable<LodopPrintResult> { return this._events.asObservable(); } /** 获取 lodop 对象 */ get lodop(): Observable<LodopResult> { if (this._lodop) return of({ ok: true, lodop: this._lodop } as LodopResult); if (this.pending) return this._init.asObservable(); this.request(); return this._init.asObservable(); } /** 获取打印机列表 */ get printer(): string[] { this.check(); const ret: string[] = []; const count = this._lodop!.GET_PRINTER_COUNT(); for (let index = 0; index < count; index++) { ret.push(this._lodop!.GET_PRINTER_NAME(index)); } return ret; } private check(): void { if (!this._lodop) throw new Error(`请务必先调用 lodop 获取对象`); } private request(): void { this.pending = true; const url = `${this.cog.url}?name=${this.cog.name}`; let checkMaxCount = this.cog.checkMaxCount as number; const onResolve = (status: NzSafeAny, error?: {}) => { this._init.next({ ok: status === 'ok', status, error, lodop: this._lodop!, }); }; const checkStatus = () => { --checkMaxCount; if (this._lodop!.webskt && this._lodop!.webskt.readyState === 1) { onResolve('ok'); } else { if (checkMaxCount < 0) { onResolve('check-limit'); return; } setTimeout(() => checkStatus(), 100); } }; this.scriptSrv.loadScript(url).then((res: NzSafeAny) => { if (res.status !== 'ok') { this.pending = false; onResolve('script-load-error', res[0]); return; } const win = window as NzSafeAny; if (win.hasOwnProperty(this.cog.name!)) { this._lodop = win[this.cog.name!] as Lodop; } if (this._lodop === null) { onResolve('load-variable-name-error', { name: this.cog.name }); return; } this._lodop.SET_LICENSES(this.cog.companyName!, this.cog.license!, this.cog.licenseA, this.cog.licenseB); checkStatus(); }); } /** 重置 lodop 对象 */ reset(): void { this._lodop = null; this.pending = false; this.request(); } /** * 附加代码至 `lodop` 对象上,字符串类支持 `{{key}}` 的动态参数 * * **注:** 代码是指打印设计所产生字符串数据 * * @param code 代码 * @param contextObj 动态参数上下文对象 * @param parser 自定义解析表达式,默认:`/LODOP\.([^(]+)\(([^\n]+)?\);/i` */ attachCode(code: string, contextObj?: NzSafeAny, parser?: RegExp): void { this.check(); if (!parser) parser = /LODOP\.([^(]+)\(([^\n]+)?\);/i; code.split('\n').forEach(line => { const res = parser!.exec(line.trim()); if (!res) return; const fn = this._lodop![res[1]]; if (fn) { let arr: any[] | null = null; try { // tslint:disable-next-line: function-constructor const fakeFn = new Function(`return [${res[2]}]`); arr = fakeFn(); } catch { } if (arr != null && Array.isArray(arr) && contextObj) { for (let i = 0; i < arr.length; i++) { if (typeof arr[i] === 'string') { arr[i] = (arr[i] as string).replace(/{{(.*?)}}/g, (_match, key) => contextObj[key.trim()] || ''); } } } fn.apply(this._lodop, arr!); } }); } /** * 打开打印设计关闭后自动返回代码 * * **注:** 自动监听 `On_Return` 事件,运行后会移除 */ design(): Promise<string> { this.check(); const tid = this._lodop!.PRINT_DESIGN(); return new Promise(resolve => { this._lodop!.On_Return = (taskID: string, value: boolean | string) => { if (tid !== taskID) return; this._lodop!.On_Return = null; resolve('' + value); }; }); } private printDo(): void { const data = this.printBuffer.shift(); if (!data) return; this.attachCode(data.code, data.item, data.parser); const tid = this._lodop!.PRINT(); this._lodop!.On_Return = (taskID: string, value: boolean | string) => { if (tid !== taskID) return; this._lodop!.On_Return = null; this._events.next({ ok: value === true, error: value === true ? null : value, ...data, }); this.printDo(); }; } /** * 立即打印,一般用于批量套打 * * @param code 代码 * @param contextObj 动态参数上下文对象 * @param parser 自定义解析表达式,默认:`/LODOP\.([^(]+)\(([^\n]+)?\);/i` */ print(code: string, contextObj: {} | Array<{}>, parser?: RegExp): void { this.check(); if (contextObj) { this.printBuffer.push( ...(Array.isArray(contextObj) ? contextObj : [contextObj]).map(item => { return { code, parser, item }; }), ); } this.printDo(); } ngOnDestroy(): void { this._init.unsubscribe(); this._events.unsubscribe(); } }