|
@@ -1,53 +1,3 @@
|
|
|
-/*---------------------------------------------参数配置---------------------------------------*/
|
|
|
-const CONSTANTS = {
|
|
|
- KEY_CHANNEL_NAMES: 'channel_names', //上游的名字,通道分组用
|
|
|
- KEY_MERCHANT_NAMES: 'merchant_names', //下游的名字,机构分组用
|
|
|
- KEY_CHANNEL_FAST: 'channel_fast', //上下游余额统计:统计的快充通道
|
|
|
- KEY_CHANNEL_NORMAL: 'channel_normal', //上下游余额统计:统计的普充通道
|
|
|
- KEY_MERCHANT: 'merchant', //上下游余额统计:统计的机构
|
|
|
- KEY_DAILY_CHANNEL: 'daily_channel', //日对账单:统计的通道
|
|
|
- KEY_DAILY_MERCHANT: 'daily_merchant', //日对账单:统计的机构
|
|
|
- KEY_MONTHLY_CHANNEL: 'monthly_channel', //月对账单:统计的通道
|
|
|
- KEY_MONTHLY_MERCHANT: 'monthly_merchant', //月对账单:统计的机构
|
|
|
- KEY_APPROVAL_TASK: 'approval_task', //审批列表
|
|
|
-};
|
|
|
-
|
|
|
-/*---------------------------------------------公共方法---------------------------------------*/
|
|
|
-function formatDecimals(number, digit= 2) {//格式化金额
|
|
|
- if (typeof number === 'string') {
|
|
|
- number = Number(number);
|
|
|
- }
|
|
|
- if (number === 0) {
|
|
|
- return '0';
|
|
|
- }
|
|
|
- return parseFloat(number).toFixed(digit);
|
|
|
-}
|
|
|
-
|
|
|
-function isValidKey(obj, key) {
|
|
|
- if (obj.hasOwnProperty(key)) {
|
|
|
- if (obj[key] !== null && obj[key] !== undefined && obj[key] !== '') {
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
- return false;
|
|
|
-}
|
|
|
-
|
|
|
-function deepCloneData(obj) {//数据深拷贝
|
|
|
- if (obj === null || typeof obj !== 'object') {
|
|
|
- return obj;
|
|
|
- }
|
|
|
-
|
|
|
- let clone = Array.isArray(obj) ? [] : {};
|
|
|
-
|
|
|
- for (let key in obj) {
|
|
|
- if (obj.hasOwnProperty(key)) {
|
|
|
- clone[key] = deepCloneData(obj[key]);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return clone;
|
|
|
-}
|
|
|
-
|
|
|
function sortSysData(sysData, sortData, key) {//sortData数据前置,sysData中未包含在sortData中的数据放在后面
|
|
|
let sortedData = deepCloneData(sortData);
|
|
|
const unselectedData = sysData.filter(function (sys) {
|
|
@@ -101,37 +51,6 @@ function sortCustData(sortCustSet, data, groupKey, nameKey) {
|
|
|
return sortedData;
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * 按指定字段进行排序,非字典序,将间隔开的元素排在一起
|
|
|
- * @param list
|
|
|
- * @param key
|
|
|
- * @returns {*[]}
|
|
|
- */
|
|
|
-function sortByName(list, key) {
|
|
|
- const dataMap = new Map();
|
|
|
-
|
|
|
- const result = [...list];
|
|
|
-
|
|
|
- for (let i = 0; i < result.length; i++) {
|
|
|
- const dataName = result[i][key];
|
|
|
- const sortKey = dataName.slice(0, 2);
|
|
|
-
|
|
|
- if (dataMap.has(sortKey)) {
|
|
|
- const firstIndex = dataMap.get(sortKey);
|
|
|
- if (i > firstIndex) {
|
|
|
- const [item] = result.splice(i, 1);
|
|
|
- result.splice(firstIndex + 1, 0, item);
|
|
|
- dataMap.set(sortKey, firstIndex + 1);
|
|
|
- i--;
|
|
|
- }
|
|
|
- } else {
|
|
|
- dataMap.set(sortKey, i);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return result;
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* 合并二维数据,表格数据合并/通道机构配置项合并
|
|
|
* 注意data1和data2的位置,data1为本平台的缓存,data2为导入的数据
|
|
@@ -173,153 +92,8 @@ function mergeNames(data1, data2) {
|
|
|
return data1.concat(notin);
|
|
|
}
|
|
|
|
|
|
-function handleInputd2(event) {//限制金额输入框
|
|
|
- let element = event.target;
|
|
|
- let value = element.textContent;
|
|
|
-
|
|
|
- let selection = window.getSelection();
|
|
|
- let range = selection.getRangeAt(0);
|
|
|
- let startOffset = range.startOffset;
|
|
|
-
|
|
|
- value = value.replace(/[^\d.-]/g, '');
|
|
|
-
|
|
|
- const parts = value.split('.');
|
|
|
- if (parts.length > 1) {
|
|
|
- parts[1] = parts[1].slice(0, 2);
|
|
|
- value = parts.join('.');
|
|
|
- }
|
|
|
-
|
|
|
- element.textContent = value;
|
|
|
-
|
|
|
- let newNode = element.childNodes[0] || element;
|
|
|
-
|
|
|
- range.setStart(newNode, Math.min(startOffset, value.length));
|
|
|
- range.setEnd(newNode, Math.min(startOffset, value.length));
|
|
|
- selection.removeAllRanges();
|
|
|
- selection.addRange(range);
|
|
|
-}
|
|
|
-
|
|
|
-function handleInputd4(event) {
|
|
|
- let element = event.target;
|
|
|
- let value = element.textContent;
|
|
|
-
|
|
|
- let selection = window.getSelection();
|
|
|
- let range = selection.getRangeAt(0);
|
|
|
- let startOffset = range.startOffset;
|
|
|
-
|
|
|
- value = value.replace(/[^\d.-]/g, '');
|
|
|
-
|
|
|
- const parts = value.split('.');
|
|
|
- if (parts.length > 1) {
|
|
|
- parts[1] = parts[1].slice(0, 4);
|
|
|
- value = parts.join('.');
|
|
|
- }
|
|
|
-
|
|
|
- element.textContent = value;
|
|
|
-
|
|
|
- let newNode = element.childNodes[0] || element;
|
|
|
-
|
|
|
- range.setStart(newNode, Math.min(startOffset, value.length));
|
|
|
- range.setEnd(newNode, Math.min(startOffset, value.length));
|
|
|
- selection.removeAllRanges();
|
|
|
- selection.addRange(range);
|
|
|
-}
|
|
|
-
|
|
|
-function normalizeAmount(amount) {
|
|
|
- return amount.replace(/^0+(\d+)/, '$1').replace(/^0+$/, '0');
|
|
|
-}
|
|
|
-
|
|
|
-function formatDateTime(dateString) {
|
|
|
- const date = new Date(dateString);
|
|
|
- const year = date.getFullYear();
|
|
|
- const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
|
- const day = String(date.getDate()).padStart(2, '0');
|
|
|
- const hours = String(date.getHours()).padStart(2, '0');
|
|
|
- const minutes = String(date.getMinutes()).padStart(2, '0');
|
|
|
- const seconds = String(date.getSeconds()).padStart(2, '0');
|
|
|
-
|
|
|
- return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
- * 过滤json数组,仅保留需要的字段
|
|
|
- */
|
|
|
-function filterJsonFields(jsonArray, fieldsToKeep) {
|
|
|
- return jsonArray.map(item => {
|
|
|
- return fieldsToKeep.reduce((filteredItem, field) => {
|
|
|
- if (field in item) {
|
|
|
- filteredItem[field] = item[field];
|
|
|
- }
|
|
|
- return filteredItem;
|
|
|
- }, {});
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-function isObjectEmpty(obj) {
|
|
|
- return Object.keys(obj).length === 0;
|
|
|
-}
|
|
|
-
|
|
|
-function showErr(error) {
|
|
|
- layer.alert(error, {
|
|
|
- icon: 2,
|
|
|
- title: '错误'
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-function showWarning(error, callback) {
|
|
|
- layer.alert(error, {
|
|
|
- icon: 0,
|
|
|
- title: '注意',
|
|
|
- yes: function(index) {
|
|
|
- if (typeof callback === 'function') {
|
|
|
- callback();
|
|
|
- }
|
|
|
- layer.close(index);
|
|
|
- }
|
|
|
- });
|
|
|
-}
|
|
|
-function showSuccess(msg) {
|
|
|
- layer.msg(msg, {
|
|
|
- icon: 1,
|
|
|
- time: 2000
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-function isNumeric(value) {
|
|
|
- return /^-?\d+(\.\d+)?$/.test(value);
|
|
|
-}
|
|
|
-
|
|
|
-/*----------------------------------------------统一请求定义---------------------------------------*/
|
|
|
-class ApiService {
|
|
|
- constructor(baseUrl) {
|
|
|
- this.baseUrl = baseUrl;
|
|
|
- }
|
|
|
-
|
|
|
- request(endpoint, method, data) {
|
|
|
- const that = this;
|
|
|
-
|
|
|
- return new Promise(function(resolve, reject) {
|
|
|
- $.ajax({
|
|
|
- url: that.baseUrl + endpoint,
|
|
|
- type: method,
|
|
|
- data: data,
|
|
|
- dataType: 'json',
|
|
|
- success: function(response) {
|
|
|
- try {
|
|
|
- const parsedResponse = JSON.parse(JSON.stringify(response));
|
|
|
- resolve(parsedResponse);
|
|
|
- } catch (e) {
|
|
|
- reject(new Error('请求失败 ' + response));
|
|
|
- }
|
|
|
- },
|
|
|
- error: function(jqXHR, textStatus, errorThrown) {
|
|
|
- reject(new Error('请求失败: ' + textStatus + ', ' + errorThrown));
|
|
|
- }
|
|
|
- });
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
+/*----------------------------------------------请求---------------------------------------*/
|
|
|
+class AmountApiService extends BaseService {
|
|
|
getStatsSettings(keys = []) {
|
|
|
const endpoint = '?act=refill_amount_stats&op=stats_settings&key=' + keys.join(',');
|
|
|
return this.request(endpoint, 'GET', {});
|
|
@@ -379,244 +153,7 @@ class ApiService {
|
|
|
return this.request(endpoint, 'POST', params);
|
|
|
};
|
|
|
}
|
|
|
-const statsApi = new ApiService('');
|
|
|
-
|
|
|
-/*------------------------------------------------------组件实现:调度类-------------------------------------------*/
|
|
|
-class ComponentBase {
|
|
|
- constructor(options) {
|
|
|
- this.el = document.querySelector(options.el);
|
|
|
- this.components = options.components || {};
|
|
|
- this.componentData = options.componentData || {};
|
|
|
- this.events = {};
|
|
|
- this.componentInstances = {};
|
|
|
- this.render();
|
|
|
- }
|
|
|
-
|
|
|
- render() {
|
|
|
- this.el.innerHTML = this.compile(this.el.innerHTML);
|
|
|
- }
|
|
|
-
|
|
|
- compile(template) {
|
|
|
- const componentNames = Object.keys(this.components);
|
|
|
- componentNames.forEach(name => {
|
|
|
- const regex = new RegExp(`<${name}([^>]*)>(.*?)<\/${name}>`, 'g');
|
|
|
- template = template.replace(regex, (match, attrs) => {
|
|
|
- const props = {};
|
|
|
-
|
|
|
- attrs.replace(/(\w+)="([^"]*)"/g, (match, key, value) => {
|
|
|
- if (CONSTANTS[value] !== undefined) {
|
|
|
- value = CONSTANTS[value];
|
|
|
- }
|
|
|
-
|
|
|
- props[key] = value;
|
|
|
- });
|
|
|
-
|
|
|
- const component = new this.components[name]({
|
|
|
- props: props,
|
|
|
- data: this.componentData[name] || {},
|
|
|
- parent: this
|
|
|
- });
|
|
|
-
|
|
|
- this.componentInstances[name] = component;
|
|
|
-
|
|
|
- return component.render();
|
|
|
- });
|
|
|
- });
|
|
|
-
|
|
|
- return template;
|
|
|
- }
|
|
|
-
|
|
|
- on(event, callback) {
|
|
|
- if (!this.events[event]) {
|
|
|
- this.events[event] = [];
|
|
|
- }
|
|
|
- this.events[event].push(callback);
|
|
|
- }
|
|
|
-
|
|
|
- emit(event, ...args) {
|
|
|
- if (this.events[event]) {
|
|
|
- this.events[event].forEach(callback => callback(...args));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- getComponent(name) {
|
|
|
- return this.componentInstances[name];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/*------------------------------------------------------组件实现:组件基类-------------------------------------------*/
|
|
|
-class Component {
|
|
|
- constructor(options) {
|
|
|
- this.data = options.data || {};
|
|
|
- this.props = options.props || {};
|
|
|
- this.template = options.template || '';
|
|
|
- this.id = 'component-' + Math.random().toString(36).substr(2, 9);
|
|
|
- this.props['comp-id'] = this.id;
|
|
|
- }
|
|
|
-
|
|
|
- render() {
|
|
|
- let template = this.template;
|
|
|
-
|
|
|
- for (const key in this.props) {
|
|
|
- template = template.replace(new RegExp(`{{${key}}}`, 'g'), this.props[key]);
|
|
|
- }
|
|
|
-
|
|
|
- setTimeout(() => {
|
|
|
- this.bindEvents();
|
|
|
- this.mounted();
|
|
|
- }, 0);
|
|
|
-
|
|
|
- return template;
|
|
|
- }
|
|
|
-
|
|
|
- bindEvents() {
|
|
|
- const rootElement = document.querySelector(`#${this.id}`);
|
|
|
-
|
|
|
- if (!rootElement) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- this.unbindEvents();
|
|
|
-
|
|
|
- const supportedEvents = ['click', 'input', 'blur', 'change'];
|
|
|
-
|
|
|
- supportedEvents.forEach(eventType => {
|
|
|
- const elements = rootElement.querySelectorAll(`[v-on\\:${eventType}]`);
|
|
|
-
|
|
|
- elements.forEach(element => {
|
|
|
- const method = element.getAttribute(`v-on:${eventType}`);
|
|
|
- if (method && typeof this[method] === 'function') {
|
|
|
- const listener = this[method].bind(this);
|
|
|
- element.addEventListener(eventType, listener);
|
|
|
-
|
|
|
- if (!this.eventListeners[eventType]) {
|
|
|
- this.eventListeners[eventType] = [];
|
|
|
- }
|
|
|
- this.eventListeners[eventType].push({ element, listener });
|
|
|
- }
|
|
|
- });
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- unbindEvents() {
|
|
|
- for (const eventType in this.eventListeners) {
|
|
|
- this.eventListeners[eventType].forEach(({ element, listener }) => {
|
|
|
- element.removeEventListener(eventType, listener);
|
|
|
- });
|
|
|
- }
|
|
|
- this.eventListeners = {};
|
|
|
- }
|
|
|
-
|
|
|
- mounted() {
|
|
|
-
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/*------------------------------------------------------layui表格基类-----------------------------------------------*/
|
|
|
-class LayuiTableBase {
|
|
|
- constructor(id) {
|
|
|
- this.tableId = id;
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * 表格中可编辑列的处理
|
|
|
- */
|
|
|
- editEvent(editColumns = [], callback) {
|
|
|
- const tableItem = $('#' + this.tableId);
|
|
|
-
|
|
|
- const trs = tableItem.next('.layui-table-view').find('.layui-table-body tbody tr');
|
|
|
-
|
|
|
- trs.each(function (i, tr) {
|
|
|
- for (let col of editColumns) {
|
|
|
- const td = $(tr).find('td[data-field="' + col + '"]').not('.layui-hide');
|
|
|
- if (td.length > 0) {//合并隐藏的不处理
|
|
|
- const valDiv = td.find('div');
|
|
|
- valDiv.attr('contenteditable', true).css('background-color', 'lightblue');
|
|
|
-
|
|
|
- valDiv.off('input', handleInputd4)
|
|
|
- .off('keypress')
|
|
|
- .off('blur')
|
|
|
- .on('input', handleInputd4)
|
|
|
- .on('keypress', function (e) {
|
|
|
- if (e.keyCode === 13) {
|
|
|
- e.preventDefault();
|
|
|
- $(this).blur();
|
|
|
- }
|
|
|
- })
|
|
|
- .on('blur', function () {
|
|
|
- const val = valDiv.text().trim();
|
|
|
- if (!isNumeric(val)) {
|
|
|
- valDiv.html('0');
|
|
|
- }
|
|
|
-
|
|
|
- if (callback !== null && typeof callback === 'function') {
|
|
|
- const index = $(this).parent().parent().data('index');
|
|
|
- callback(index);
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- switchEvent(switchColumns = [], callback) {
|
|
|
- const tableItem = $('#' + this.tableId);
|
|
|
- const trs = tableItem.next('.layui-table-view').find('.layui-table-body tbody tr');
|
|
|
-
|
|
|
- trs.each(function (i, tr) {
|
|
|
- for (let clo of switchColumns) {
|
|
|
- const td = $(tr).find('td[data-field="' + clo + '"]').not('.layui-hide');
|
|
|
- if (td.length > 0) {
|
|
|
- const buttons = td.find('.layui-btn');
|
|
|
-
|
|
|
- buttons.off('click').on('click', function (e) {
|
|
|
- e.preventDefault();
|
|
|
- e.stopPropagation();
|
|
|
-
|
|
|
- const currTr = $(this).closest('tr');
|
|
|
- const index = currTr.data('index');
|
|
|
-
|
|
|
- buttons.removeClass('selected').addClass('unselected');
|
|
|
- $(this).removeClass('unselected').addClass('selected');
|
|
|
-
|
|
|
- if (callback !== null && typeof callback === 'function') {
|
|
|
- callback(index);
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * 表格中金额字段样式,小于0的数值设置为红色
|
|
|
- */
|
|
|
- setValueClass(redColumns, boldColumns = []) {
|
|
|
- const trs = $('#' + this.tableId).next('.layui-table-view').find('.layui-table-body tbody tr');
|
|
|
- trs.each(function(i, tr) {
|
|
|
- for(let col of redColumns) {
|
|
|
- const td = $(tr).find('td[data-field="' + col + '"]').not('.layui-hide');
|
|
|
- if (td.length > 0) {//合并隐藏的不处理
|
|
|
- const valDiv = td.find('div');
|
|
|
- const val = valDiv.text().trim();
|
|
|
- if (parseFloat(val) < 0) {
|
|
|
- valDiv.addClass('negative-value');
|
|
|
- } else {
|
|
|
- valDiv.removeClass('negative-value');
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- for (let boldCol of boldColumns) {
|
|
|
- const boldTd = $(tr).find('td[data-field="' + boldCol + '"]').not('.layui-hide');
|
|
|
- if (boldTd.length > 0) {
|
|
|
- const boldDiv = boldTd.find('div');
|
|
|
- boldDiv.css('font-weight', 'bold');
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
-}
|
|
|
+const statsApi = new AmountApiService('');
|
|
|
|
|
|
/*------------------------------------------------------组件:上下游名称设置-------------------------------------------*/
|
|
|
class StreamNameComponent extends Component {
|
|
@@ -1172,7 +709,7 @@ class SelectedMerchantComponent extends Component {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/*-------------------------------------页面全局数据封装,防止出现重复定义-------------------------------*/
|
|
|
+/*-------------------------------------UI数据-------------------------------*/
|
|
|
class GlobalDataBase {
|
|
|
constructor() {
|
|
|
this.data = {};
|
|
@@ -1257,149 +794,3 @@ class GlobalDataBase {
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-class TaskManager {
|
|
|
- constructor() {
|
|
|
- this.globalTaskList = [];
|
|
|
- this.currentTaskList = [];
|
|
|
- }
|
|
|
-
|
|
|
- async initializeGlobalTaskList() {
|
|
|
- this.globalTaskList = await this._fetchTasksFromBackend();
|
|
|
- this._updateCurrentTaskList();
|
|
|
- }
|
|
|
-
|
|
|
- async _fetchTasksFromBackend() {
|
|
|
- const response = await statsApi.getStatsSettings([CONSTANTS.KEY_APPROVAL_TASK]);
|
|
|
- let data = [];
|
|
|
- if (response.state === true) {
|
|
|
- data = response[CONSTANTS.KEY_APPROVAL_TASK];
|
|
|
- }
|
|
|
- return data.map(task => this._normalizeTask(task));
|
|
|
- }
|
|
|
-
|
|
|
- async _syncTaskWithBackend(task) {
|
|
|
- const response = await statsApi.setStatsSettings(CONSTANTS.KEY_APPROVAL_TASK, task);
|
|
|
- return response.state === true;
|
|
|
- }
|
|
|
-
|
|
|
- async _syncTaskListWithBackend() {
|
|
|
- try {
|
|
|
- this.globalTaskList = await this._fetchTasksFromBackend();
|
|
|
- this._updateCurrentTaskList();
|
|
|
- } catch (error) {
|
|
|
- console.error("Failed to sync tasks with backend:", error);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- _mergeTasks(taskList, newTask) {
|
|
|
- const taskId = newTask.id;
|
|
|
- const taskIndex = taskList.findIndex(task => task.id === taskId);
|
|
|
-
|
|
|
- if (taskIndex !== -1) {
|
|
|
- taskList[taskIndex] = { ...taskList[taskIndex], ...newTask };
|
|
|
- } else {
|
|
|
- taskList.push(newTask);
|
|
|
- }
|
|
|
-
|
|
|
- return taskList;
|
|
|
- }
|
|
|
-
|
|
|
- _normalizeTask(task) {
|
|
|
- return {
|
|
|
- id: task.id || this._generateUniqueId(),
|
|
|
- type: task.type || this.getTaskType(),
|
|
|
- time: task.time || new Date().toISOString(),
|
|
|
- data: task.data || {},
|
|
|
- status: task.status || 'pending',
|
|
|
- initiator: task.initiator || '',
|
|
|
- approver: task.approver || ''
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
- _generateUniqueId() {
|
|
|
- return 'xxxx-xxxx-4xxx-yxxx-xxxxxx'.replace(/[xy]/g, function(c) {
|
|
|
- let r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
|
|
|
- return v.toString(16);
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- getTaskType() {
|
|
|
- throw new Error("Subclasses must implement getTaskType()");
|
|
|
- }
|
|
|
-
|
|
|
- _updateCurrentTaskList() {
|
|
|
- const field = this.getTaskType();
|
|
|
- this.currentTaskList = this.globalTaskList.filter(task => task.type === field);
|
|
|
- this._sortCurrentTaskListByTime();
|
|
|
- }
|
|
|
-
|
|
|
- _sortCurrentTaskListByTime() {
|
|
|
- this.currentTaskList.sort((a, b) => new Date(a.time) - new Date(b.time));
|
|
|
- }
|
|
|
-
|
|
|
- async addTask(data = {}, initiator = '', approver = '') {
|
|
|
- const newTask = this._normalizeTask({ data, initiator, approver });
|
|
|
- const taskTmp = deepCloneData(this.globalTaskList);
|
|
|
- const updateTask = this._mergeTasks(taskTmp, newTask);
|
|
|
- if (await this._syncTaskWithBackend(updateTask)) {
|
|
|
- this.globalTaskList.push(newTask);
|
|
|
- this._updateCurrentTaskList();
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- getPendingTasks() {
|
|
|
- return this.currentTaskList;
|
|
|
- }
|
|
|
-
|
|
|
- async executeTask(taskId, approvalHandler) {
|
|
|
- await this._syncTaskListWithBackend();
|
|
|
-
|
|
|
- const taskIndex = this.currentTaskList.findIndex(task => task.id === taskId);
|
|
|
- if (taskIndex === -1) {
|
|
|
- console.warn("Task already processed or not found.");
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- const task = this.currentTaskList[taskIndex];
|
|
|
-
|
|
|
- await approvalHandler(task);
|
|
|
-
|
|
|
- this.currentTaskList.splice(taskIndex, 1);
|
|
|
-
|
|
|
- const globalIndex = this.globalTaskList.findIndex(t => t.id === taskId);
|
|
|
- if (globalIndex !== -1) {
|
|
|
- this.globalTaskList.splice(globalIndex, 1);
|
|
|
- }
|
|
|
-
|
|
|
- await this._syncTaskWithBackend(this.globalTaskList);
|
|
|
-
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- async updateTask(taskId, updatedData) {
|
|
|
- const taskIndex = this.globalTaskList.findIndex(task => task.id === taskId);
|
|
|
- if (taskIndex === -1) {
|
|
|
- console.warn(`Task with ID ${taskId} not found.`);
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- if (Object.keys(updatedData).length === 0) {
|
|
|
- this.globalTaskList.splice(taskIndex, 1);
|
|
|
- } else {
|
|
|
- this.globalTaskList[taskIndex].data = updatedData;
|
|
|
- }
|
|
|
-
|
|
|
- const updateSuccess = await this._syncTaskWithBackend(this.globalTaskList);
|
|
|
- if (updateSuccess) {
|
|
|
- this._updateCurrentTaskList();
|
|
|
- return true;
|
|
|
- } else {
|
|
|
- console.error(`Failed to update task ${taskId} in the backend.`);
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|