| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- class VectorizedPanel extends zui.Component
- {
- static NAME = 'VectorizedPanel';
- get actualStatus()
- {
- if(!this.isStoreOk) return 'unavailable';
- let status = this.options.status;
- if(status === 'syncing' && !this.syncing) status = 'paused';
- return status;
- }
- init()
- {
- this.commandScope = 'vectorizedpanel';
- this.isLoading = false;
- this.syncing = false;
- this.syncingTimer = 0;
- this.progressBarWidth = 700;
- this.waitTime = 0;
- this.syncCouter = 0;
- let store = null;
- if(window !== window.parent)
- {
- const zaiPanel = window.parent.zui.AIPanel.shared;
- store = zaiPanel ? zaiPanel.store : null;
- }
- else if(this.options.zaiSetting)
- {
- try {
- store = zui.ZentaoAIStore.createFromZentao(this.options.zaiSetting);
- } catch (error) {
- console.error('create zentao ai store failed', error);
- }
- }
- this.store = store;
- }
- async afterInit()
- {
- this.$panel = this.$element.closest('.vectorized-panel');
- this.toggleLoading();
- if (this.store) this.isStoreOk = await this.store.isOK();
- this.toggleLoading(false);
- zui.bindCommands(this.$panel, {
- scope: this.commandScope,
- onCommand: this.executeCommand.bind(this),
- });
- this.render();
- }
- updateProgresses(status)
- {
- status = status || this.actualStatus;
- const options = this.options;
- const syncDetails = options.syncDetails || {};
- const $progresses = this.$panel.find('.vectorized-progress');
- const maxCount = Math.max(100, Object.values(syncDetails).reduce((maxVal, info) => {
- maxVal = Math.max(maxVal, (info.failed || 0) + (info.synced || 0));
- return maxVal;
- }, 0));
- const maxWidth = this.progressBarWidth || 600;
- const syncing = !!this.syncing;
- $progresses.each(function()
- {
- const $progress = $(this);
- const type = $progress.data('type');
- const info = syncDetails[type] || {failed: 0, synced: 0};
- const isSyncing = type === options.syncingType && syncing;
- const synced = info.synced || 0;
- const failed = info.failed || 0;
- const total = synced + failed;
- $progress.toggleClass('is-syncing-type', isSyncing);
- $progress.find('.vectorized-failed-info').toggleClass('hidden', !info.failed);
- $progress.find('.vectorized-finished-count').text(synced);
- $progress.find('.vectorized-failed-count').text(failed);
- $progress.find('.vectorized-loading-icon').toggleClass('hidden', !isSyncing);
- $progress.find('.vectorized-sync-type').toggleClass('font-bold', !!syncDetails[type]).toggleClass('text-gray', !syncDetails[type]).toggleClass('text-primary', isSyncing);
- $progress.find('.vectorized-sync-progress').toggleClass('active progress-striped', isSyncing).css('width', Math.max(1, maxWidth * total / maxCount));
- $progress.find('.progress-bar.is-synced').css('width', total ? `${100 * synced / total}%` : '1px');
- $progress.find('.progress-bar.is-failed').css('width', total ? `${100 * failed / total}%` : '0');
- });
- }
- render(newOptions)
- {
- super.render(newOptions);
- const $panel = this.$panel;
- const options = this.options;
- const status = this.actualStatus;
- const lang = options.langData;
- const syncFailed = status === 'synced' && !this.options.syncedCount && !!this.options.syncFailedCount;
- Object.keys(lang.vectorizedStatusList).forEach(statusType =>
- {
- $panel.toggleClass(`is-status-${statusType}`, status === statusType).toggleClass(`not-status-${statusType}`, status !== statusType);
- });
- $panel.removeClass('loading');
- $panel.find('.vectorized-status').text(lang.vectorizedStatusList[syncFailed ? 'failed' : status]);
- $panel.toggleClass('is-syncing-loop', !!this.syncing);
- $panel.toggleClass('not-syncing-loop', !this.syncing);
- $panel.toggleClass('is-synced-failed', syncFailed).toggleClass('not-synced-failed', !syncFailed);
- $panel.find('.vectorized-finished-total-count').text(options.syncedCount);
- $panel.find('.vectorized-failed-total-count').text(options.syncFailedCount);
- $panel.find('.vectorized-last-sync-info').toggleClass('hidden', status !== 'paused' && status !== 'synced').find('.vectorized-last-sync-time').text(zui.formatDate(status === 'synced' ? (options.syncedTime || options.syncTime) : options.syncTime));
- $panel.find('.vectorized-synced-with-failed').toggleClass('hidden', options.syncFailedCount === 0 || status !== 'synced');
- this.updateProgresses();
- }
- executeCommand(context, params)
- {
- if(typeof context === 'string') context = {name: context};
- if (!context.scope || context.scope === this.commandScope)
- {
- return zui.deepCall(this, context.name, params);
- }
- }
- toggleLoading(loading)
- {
- loading = loading === undefined ? true : !!loading;
- this.isLoading = loading;
- this.$panel.toggleClass('loading', loading);
- }
- getLang(key)
- {
- return this.options.langData[key];
- }
- async request(url, options)
- {
- if(Array.isArray(url)) url = $.createLink.apply(null, url);
- const result = await $.ajaxSubmit($.extend({url: url}, options));
- const response = result[0];
- const error = result[1];
- if(!error && response && response.info) this.render(response.info);
- return response;
- }
- async post(url, data, options)
- {
- return this.request(url, $.extend({method: 'POST', data: data}, options));
- }
- async enable()
- {
- this.toggleLoading(true);
- const result = await this.post(['zai', 'ajaxEnableVectorization']);
- this.toggleLoading(false);
- if(result) return true;
- }
- async syncNext(data)
- {
- this.syncCouter++;
- const result = await this.post(['zai', 'ajaxSyncVectorization'], data);
- let waitTime = result.data.lastSync ? (result.data.lastSync.time * 3) : 100;
- if(this.syncCouter % 200 === 0) waitTime += 2000;
- if(this.syncCouter % 1000 === 0) waitTime += 2000;
- await zui.delay(waitTime);
- return result;
- }
- async sync(options)
- {
- this.syncing = true;
- this.render();
- const force = options && options.force;
- const result = await this.syncNext({force: !!force});
- if(!result || typeof result !== 'object')
- {
- zui.Messager.fail(this.getLang('syncRequestFailed'));
- this.syncing = false;
- this.render();
- return;
- }
- if(result.result !== 'success')
- {
- this.syncing = false;
- this.render(result.data);
- return;
- }
- if(result.data)
- {
- if(result.data.status === 'synced')
- {
- this.syncing = false;
- }
- else
- {
- this.syncingTimer = setTimeout(() => {
- this.syncingTimer = 0;
- if(this.syncing) this.sync();
- }, this.waitTime || 0);
- }
- this.render(result.data);
- }
- }
- async startSync()
- {
- if(this.syncing) return;
- this.sync();
- }
- resumeSync()
- {
- return this.startSync();
- }
- pauseSync()
- {
- if(this.syncingTimer)
- {
- clearTimeout(this.syncingTimer);
- this.syncingTimer = 0;
- }
- this.syncing = false;
- }
- resync()
- {
- if(this.syncing) return;
- return this.sync({force: true});
- }
- async resetSync()
- {
- const confirmed = await zui.Modal.confirm(this.getLang('confirmResetSync'));
- if(!confirmed) return;
- this.toggleLoading(true);
- const result = await this.post(['zai', 'ajaxEnableVectorization'], {force: true});
- this.toggleLoading(false);
- return result;
- }
- destroy()
- {
- super.destroy();
- zui.unbindCommands(this.$panel, this.commandScope);
- }
- };
- VectorizedPanel.register();
- window.updateVectorizedState = function($element)
- {
- const panel = $element.find('[z-use-vectorizedpanel]').zui();
- if(panel) panel.render();
- };
|