UNPKG

@bos-alpha/data

Version:

数据管理

376 lines (375 loc) 20.2 kB
var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) { if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; }; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { useEffect, useRef, useState } from 'react'; import dayjs from 'dayjs'; import { Icon, Table, prefixCls, Modal } from '@bos-alpha/common'; import * as api from '@bos-alpha/common/lib/services'; import styled from '@emotion/styled'; import store from '../../store'; import { parseScheduleType, parseScheduleText } from '../../utils/schedule'; import { message, Progress } from 'antd'; var timer = null; export var TaskList = function () { // 表格数据 var _a = useState([]), tableData = _a[0], setTableData = _a[1]; var tableDataRef = useRef([]); var _b = useState(false), loading = _b[0], setLoading = _b[1]; var _c = useState(0), total = _c[0], setTotal = _c[1]; var _d = useState({ per_page: 10, page: 1 }), pagination = _d[0], setPagination = _d[1]; // 是否打开弹窗 var modalVisible = useRef(false); var _e = store(), visible = _e.visible, users = _e.users, setState = _e.setState; useEffect(function () { modalVisible.current = visible; if (visible) return; fetchData(); // 获取最新进度 loopFetchTaskStatus(); }, [visible, pagination]); // eslint-disable-line // 清除定时器 useEffect(function () { return function () { if (timer) window.clearInterval(timer); }; }, []); // eslint-disable-line var fetchData = function () { return __awaiter(void 0, void 0, void 0, function () { var appUsers, usersRes, res, list; return __generator(this, function (_a) { switch (_a.label) { case 0: appUsers = users; if (!(users.length === 0)) return [3 /*break*/, 2]; return [4 /*yield*/, api.getPersonneUsers({ data: {} })]; case 1: usersRes = _a.sent(); appUsers = usersRes.results; setState({ users: appUsers }); _a.label = 2; case 2: setLoading(true); return [4 /*yield*/, api.queryEntity('importTask', { params: __assign(__assign({}, pagination), { sortby: 'gcreatetime', order: 'desc', noRelation: true }), data: { condition: [] } })]; case 3: res = _a.sent(); list = res.data.map(function (item) { var creator = appUsers.find(function (uitem) { return "".concat(uitem.bosclass, "/").concat(uitem.id) === item.creator; }); var guser = appUsers.find(function (uitem) { return "".concat(uitem.bosclass, "/").concat(uitem.id) === item.guser; }); return __assign(__assign({}, item), { createTime: item.gcreatetime ? dayjs(Number(item.gcreatetime)).format('YYYY-MM-DD HH:mm:ss') : '', scheduleTypeText: parseScheduleType(item.scheduleType), scheduleValueText: parseScheduleText(item.scheduleType, item.scheduleValue), progress: parseInt(item.progress), creator: creator ? creator.fullName ? "".concat(creator.fullName, "\uFF08").concat(creator.name, "\uFF09") : creator.name : item.creator, guser: guser ? guser.fullName ? "".concat(guser.fullName, "\uFF08").concat(guser.name, "\uFF09") : guser.name : item.guser, gtime: item.gtime ? dayjs(Number(item.gtime)).format('YYYY-MM-DD HH:mm:ss') : '' }); }); setTotal(res.count); tableDataRef.current = list; setTableData(list); setLoading(false); return [2 /*return*/]; } }); }); }; // 轮询刷新进度 只获取状态 key匹配 var loopFetchTaskStatus = function () { if (timer) window.clearInterval(timer); timer = setInterval(function () { return __awaiter(void 0, void 0, void 0, function () { var res, statusList, newList; return __generator(this, function (_a) { switch (_a.label) { case 0: // 有弹窗遮罩时,不刷新任务进度 if (modalVisible.current) return [2 /*return*/]; return [4 /*yield*/, api.queryEntity('importTask', { params: __assign(__assign({}, pagination), { sortby: 'gcreatetime', order: 'desc', noRelation: true }), data: { condition: [], select: ['_key', 'status', 'progress'] } })]; case 1: res = _a.sent(); statusList = res.data.map(function (item) { return ({ key: item.key, status: item.status, progress: parseInt(item.progress) }); }); newList = tableDataRef.current.map(function (item) { var curTaskStatus = statusList.find(function (el) { return el.key === item.key; }); // 更新状态status和进度progress if (curTaskStatus) { return __assign(__assign({}, item), { status: curTaskStatus.status, progress: curTaskStatus.progress }); } return item; }); setTableData(newList); return [2 /*return*/]; } }); }); }, 5 * 1000); }; /** * 执行 注意区分API和数据库的编辑接口 * 任务状态码 status:string (1)-2:配置中(任务配置尚未完成) (2)0:队列中(将在计划时间执行) (3)0.5:立即执行 (4)1:正在导入(后台自动设置) (5)2:导入完成(后台自动设置) (6)-1:导入失败(后台自动设置) (7)1.5:部分成功(后台自动设置) * 执行成功立马改变状态为执行中 等5秒后查询结果变更任务进度 */ var onExecute = function (record) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: console.log('onExecute:', record); if (record.status === '-2' || record.status === '1') return [2 /*return*/, message.error('执行失败,配置未完成或正在执行中')]; if (!(record.type === 'DB')) return [3 /*break*/, 2]; return [4 /*yield*/, api.importDatabaseFile({ data: { taskId: record.key, name: record.name, enabled: true, status: '0.5' } })]; case 1: _a.sent(); return [3 /*break*/, 4]; case 2: return [4 /*yield*/, api.postDataImportTasks({ data: { taskId: record.key, name: record.name, enabled: true, status: '0.5' } })]; case 3: _a.sent(); _a.label = 4; case 4: // 开始执行 状态改为开始 setTableData(tableData.map(function (item) { if (item.key === record.key) { return __assign(__assign({}, item), { status: '1', progress: 0 }); } return item; })); return [2 /*return*/]; } }); }); }; // 编辑 var onEdit = function (record) { console.log('edit:', record); if (record.status === '0.5' || record.status === '1') return message.error('任务正在执行'); setState({ isEdit: true, // 任务状态 任务配置中-2,导入数据库时必须选配置文件 status: record.status, // 站点id siteId: record.extra, // 任务id taskId: record.key, visible: true, type: record.type === 'DB' ? 'db' : 'api', scheduleInfo: { name: record.name, description: record.description, scheduleType: record.scheduleType, scheduleValue: record.scheduleValue, creator: record.creator, createTime: record.createTime, guser: record.guser, gtime: record.gtime }, mappings: record.mappings || [], insert: record.insert, update: record.update, rollback: record.rollback }); }; // 删除任务 var onDelete = function (record) { if (record.status === '0.5' || record.status === '1') return message.error('任务正在执行'); Modal.confirm({ title: '删除任务', content: '删除后不可恢复,是否确认?', centered: true, onOk: function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, api.deleteEntity('importTask', record.key, { params: { delRelation: true } })]; case 1: _a.sent(); message.success('删除成功'); fetchData(); return [2 /*return*/]; } }); }); } }); }; var columns = [ { dataIndex: 'name', title: '配置名称', width: 180, ellipsis: true }, { dataIndex: 'type', title: '对接方式', width: 90, render: function (type) { return (type === 'DB' ? '数据库' : 'API'); } }, { dataIndex: 'creator', title: '创建者', width: 180, ellipsis: true }, { dataIndex: 'createTime', title: '创建时间', width: 160, ellipsis: true }, { dataIndex: 'guser', title: '最后修改人', width: 120, ellipsis: true }, { dataIndex: 'gtime', title: '最后修改时间', width: 120, ellipsis: true }, { dataIndex: 'scheduleTypeText', title: '触发条件', width: 90 }, { dataIndex: 'scheduleValueText', title: '触发参数', width: 300, ellipsis: true }, { dataIndex: 'key', title: '操作', fixed: 'right', width: 250, render: function (status, record) { // status '-2'(配置中),'0'(队列中),'1'(进行中),'-1'(失败),'2'(完成) return (_jsxs(Operation, { children: [record.status === '-2' ? (_jsx(Pending, { children: "\u914D\u7F6E\u672A\u5B8C\u6210" }, void 0)) : record.status === '0.5' || record.status === '1' ? (_jsx(Progress, { percent: record.progress, showInfo: false }, void 0)) : (_jsxs(LinkButton, __assign({ onClick: function () { return onExecute(record); } }, { children: [_jsx(Icon, { className: "icon", type: "iconicon_startuploading-01" }, void 0), _jsx("span", { children: "\u5F00\u59CB\u6267\u884C" }, void 0)] }), void 0)), _jsxs(LinkButton, __assign({ className: "line-btn ".concat(record.status === '0.5' || record.status === '1' ? 'disabled' : ''), onClick: function () { return onEdit(record); } }, { children: [_jsx(Icon, { className: "icon", type: "iconicon_edit" }, void 0), _jsx("span", { children: "\u7F16\u8F91" }, void 0)] }), void 0), _jsxs(LinkButton, __assign({ className: "line-btn ".concat(record.status === '0.5' || record.status === '1' ? 'disabled' : ''), onClick: function () { return onDelete(record); } }, { children: [_jsx(Icon, { className: "icon", type: "iconicon_delete" }, void 0), _jsx("span", { children: "\u5220\u9664" }, void 0)] }), void 0)] }, void 0)); } } ]; return (_jsx(CustomTable, { columns: columns, dataSource: tableData, scroll: { x: 1000, y: 'calc(100vh - 360px)' }, loading: loading, pagination: { current: pagination.page, pageSize: pagination.per_page, total: total, showSizeChanger: true, showQuickJumper: true, showTotal: function (total) { return _jsxs("span", { children: ["\u5171 ", total, " \u6761"] }, void 0); }, onChange: function (page, pageSize) { setPagination(__assign(__assign({}, pagination), { page: page, per_page: pageSize })); } } }, void 0)); }; var CustomTable = styled(Table)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n .", "-table-body {\n &::-webkit-scrollbar {\n -webkit-appearance: none;\n }\n /* \u6EDA\u52A8\u6761\u5E38\u663E */\n &::-webkit-scrollbar:vertical {\n width: 6px;\n }\n &::-webkit-scrollbar:horizontal {\n height: 6px;\n }\n &::-webkit-scrollbar-thumb {\n border-radius: 8px;\n border: 6px solid rgba(255, 255, 255, 0.4);\n background-color: rgba(0, 0, 0, 0.5);\n }\n }\n"], ["\n .", "-table-body {\n &::-webkit-scrollbar {\n -webkit-appearance: none;\n }\n /* \u6EDA\u52A8\u6761\u5E38\u663E */\n &::-webkit-scrollbar:vertical {\n width: 6px;\n }\n &::-webkit-scrollbar:horizontal {\n height: 6px;\n }\n &::-webkit-scrollbar-thumb {\n border-radius: 8px;\n border: 6px solid rgba(255, 255, 255, 0.4);\n background-color: rgba(0, 0, 0, 0.5);\n }\n }\n"])), prefixCls); var Operation = styled.div(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n display: flex;\n justify-content: space-between;\n & > .line-btn {\n width: 50px;\n }\n .", "-progress-line {\n margin-right: 20px;\n width: 80px;\n }\n"], ["\n display: flex;\n justify-content: space-between;\n & > .line-btn {\n width: 50px;\n }\n .", "-progress-line {\n margin-right: 20px;\n width: 80px;\n }\n"])), prefixCls); var Pending = styled.div(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n color: rgba(68, 68, 68, 0.6);\n"], ["\n color: rgba(68, 68, 68, 0.6);\n"]))); var LinkButton = styled.span(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n cursor: pointer;\n color: #2878ff;\n display: inline-flex;\n align-items: center;\n &.disabled {\n cursor: not-allowed;\n color: rgba(40, 120, 255, 0.6);\n }\n & > .icon {\n font-size: 16px;\n margin-right: 4px;\n }\n"], ["\n cursor: pointer;\n color: #2878ff;\n display: inline-flex;\n align-items: center;\n &.disabled {\n cursor: not-allowed;\n color: rgba(40, 120, 255, 0.6);\n }\n & > .icon {\n font-size: 16px;\n margin-right: 4px;\n }\n"]))); var templateObject_1, templateObject_2, templateObject_3, templateObject_4;