bee-front-components 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/config.ts +28 -0
- package/lib/assets/images/empty.png +0 -0
- package/lib/components/BaseModal/index.d.ts +41 -0
- package/lib/components/BaseModal/index.js +133 -0
- package/lib/components/BaseModal/index.module.less +66 -0
- package/lib/components/Buttons/Button.d.ts +17 -0
- package/lib/components/Buttons/Button.js +34 -0
- package/lib/components/Buttons/ButtonPermission.d.ts +18 -0
- package/lib/components/Buttons/ButtonPermission.js +34 -0
- package/lib/components/Buttons/index.d.ts +3 -0
- package/lib/components/Buttons/index.js +3 -0
- package/lib/components/Buttons/index.module.less +21 -0
- package/lib/components/ContentHeader/index.d.ts +17 -0
- package/lib/components/ContentHeader/index.js +22 -0
- package/lib/components/ContentHeader/index.module.less +14 -0
- package/lib/components/Empty/index.d.ts +17 -0
- package/lib/components/Empty/index.js +23 -0
- package/lib/components/Empty/index.module.less +15 -0
- package/lib/components/ExcelExport/index.d.ts +28 -0
- package/lib/components/ExcelExport/index.js +60 -0
- package/lib/components/ExcelExport/index.module.less +61 -0
- package/lib/components/Modal/index.d.ts +26 -0
- package/lib/components/Modal/index.js +191 -0
- package/lib/components/Modal/index.module.less +79 -0
- package/lib/components/PageHeader/index.d.ts +43 -0
- package/lib/components/PageHeader/index.js +72 -0
- package/lib/components/PageHeader/index.module.less +38 -0
- package/lib/components/PdfViewer/index.d.ts +49 -0
- package/lib/components/PdfViewer/index.js +699 -0
- package/lib/components/QueryBar/TableQueryBar.d.ts +32 -0
- package/lib/components/QueryBar/TableQueryBar.js +115 -0
- package/lib/components/QueryBar/index.d.ts +25 -0
- package/lib/components/QueryBar/index.js +102 -0
- package/lib/components/QueryBar/index.module.less +58 -0
- package/lib/components/RemainDay/index.d.ts +22 -0
- package/lib/components/RemainDay/index.js +47 -0
- package/lib/components/RemainDay/index.module.less +42 -0
- package/lib/components/Scanner/hooks/useKeyboardScanner.d.ts +14 -0
- package/lib/components/Scanner/hooks/useKeyboardScanner.js +95 -0
- package/lib/components/Scanner/index.d.ts +60 -0
- package/lib/components/Scanner/index.js +318 -0
- package/lib/components/Scanner/index.module.less +264 -0
- package/lib/components/Scanner/utils/device.d.ts +2 -0
- package/lib/components/Scanner/utils/device.js +18 -0
- package/lib/components/StatusTab/index.d.ts +36 -0
- package/lib/components/StatusTab/index.js +118 -0
- package/lib/components/StatusTab/index.module.less +20 -0
- package/lib/components/StatusTag/index.d.ts +32 -0
- package/lib/components/StatusTag/index.js +142 -0
- package/lib/components/StatusTag/index.module.less +37 -0
- package/lib/components/StepProgress/index.d.ts +36 -0
- package/lib/components/StepProgress/index.js +84 -0
- package/lib/components/StepProgress/index.module.less +180 -0
- package/lib/components/Table/index.d.ts +44 -0
- package/lib/components/Table/index.js +135 -0
- package/lib/components/Table/index.module.less +24 -0
- package/lib/components/TableOperationColumn/index.d.ts +45 -0
- package/lib/components/TableOperationColumn/index.js +205 -0
- package/lib/components/TableOperationColumn/index.module.less +22 -0
- package/lib/components/Tabs/TabGroup.d.ts +9 -0
- package/lib/components/Tabs/TabGroup.js +12 -0
- package/lib/components/Tabs/TabPane.d.ts +9 -0
- package/lib/components/Tabs/TabPane.js +12 -0
- package/lib/components/Tabs/Tabs.d.ts +23 -0
- package/lib/components/Tabs/Tabs.js +42 -0
- package/lib/components/Tabs/index.d.ts +4 -0
- package/lib/components/Tabs/index.js +4 -0
- package/lib/components/Tabs/index.module.less +20 -0
- package/lib/components/Upload/BatchUpload/index.d.ts +42 -0
- package/lib/components/Upload/BatchUpload/index.js +140 -0
- package/lib/components/Upload/BatchUpload/index.module.less +10 -0
- package/lib/components/Upload/DraggerUpload/index.d.ts +42 -0
- package/lib/components/Upload/DraggerUpload/index.js +142 -0
- package/lib/components/Upload/DraggerUpload/index.module.less +30 -0
- package/lib/components/Upload/FileUpload.d.ts +36 -0
- package/lib/components/Upload/FileUpload.js +122 -0
- package/lib/components/Upload/index.d.ts +4 -0
- package/lib/components/Upload/index.js +4 -0
- package/lib/components/VipFlag/index.d.ts +10 -0
- package/lib/components/VipFlag/index.js +23 -0
- package/lib/components/VipFlag/index.module.less +20 -0
- package/lib/typings/blank.d.ts +0 -0
- package/lib/typings.d.ts +3 -0
- package/lib/utils/const.d.ts +21 -0
- package/lib/utils/const.js +22 -0
- package/lib/utils/index.d.ts +95 -0
- package/lib/utils/index.js +319 -0
- package/lib/utils/menuTab.d.ts +60 -0
- package/lib/utils/menuTab.js +122 -0
- package/lib/utils/utils.d.ts +61 -0
- package/lib/utils/utils.js +270 -0
- package/package.json +41 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import _Stores from "choerodon-ui/pro/lib/stores";
|
|
2
|
+
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
3
|
+
/**
|
|
4
|
+
* @name 状态标签页组件
|
|
5
|
+
* @param {IStatusTabProps} props 组件属性
|
|
6
|
+
* @param {string} lookupCode 状态枚举值
|
|
7
|
+
* @param {string} currentStatus 当前状态
|
|
8
|
+
* @param {function} onChange 状态切换回调
|
|
9
|
+
* @author chuzhengyang
|
|
10
|
+
*/
|
|
11
|
+
import React, { useEffect, useState } from "react";
|
|
12
|
+
import request from "utils/request";
|
|
13
|
+
import { getCurrentOrganizationId } from "utils/utils";
|
|
14
|
+
import classNames from "classnames";
|
|
15
|
+
import { Tabs, TabPane } from "../Tabs";
|
|
16
|
+
import styles from "./index.module.less?modules";
|
|
17
|
+
export const organizationId = getCurrentOrganizationId();
|
|
18
|
+
|
|
19
|
+
// 状态配置项信息
|
|
20
|
+
|
|
21
|
+
const StatusTab = props => {
|
|
22
|
+
const lookupCode = props.lookupCode,
|
|
23
|
+
propsStatusList = props.statusList,
|
|
24
|
+
_props$currentStatus = props.currentStatus,
|
|
25
|
+
currentStatus = _props$currentStatus === void 0 ? "all" : _props$currentStatus,
|
|
26
|
+
_props$queryCountUrl = props.queryCountUrl,
|
|
27
|
+
queryCountUrl = _props$queryCountUrl === void 0 ? "" : _props$queryCountUrl,
|
|
28
|
+
onChange = props.onChange;
|
|
29
|
+
const _useState = useState([]),
|
|
30
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
31
|
+
statusList = _useState2[0],
|
|
32
|
+
setStatusList = _useState2[1];
|
|
33
|
+
const _useState3 = useState(0),
|
|
34
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
35
|
+
totalCount = _useState4[0],
|
|
36
|
+
setTotalCount = _useState4[1];
|
|
37
|
+
|
|
38
|
+
/** 从缓存或接口获取快码枚举列表 */
|
|
39
|
+
async function getLookupData(lookupCode) {
|
|
40
|
+
var _Stores$LookupCodeSto, _Stores$LookupCodeSto2, _Stores$LookupCodeSto3;
|
|
41
|
+
const list = ((_Stores$LookupCodeSto = _Stores.LookupCodeStore) === null || _Stores$LookupCodeSto === void 0 ? void 0 : (_Stores$LookupCodeSto2 = _Stores$LookupCodeSto.merger) === null || _Stores$LookupCodeSto2 === void 0 ? void 0 : (_Stores$LookupCodeSto3 = _Stores$LookupCodeSto2.cache) === null || _Stores$LookupCodeSto3 === void 0 ? void 0 : _Stores$LookupCodeSto3.get(lookupCode)) || [];
|
|
42
|
+
if ((list === null || list === void 0 ? void 0 : list.length) > 0) return list;
|
|
43
|
+
return _Stores.LookupCodeStore.fetchLookupData({
|
|
44
|
+
url: `/hpfm/v1/${organizationId}/lovs/data?lovCode=${lookupCode}`,
|
|
45
|
+
method: "GET"
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** 获取各状态数量 */
|
|
50
|
+
async function getCountData(url) {
|
|
51
|
+
return request(url, {
|
|
52
|
+
method: "GET"
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* 获取当前状态列表及数量
|
|
58
|
+
* - 优先使用 propsStatusList(外部传入)
|
|
59
|
+
* - 否则通过 lookupCode 获取枚举
|
|
60
|
+
* - 如有 queryCountUrl 则合并各状态数量
|
|
61
|
+
*/
|
|
62
|
+
async function fetchStatusList() {
|
|
63
|
+
if (propsStatusList) return {
|
|
64
|
+
list: propsStatusList
|
|
65
|
+
};
|
|
66
|
+
if (!lookupCode) return {
|
|
67
|
+
list: []
|
|
68
|
+
};
|
|
69
|
+
const list = await getLookupData(lookupCode);
|
|
70
|
+
if (!queryCountUrl || !(list !== null && list !== void 0 && list.length)) return {
|
|
71
|
+
list: list || []
|
|
72
|
+
};
|
|
73
|
+
const res = await getCountData(queryCountUrl);
|
|
74
|
+
const countMap = new Map(((res === null || res === void 0 ? void 0 : res.list) || []).map(i => [i.statusCode, i.count]));
|
|
75
|
+
return {
|
|
76
|
+
list: list.map(item => ({
|
|
77
|
+
...item,
|
|
78
|
+
count: countMap.get(item.value) || 0
|
|
79
|
+
})),
|
|
80
|
+
total: (res === null || res === void 0 ? void 0 : res.total) || 0
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
let cancelled = false;
|
|
85
|
+
fetchStatusList().then(({
|
|
86
|
+
list,
|
|
87
|
+
total
|
|
88
|
+
}) => {
|
|
89
|
+
if (cancelled) return;
|
|
90
|
+
setStatusList(list);
|
|
91
|
+
if (total !== undefined) setTotalCount(total);
|
|
92
|
+
});
|
|
93
|
+
return () => {
|
|
94
|
+
cancelled = true;
|
|
95
|
+
};
|
|
96
|
+
}, [lookupCode, queryCountUrl, propsStatusList]);
|
|
97
|
+
|
|
98
|
+
/** 渲染标签页标题:文本 + 可选数量(超过 99 显示 99+) */
|
|
99
|
+
function renderTab(label, count) {
|
|
100
|
+
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("span", null, label), queryCountUrl && /*#__PURE__*/React.createElement("span", {
|
|
101
|
+
className: classNames(styles.count, {
|
|
102
|
+
[styles.countSmall]: count != null && count < 10
|
|
103
|
+
})
|
|
104
|
+
}, count != null && count > 99 ? "99+" : count));
|
|
105
|
+
}
|
|
106
|
+
return /*#__PURE__*/React.createElement(Tabs, {
|
|
107
|
+
className: styles.tabsContainer,
|
|
108
|
+
defaultActiveKey: currentStatus,
|
|
109
|
+
onChange: onChange
|
|
110
|
+
}, /*#__PURE__*/React.createElement(TabPane, {
|
|
111
|
+
tab: renderTab("全部", totalCount),
|
|
112
|
+
key: "all"
|
|
113
|
+
}), statusList.map(item => /*#__PURE__*/React.createElement(TabPane, {
|
|
114
|
+
tab: renderTab(item.meaning, item.count),
|
|
115
|
+
key: item.value
|
|
116
|
+
})));
|
|
117
|
+
};
|
|
118
|
+
export default StatusTab;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
.tabsContainer {
|
|
2
|
+
height: auto !important;
|
|
3
|
+
}
|
|
4
|
+
.count {
|
|
5
|
+
margin-left: 0.06rem;
|
|
6
|
+
display: inline-block;
|
|
7
|
+
width: 0.32rem;
|
|
8
|
+
height: 0.16rem;
|
|
9
|
+
background: @primaryLightColor;
|
|
10
|
+
border-radius: 0.09rem;
|
|
11
|
+
font-weight: 400;
|
|
12
|
+
font-size: 0.12rem;
|
|
13
|
+
color: @primaryColor;
|
|
14
|
+
line-height: 0.16rem;
|
|
15
|
+
text-align: center;
|
|
16
|
+
&.countSmall {
|
|
17
|
+
width: 0.16rem;
|
|
18
|
+
border-radius: 50%;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
/** 快码枚举值 */
|
|
3
|
+
interface IStatusItem {
|
|
4
|
+
/** 排序标识 */
|
|
5
|
+
orderSeq: number;
|
|
6
|
+
/** 枚举中文表述 */
|
|
7
|
+
meaning: string;
|
|
8
|
+
/** 枚举值 */
|
|
9
|
+
value: string;
|
|
10
|
+
/** 可用标识 */
|
|
11
|
+
enabledFlag: number;
|
|
12
|
+
}
|
|
13
|
+
/** 状态分类类别 */
|
|
14
|
+
type IStatusCategory = "initial" | "success" | "error" | "default" | "primary";
|
|
15
|
+
interface IProps {
|
|
16
|
+
/** 枚举代码,用于请求状态列表 */
|
|
17
|
+
lovCode?: string;
|
|
18
|
+
/** 当前状态value */
|
|
19
|
+
value: string;
|
|
20
|
+
/** 当前状态文本 */
|
|
21
|
+
text?: string;
|
|
22
|
+
/** 展示类型 */
|
|
23
|
+
showType?: "default" | "circle";
|
|
24
|
+
/** 自定义显示内容 */
|
|
25
|
+
children?: React.ReactNode;
|
|
26
|
+
/** 自定义类名 */
|
|
27
|
+
className?: string;
|
|
28
|
+
/** 自定义分类函数 */
|
|
29
|
+
categorize?: (status: IStatusItem) => IStatusCategory;
|
|
30
|
+
}
|
|
31
|
+
declare const StatusTag: React.FC<IProps>;
|
|
32
|
+
export default StatusTag;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import _Stores from "choerodon-ui/pro/lib/stores";
|
|
2
|
+
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
3
|
+
/**
|
|
4
|
+
* @name 状态颜色标签
|
|
5
|
+
* @description 根据lovCode调用后台接口获取状态枚举,自动匹配当前value展示带分类小圆点标签,支持自定义children覆盖展示内容
|
|
6
|
+
* @param { string } lovCode 枚举代码,用于从后台拉取状态列表
|
|
7
|
+
* @param { string } value 当前状态的value值
|
|
8
|
+
* @param { function } categorize 自定义分类函数
|
|
9
|
+
* @param { ReactNode } children 自定义显示内容
|
|
10
|
+
* @author lichen
|
|
11
|
+
*/
|
|
12
|
+
import classNames from "classnames";
|
|
13
|
+
import React, { useEffect, useMemo, useState } from "react";
|
|
14
|
+
import { getCurrentOrganizationId } from "utils/utils";
|
|
15
|
+
import styles from "./index.module.less?modules";
|
|
16
|
+
|
|
17
|
+
/** 快码枚举值 */
|
|
18
|
+
|
|
19
|
+
/** 状态分类类别 */
|
|
20
|
+
|
|
21
|
+
// 根据中文字段模糊匹配 进行默认分类
|
|
22
|
+
function defaultCategorize(status) {
|
|
23
|
+
const statusMeaning = status.meaning.toLowerCase();
|
|
24
|
+
if (/待审核|待发布|中/.test(statusMeaning)) return "primary";
|
|
25
|
+
if (/拒|撤|废|败|销|退|取消|停|禁|弃|驳回/.test(statusMeaning)) return "error";
|
|
26
|
+
if (/草稿|待|新|建/.test(statusMeaning)) return "initial";
|
|
27
|
+
if (/通|过|完|成|已|启|用/.test(statusMeaning)) return "success";
|
|
28
|
+
return "default";
|
|
29
|
+
}
|
|
30
|
+
const DEFAULT_COLOR = {
|
|
31
|
+
default: "",
|
|
32
|
+
light: ""
|
|
33
|
+
};
|
|
34
|
+
// 生成不同状态类别相对应的色值映射
|
|
35
|
+
function getStatusColorMap(statusList, categorize) {
|
|
36
|
+
// 固定颜色映射
|
|
37
|
+
const categoryColors = {
|
|
38
|
+
initial: {
|
|
39
|
+
default: styles.warningColor,
|
|
40
|
+
light: styles.warningLightColor
|
|
41
|
+
},
|
|
42
|
+
// 黄色
|
|
43
|
+
success: {
|
|
44
|
+
default: styles.successColor,
|
|
45
|
+
light: styles.successLightColor
|
|
46
|
+
},
|
|
47
|
+
// 绿色
|
|
48
|
+
error: {
|
|
49
|
+
default: styles.errorColor,
|
|
50
|
+
light: styles.errorLightColor
|
|
51
|
+
},
|
|
52
|
+
// 红色
|
|
53
|
+
primary: {
|
|
54
|
+
default: styles.primaryColor,
|
|
55
|
+
light: styles.primaryLightColor
|
|
56
|
+
},
|
|
57
|
+
// 蓝色
|
|
58
|
+
default: DEFAULT_COLOR
|
|
59
|
+
};
|
|
60
|
+
const colorMap = {};
|
|
61
|
+
statusList === null || statusList === void 0 ? void 0 : statusList.forEach(status => {
|
|
62
|
+
const type = categorize(status);
|
|
63
|
+
colorMap[status.value] = categoryColors[type];
|
|
64
|
+
});
|
|
65
|
+
return colorMap;
|
|
66
|
+
}
|
|
67
|
+
const organizationId = getCurrentOrganizationId();
|
|
68
|
+
const StatusTag = props => {
|
|
69
|
+
const lovCode = props.lovCode,
|
|
70
|
+
value = props.value,
|
|
71
|
+
_props$text = props.text,
|
|
72
|
+
text = _props$text === void 0 ? "" : _props$text,
|
|
73
|
+
_props$showType = props.showType,
|
|
74
|
+
showType = _props$showType === void 0 ? "default" : _props$showType,
|
|
75
|
+
children = props.children,
|
|
76
|
+
className = props.className,
|
|
77
|
+
_props$categorize = props.categorize,
|
|
78
|
+
categorize = _props$categorize === void 0 ? defaultCategorize : _props$categorize;
|
|
79
|
+
const _useState = useState([]),
|
|
80
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
81
|
+
statusList = _useState2[0],
|
|
82
|
+
setStatusList = _useState2[1];
|
|
83
|
+
|
|
84
|
+
// 获取状态枚举值
|
|
85
|
+
async function getStatusEnum() {
|
|
86
|
+
var _Stores$LookupCodeSto, _Stores$LookupCodeSto2, _Stores$LookupCodeSto3;
|
|
87
|
+
// 请求快码值,优先返回缓存中的数据
|
|
88
|
+
const list = ((_Stores$LookupCodeSto = _Stores.LookupCodeStore) === null || _Stores$LookupCodeSto === void 0 ? void 0 : (_Stores$LookupCodeSto2 = _Stores$LookupCodeSto.merger) === null || _Stores$LookupCodeSto2 === void 0 ? void 0 : (_Stores$LookupCodeSto3 = _Stores$LookupCodeSto2.cache) === null || _Stores$LookupCodeSto3 === void 0 ? void 0 : _Stores$LookupCodeSto3.get(lovCode)) || [];
|
|
89
|
+
if ((list === null || list === void 0 ? void 0 : list.length) > 0) {
|
|
90
|
+
setStatusList(list);
|
|
91
|
+
} else {
|
|
92
|
+
const lookupData = await _Stores.LookupCodeStore.fetchLookupData({
|
|
93
|
+
url: `/hpfm/v1/${organizationId}/lovs/data?lovCode=${lovCode}`,
|
|
94
|
+
method: "GET"
|
|
95
|
+
});
|
|
96
|
+
setStatusList(lookupData || []);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
if (text) {
|
|
101
|
+
setStatusList([{
|
|
102
|
+
orderSeq: 1,
|
|
103
|
+
meaning: text,
|
|
104
|
+
value,
|
|
105
|
+
enabledFlag: 1
|
|
106
|
+
}]);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (!lovCode) return;
|
|
110
|
+
getStatusEnum(); // 请求状态枚举
|
|
111
|
+
}, [lovCode, text]);
|
|
112
|
+
|
|
113
|
+
// 计算颜色映射
|
|
114
|
+
const colorMap = useMemo(() => getStatusColorMap(statusList, categorize), [statusList, categorize]);
|
|
115
|
+
const color = useMemo(() => colorMap[value] || DEFAULT_COLOR, [colorMap, value]);
|
|
116
|
+
const label = useMemo(() => {
|
|
117
|
+
var _statusList$find;
|
|
118
|
+
return (statusList === null || statusList === void 0 ? void 0 : (_statusList$find = statusList.find(e => e.value === value)) === null || _statusList$find === void 0 ? void 0 : _statusList$find.meaning) || value;
|
|
119
|
+
}, [statusList, value]);
|
|
120
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
121
|
+
className: styles.statusTag
|
|
122
|
+
}, children || (showType === "circle" ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
|
123
|
+
style: {
|
|
124
|
+
backgroundColor: color.default
|
|
125
|
+
},
|
|
126
|
+
className: styles.statusCircle
|
|
127
|
+
}), /*#__PURE__*/React.createElement("span", {
|
|
128
|
+
style: {
|
|
129
|
+
color: color.default
|
|
130
|
+
},
|
|
131
|
+
className: styles.statusLabel
|
|
132
|
+
}, label)) : /*#__PURE__*/React.createElement("div", {
|
|
133
|
+
className: classNames(styles.statusContent, className),
|
|
134
|
+
style: {
|
|
135
|
+
backgroundColor: color.light,
|
|
136
|
+
color: color.default
|
|
137
|
+
}
|
|
138
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
139
|
+
className: styles.statusLabel
|
|
140
|
+
}, label))));
|
|
141
|
+
};
|
|
142
|
+
export default StatusTag;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// 状态标签组件
|
|
2
|
+
.statusTag {
|
|
3
|
+
.flex(@justify: flex-start);
|
|
4
|
+
height: 100%;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.statusContent {
|
|
8
|
+
padding: 0 0.08rem;
|
|
9
|
+
border-radius: 0.04rem;
|
|
10
|
+
min-width: 0.64rem;
|
|
11
|
+
display: flex;
|
|
12
|
+
align-items: center;
|
|
13
|
+
justify-content: center;
|
|
14
|
+
}
|
|
15
|
+
.statusCircle {
|
|
16
|
+
width: 0.08rem;
|
|
17
|
+
height: 0.08rem;
|
|
18
|
+
border-radius: 50%;
|
|
19
|
+
margin-right: 0.04rem;
|
|
20
|
+
}
|
|
21
|
+
.statusLabel {
|
|
22
|
+
font-size: @fontSize;
|
|
23
|
+
line-height: 0.24rem;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// 关键:导出给 JS/TS 使用
|
|
27
|
+
:export {
|
|
28
|
+
primaryColor: @primaryColor;
|
|
29
|
+
successColor: @successColor;
|
|
30
|
+
warningColor: @warnColor;
|
|
31
|
+
errorColor: @errorColor;
|
|
32
|
+
primaryWord: @primaryWord;
|
|
33
|
+
primaryLightColor: @primaryLightColor;
|
|
34
|
+
successLightColor: @successLightColor;
|
|
35
|
+
warningLightColor: @warnLightColor;
|
|
36
|
+
errorLightColor: @errorLightColor;
|
|
37
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @name 步骤条或时间线样式组件
|
|
3
|
+
* @param {string} className 自定义类名
|
|
4
|
+
* @param {string} itemClass 每一项数据自定义类名
|
|
5
|
+
* @param {StepItem[]} steps 步骤条配置列表
|
|
6
|
+
* @param {string} currentStatus 当前步骤状态
|
|
7
|
+
* @param {"horizontal" | "vertical"} layout 布局方向
|
|
8
|
+
* @author chuzhengyang
|
|
9
|
+
*/
|
|
10
|
+
import React from "react";
|
|
11
|
+
export interface StepItem {
|
|
12
|
+
/** 步骤标题 */
|
|
13
|
+
title?: string;
|
|
14
|
+
/** 自定义描述内容 */
|
|
15
|
+
content?: React.ReactNode;
|
|
16
|
+
/** 步骤描述 */
|
|
17
|
+
description?: string | React.ReactNode;
|
|
18
|
+
/** 步骤时间 */
|
|
19
|
+
time?: string;
|
|
20
|
+
/** 步骤状态 */
|
|
21
|
+
status?: string;
|
|
22
|
+
}
|
|
23
|
+
interface IStepProgressProps {
|
|
24
|
+
/** 自定义类名 */
|
|
25
|
+
className?: string;
|
|
26
|
+
/** 每一项数据自定义类名 */
|
|
27
|
+
itemClass?: string;
|
|
28
|
+
/** 步骤列表 */
|
|
29
|
+
steps: StepItem[];
|
|
30
|
+
/** 当前步骤状态 */
|
|
31
|
+
currentStatus?: string;
|
|
32
|
+
/** 布局方向 */
|
|
33
|
+
layout?: "horizontal" | "vertical";
|
|
34
|
+
}
|
|
35
|
+
declare const StepProgress: React.FC<IStepProgressProps>;
|
|
36
|
+
export default StepProgress;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @name 步骤条或时间线样式组件
|
|
3
|
+
* @param {string} className 自定义类名
|
|
4
|
+
* @param {string} itemClass 每一项数据自定义类名
|
|
5
|
+
* @param {StepItem[]} steps 步骤条配置列表
|
|
6
|
+
* @param {string} currentStatus 当前步骤状态
|
|
7
|
+
* @param {"horizontal" | "vertical"} layout 布局方向
|
|
8
|
+
* @author chuzhengyang
|
|
9
|
+
*/
|
|
10
|
+
import React, { useMemo } from "react";
|
|
11
|
+
import { findLastIndex } from "lodash";
|
|
12
|
+
import classNames from "classnames";
|
|
13
|
+
import styles from "./index.module.less?modules";
|
|
14
|
+
|
|
15
|
+
// 步骤条配置项信息
|
|
16
|
+
|
|
17
|
+
const StepProgress = props => {
|
|
18
|
+
const className = props.className,
|
|
19
|
+
itemClass = props.itemClass,
|
|
20
|
+
steps = props.steps,
|
|
21
|
+
_props$currentStatus = props.currentStatus,
|
|
22
|
+
currentStatus = _props$currentStatus === void 0 ? "completed" : _props$currentStatus,
|
|
23
|
+
_props$layout = props.layout,
|
|
24
|
+
layout = _props$layout === void 0 ? "horizontal" : _props$layout;
|
|
25
|
+
|
|
26
|
+
// const currentIndex = useMemo(() => steps?.findIndex((step) => step?.status === currentStatus), [steps, currentStatus]); // 获取当前状态在步骤列表中的索引
|
|
27
|
+
const currentIndex = useMemo(() => findLastIndex(steps, step => (step === null || step === void 0 ? void 0 : step.status) === currentStatus), [steps, currentStatus]); // 获取当前状态在步骤列表中的最后一个索引 以解决存在多个重复状态时后续状态无法被正常显示的问题
|
|
28
|
+
return layout === "horizontal" ? /*#__PURE__*/React.createElement("div", {
|
|
29
|
+
className: classNames(styles.stepProgress, className)
|
|
30
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
31
|
+
className: styles.stepsContainer
|
|
32
|
+
}, steps === null || steps === void 0 ? void 0 : steps.map((step, index) => {
|
|
33
|
+
// 当前步骤索引小于等于当前状态索引时高亮(包含当前状态及之前的所有步骤)
|
|
34
|
+
const isCompleted = index <= currentIndex;
|
|
35
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
36
|
+
key: `horizontal_${index}`,
|
|
37
|
+
className: classNames(styles.stepWrapper, itemClass)
|
|
38
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
39
|
+
className: styles.stepHeader
|
|
40
|
+
}, step.title && /*#__PURE__*/React.createElement("span", {
|
|
41
|
+
className: styles.stepTitle
|
|
42
|
+
}, step.title), /*#__PURE__*/React.createElement("div", {
|
|
43
|
+
className: classNames(styles.stepDot, {
|
|
44
|
+
[styles.completed]: isCompleted
|
|
45
|
+
})
|
|
46
|
+
})), (step === null || step === void 0 ? void 0 : step.content) || /*#__PURE__*/React.createElement("div", {
|
|
47
|
+
className: styles.stepContent
|
|
48
|
+
}, /*#__PURE__*/React.createElement("p", {
|
|
49
|
+
className: styles.description
|
|
50
|
+
}, step.description), /*#__PURE__*/React.createElement("p", {
|
|
51
|
+
className: styles.time
|
|
52
|
+
}, step.time)), index < steps.length - 1 && /*#__PURE__*/React.createElement("div", {
|
|
53
|
+
className: classNames(styles.connectionLine, {
|
|
54
|
+
[styles.hasTitle]: !!(step !== null && step !== void 0 && step.title),
|
|
55
|
+
[styles.completed]: isCompleted
|
|
56
|
+
})
|
|
57
|
+
}));
|
|
58
|
+
}))) : /*#__PURE__*/React.createElement("div", {
|
|
59
|
+
className: classNames(styles.verticalProgress, className)
|
|
60
|
+
}, steps === null || steps === void 0 ? void 0 : steps.map((step, index) => {
|
|
61
|
+
const stepStatus = step.status || "completed",
|
|
62
|
+
isLast = index === steps.length - 1;
|
|
63
|
+
const statusClass = (styles === null || styles === void 0 ? void 0 : styles[stepStatus]) || "";
|
|
64
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
65
|
+
key: `vertical${index}`,
|
|
66
|
+
className: classNames(styles.verticalItem, itemClass)
|
|
67
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
68
|
+
className: styles.verticalLeft
|
|
69
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
70
|
+
className: classNames(styles.verticalDot, (styles === null || styles === void 0 ? void 0 : styles[stepStatus]) || "")
|
|
71
|
+
})), !isLast && /*#__PURE__*/React.createElement("div", {
|
|
72
|
+
className: classNames(styles.verticalLine, statusClass)
|
|
73
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
74
|
+
className: styles.verticalRight
|
|
75
|
+
}, (step === null || step === void 0 ? void 0 : step.title) && /*#__PURE__*/React.createElement("span", {
|
|
76
|
+
className: styles.stepTitle
|
|
77
|
+
}, step.title), (step === null || step === void 0 ? void 0 : step.content) || /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("p", {
|
|
78
|
+
className: styles.time
|
|
79
|
+
}, step.time), /*#__PURE__*/React.createElement("span", {
|
|
80
|
+
className: styles.description
|
|
81
|
+
}, step.description))));
|
|
82
|
+
}));
|
|
83
|
+
};
|
|
84
|
+
export default StepProgress;
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
.stepProgress {
|
|
2
|
+
width: 100%;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.stepsContainer {
|
|
6
|
+
position: relative;
|
|
7
|
+
.flex(row, space-between, flex-start, nowrap);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.stepWrapper {
|
|
11
|
+
position: relative;
|
|
12
|
+
.flex(column);
|
|
13
|
+
flex: 1;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.stepHeader {
|
|
17
|
+
.flex(column);
|
|
18
|
+
margin-bottom: 0.16rem;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.stepTitle {
|
|
22
|
+
margin-bottom: 0.08rem;
|
|
23
|
+
font-size: @fontSize;
|
|
24
|
+
font-weight: 600;
|
|
25
|
+
color: @primaryWord;
|
|
26
|
+
|
|
27
|
+
&.completed {
|
|
28
|
+
color: @primaryWord;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
&.current {
|
|
32
|
+
color: @primaryColor;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
&.pending {
|
|
36
|
+
color: @borderColor;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.stepDot {
|
|
41
|
+
z-index: 1;
|
|
42
|
+
width: 0.16rem;
|
|
43
|
+
height: 0.16rem;
|
|
44
|
+
border-radius: 50%;
|
|
45
|
+
background-color: @lightWord;
|
|
46
|
+
|
|
47
|
+
&.completed {
|
|
48
|
+
background-color: @primaryColor;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
&.current {
|
|
52
|
+
background-color: @primaryColor;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
&.pending {
|
|
56
|
+
background-color: @borderColor;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.stepContent {
|
|
61
|
+
max-width: 2rem;
|
|
62
|
+
text-align: center;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.description {
|
|
66
|
+
line-height: 1.4;
|
|
67
|
+
margin: 0 0 0.08rem 0;
|
|
68
|
+
font-size: @smallFont;
|
|
69
|
+
color: @primaryWord;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.time {
|
|
73
|
+
margin: 0;
|
|
74
|
+
font-size: @smallFont;
|
|
75
|
+
color: @minorWord;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// 水平布局连接线
|
|
79
|
+
.connectionLine {
|
|
80
|
+
.position(absolute, 0.08rem, @left: calc(50% + 0.16rem));
|
|
81
|
+
z-index: 0;
|
|
82
|
+
width: calc(100% - 0.32rem);
|
|
83
|
+
height: 0.02rem;
|
|
84
|
+
background-color: @lightWord;
|
|
85
|
+
&.hasTitle {
|
|
86
|
+
top: 0.36rem;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.connectionLine.completed {
|
|
91
|
+
background: @primaryColor;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.stepWrapper:last-child .connectionLine {
|
|
95
|
+
display: none;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ============ 竖向布局(时间线模式) ============
|
|
99
|
+
.verticalProgress {
|
|
100
|
+
width: 100%;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.verticalItem {
|
|
104
|
+
position: relative;
|
|
105
|
+
padding-bottom: 0.1rem;
|
|
106
|
+
.flex(@align: flex-start);
|
|
107
|
+
|
|
108
|
+
&:last-child {
|
|
109
|
+
padding-bottom: 0;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.verticalLeft {
|
|
114
|
+
position: relative;
|
|
115
|
+
.flex(column);
|
|
116
|
+
flex-shrink: 0;
|
|
117
|
+
width: 0.24rem;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.verticalDot {
|
|
121
|
+
position: relative;
|
|
122
|
+
z-index: 1;
|
|
123
|
+
flex-shrink: 0;
|
|
124
|
+
width: 0.16rem;
|
|
125
|
+
height: 0.16rem;
|
|
126
|
+
border-radius: 50%;
|
|
127
|
+
background-color: @borderColor;
|
|
128
|
+
|
|
129
|
+
&.completed {
|
|
130
|
+
background-color: @primaryColor;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
&.current {
|
|
134
|
+
background-color: @primaryColor;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
&.pending {
|
|
138
|
+
background-color: @borderColor;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.verticalLine {
|
|
143
|
+
.position(absolute, 0.24rem, unset, 0.1rem, 0.12rem);
|
|
144
|
+
width: 0.02rem;
|
|
145
|
+
background-color: @borderColor;
|
|
146
|
+
transform: translateX(-50%);
|
|
147
|
+
|
|
148
|
+
&.completed {
|
|
149
|
+
background-color: @primaryColor;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
&.current {
|
|
153
|
+
background-color: @primaryColor;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
&.pending {
|
|
157
|
+
background-color: @borderColor;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.verticalRight {
|
|
162
|
+
.position(relative, -0.03rem);
|
|
163
|
+
flex: 1;
|
|
164
|
+
padding-left: 0.16rem;
|
|
165
|
+
padding-right: 0.16rem;
|
|
166
|
+
padding-bottom: 0.12rem;
|
|
167
|
+
.time {
|
|
168
|
+
margin-bottom: 0.12rem;
|
|
169
|
+
font-size: @fontSize;
|
|
170
|
+
color: @minorWord;
|
|
171
|
+
}
|
|
172
|
+
.description {
|
|
173
|
+
position: relative;
|
|
174
|
+
display: inline-block;
|
|
175
|
+
max-width: calc(100% - 2.22rem);
|
|
176
|
+
line-height: 1.4;
|
|
177
|
+
font-size: @fontSize;
|
|
178
|
+
color: @primaryWord;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @name 通用表格组件
|
|
3
|
+
* @param {string} className 该组件自定义类名
|
|
4
|
+
* @param {ButtonItemProps[]} optBtns 操作栏中按钮集合
|
|
5
|
+
* @param {object} renderColumn 自定义操作栏配置
|
|
6
|
+
* @param {boolean} isShowDivider 是否显示分割线
|
|
7
|
+
* @param {string} dividerClass 分割线自定义样式
|
|
8
|
+
* @param {string} customizedCode 该组件自定义表格列的唯一性标识
|
|
9
|
+
* @param {React.ReactNode} extra 表格头部额外内容(默认置于右侧)
|
|
10
|
+
* @param {React.ReactNode} customHeader 自定义表格头部操作区域
|
|
11
|
+
* @param {...args} 其他剩余参数 同choerodon UI组件中的Table使用方式
|
|
12
|
+
* @author lichen
|
|
13
|
+
*/
|
|
14
|
+
import React from "react";
|
|
15
|
+
import type { TableProps } from "choerodon-ui/pro/lib/table/Table";
|
|
16
|
+
import type { ColumnProps } from "choerodon-ui/pro/lib/table/Column";
|
|
17
|
+
import type { ButtonItemProps } from "../TableOperationColumn";
|
|
18
|
+
import type { IProps as ITableQueryBarProps } from "../QueryBar/TableQueryBar";
|
|
19
|
+
interface IProps extends Omit<TableProps, "queryBarProps"> {
|
|
20
|
+
/** 自定义类名 */
|
|
21
|
+
className?: string;
|
|
22
|
+
/** 操作栏中按钮集合 */
|
|
23
|
+
optBtns?: ButtonItemProps[];
|
|
24
|
+
/** 需要自定义render方法的列配置 key为当前列的name值 操作栏固定key为operation */
|
|
25
|
+
renderColumn?: {
|
|
26
|
+
[key: string]: ColumnProps;
|
|
27
|
+
};
|
|
28
|
+
/** 是否显示分割线 */
|
|
29
|
+
isShowDivider?: boolean;
|
|
30
|
+
/** 分割线自定义样式 */
|
|
31
|
+
dividerClass?: string;
|
|
32
|
+
/** 是否显示展开收起按钮 */
|
|
33
|
+
isShowCollapseBtn?: boolean;
|
|
34
|
+
/** 自定义表格列标识码 */
|
|
35
|
+
customizedCode?: string;
|
|
36
|
+
/** 表格头部额外内容(默认置于右侧) */
|
|
37
|
+
extra?: React.ReactNode;
|
|
38
|
+
/** 自定义表格头部操作区域 */
|
|
39
|
+
customHeader?: React.ReactNode;
|
|
40
|
+
/** 自定义查询栏配置 */
|
|
41
|
+
queryBarProps?: Partial<ITableQueryBarProps>;
|
|
42
|
+
}
|
|
43
|
+
declare const Table: React.FC<IProps>;
|
|
44
|
+
export default Table;
|