@pnt-team/pnt-component-frontend 0.0.89 → 0.0.92

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.
@@ -1,15 +1,15 @@
1
- .pnt-image-preview-wrapper {
1
+ .pnt-image-wrapper {
2
2
  position: relative;
3
3
 
4
- .pnt-image-preview-progress,
5
- .pnt-image-preview-upload-progress {
4
+ .pnt-image-progress,
5
+ .pnt-image-upload-progress {
6
6
  width: 136px;
7
7
  height: 136px;
8
8
  display: flex;
9
9
  align-items: center;
10
10
  justify-content: center;
11
11
 
12
- .pnt-image-preview-loading {
12
+ .pnt-image-loading {
13
13
  width: 100%;
14
14
  height: 100%;
15
15
  text-align: center;
@@ -33,18 +33,25 @@
33
33
  }
34
34
  }
35
35
 
36
- .pnt-image-preview {
36
+ .pnt-image {
37
37
  width: 136px;
38
38
  height: 136px;
39
39
 
40
- .pnt-image-preview-mask {
40
+ .pnt-image-mask {
41
41
  background: rgba(0, 0, 0, 60%);
42
42
  color: #fff;
43
43
  height: 100%;
44
44
  display: flex;
45
45
  align-items: center;
46
46
  justify-content: center;
47
- .pnt-image-preview-divider {
47
+
48
+ // 纯预览模式:半透明遮罩,鼠标手型
49
+ &--basic {
50
+ cursor: pointer;
51
+ }
52
+
53
+ // 上传预览模式:分隔线
54
+ .pnt-image-divider {
48
55
  margin: 0 var(--td-comp-margin-l);
49
56
  border-left: 1px var(--td-text-color-anti) solid;
50
57
  height: var(--td-comp-size-xxxs);
@@ -1,5 +1,5 @@
1
1
  export { PntProvider, usePntConfig, type PntConfig, type commonEesType, } from './config';
2
- export { default as PntImagePreview } from './components/PntImagePreview';
2
+ export { default as PntImage } from './components/PntImage';
3
3
  export { default as PntBusinessSelect } from './components/PntBusinessSelect';
4
4
  export { default as PntSecureBox } from './components/PntSecureBox';
5
5
  export { default as PntGeneralLayout } from './components/PntGeneralLayout';
package/lib/cjs/index.js CHANGED
@@ -31,14 +31,14 @@ var src_exports = {};
31
31
  __export(src_exports, {
32
32
  PntBusinessSelect: () => import_PntBusinessSelect.default,
33
33
  PntGeneralLayout: () => import_PntGeneralLayout.default,
34
- PntImagePreview: () => import_PntImagePreview.default,
34
+ PntImage: () => import_PntImage.default,
35
35
  PntProvider: () => import_config.PntProvider,
36
36
  PntSecureBox: () => import_PntSecureBox.default,
37
37
  usePntConfig: () => import_config.usePntConfig
38
38
  });
39
39
  module.exports = __toCommonJS(src_exports);
40
40
  var import_config = require("./config");
41
- var import_PntImagePreview = __toESM(require("./components/PntImagePreview"));
41
+ var import_PntImage = __toESM(require("./components/PntImage"));
42
42
  var import_PntBusinessSelect = __toESM(require("./components/PntBusinessSelect"));
43
43
  var import_PntSecureBox = __toESM(require("./components/PntSecureBox"));
44
44
  var import_PntGeneralLayout = __toESM(require("./components/PntGeneralLayout"));
@@ -46,7 +46,7 @@ var import_PntGeneralLayout = __toESM(require("./components/PntGeneralLayout"));
46
46
  0 && (module.exports = {
47
47
  PntBusinessSelect,
48
48
  PntGeneralLayout,
49
- PntImagePreview,
49
+ PntImage,
50
50
  PntProvider,
51
51
  PntSecureBox,
52
52
  usePntConfig
@@ -153,36 +153,19 @@ const PntBusinessSelect = props => {
153
153
  // append=true 为滚动翻页(追加),append=false 为初始化/搜索/重置(替换)
154
154
  const fetchData = useCallback(async (kw, page, append) => {
155
155
  if (append) {
156
- if (appendLoadingRef.current || loadingRef.current) {
157
- console.log('[PntBS] fetchData APPEND blocked: loading=' + loadingRef.current + ' appendLoading=' + appendLoadingRef.current);
158
- return;
159
- }
156
+ if (appendLoadingRef.current || loadingRef.current) return;
160
157
  const meta = listMetaRef.current;
161
- if (meta.keyword !== kw) {
162
- console.log('[PntBS] fetchData APPEND blocked: kw mismatch ' + kw + ' vs ' + meta.keyword);
163
- return;
164
- }
165
- if (page <= meta.page) {
166
- console.log('[PntBS] fetchData APPEND blocked: page ' + page + ' <= ' + meta.page);
167
- return;
168
- }
169
- if (optionsRef.current.length >= meta.total) {
170
- console.log('[PntBS] fetchData APPEND blocked: no more');
171
- return;
172
- }
158
+ if (meta.keyword !== kw) return;
159
+ if (page <= meta.page) return;
160
+ if (optionsRef.current.length >= meta.total) return;
173
161
  appendLoadingRef.current = true;
174
162
  }
175
163
  const seq = ++fetchSeqRef.current;
176
- console.log('[PntBS] fetchData START kw="' + kw + '" page=' + page + ' append=' + append + ' seq=' + seq);
177
164
  loadingRef.current = true;
178
165
  setLoading(true);
179
166
  try {
180
167
  const res = await requestFn(buildParams(kw, page));
181
- console.log('[PntBS] fetchData GOT seq=' + seq + ' latestSeq=' + fetchSeqRef.current + ' code=' + res.code);
182
- if (seq !== fetchSeqRef.current) {
183
- console.log('[PntBS] fetchData seq MISMATCH - DROPPED (seq=' + seq + ' latest=' + fetchSeqRef.current + ')');
184
- return;
185
- }
168
+ if (seq !== fetchSeqRef.current) return;
186
169
  if (res.code === 0 && res.data) {
187
170
  const newList = res.data.list || [];
188
171
  const resTotal = res.data.pagination?.total || 0;
@@ -200,15 +183,11 @@ const PntBusinessSelect = props => {
200
183
  page,
201
184
  total: resTotal
202
185
  };
203
- console.log('[PntBS] fetchData SET options count=' + nextList.length + ' first=' + (nextList[0]?.name || 'null'));
204
186
  setOptions(nextList);
205
187
  onLoadedRef.current?.(nextList);
206
- } else {
207
- console.log('[PntBS] fetchData BAD RESPONSE code=' + res.code + ' hasData=' + !!res.data);
208
188
  }
209
- } catch (e) {
210
- const msg = e instanceof Error ? e.message : String(e);
211
- console.log('[PntBS] fetchData ERROR seq=' + seq + ' kw="' + kw + '": ' + msg);
189
+ } catch {
190
+ // 请求失败静默处理,不阻塞主流程
212
191
  } finally {
213
192
  if (append) appendLoadingRef.current = false;
214
193
  if (seq === fetchSeqRef.current) {
@@ -221,12 +200,9 @@ const PntBusinessSelect = props => {
221
200
  // ---- 远程搜索(防抖) ----
222
201
  const handleSearch = useCallback(val => {
223
202
  keywordRef.current = val;
224
- console.log('[PntBS] handleSearch val="' + val + '" debounceMs=' + searchDebounce);
225
203
  if (debounceRef.current) clearTimeout(debounceRef.current);
226
204
  debounceRef.current = setTimeout(() => {
227
- const kw = keywordRef.current;
228
- console.log('[PntBS] handleSearch timer fired, fetchData kw="' + kw + '" append=false seq++');
229
- fetchData(kw, 1, false);
205
+ fetchData(keywordRef.current, 1, false);
230
206
  }, searchDebounce);
231
207
  }, [fetchData, searchDebounce]);
232
208
 
@@ -250,7 +226,6 @@ const PntBusinessSelect = props => {
250
226
  // 上次搜索结果,关闭时必须重置回默认列表。
251
227
  keywordRef.current = '';
252
228
  if (listMetaRef.current.keyword) {
253
- console.log('[PntBS] popupClose resetting from kw="' + listMetaRef.current.keyword + '"');
254
229
  fetchData('', 1, false);
255
230
  }
256
231
  }, [fetchData]);
@@ -475,7 +450,6 @@ const PntBusinessSelect = props => {
475
450
  // 点击 clear 按钮(X)时重置列表——TDesign 的 onClearValue 只 setInputValue,
476
451
  // 不触发 handleInputChange / onSearch,所以需要主动重置。
477
452
  const handleClear = useCallback(() => {
478
- console.log('[PntBS] handleClear X-button clicked, resetting');
479
453
  keywordRef.current = '';
480
454
  if (debounceRef.current) clearTimeout(debounceRef.current);
481
455
  if (listMetaRef.current.keyword) {
@@ -0,0 +1,87 @@
1
+ import React, { FC } from 'react';
2
+ import './index.scss';
3
+ /**
4
+ * PntImage 文案集合
5
+ * @description 所有内部展示文案均可通过 texts prop 自定义,用于多语言场景
6
+ */
7
+ export interface PntImageTexts {
8
+ /** 上传中占位文案(仅上传预览模式生效) */
9
+ uploading?: string;
10
+ /** 图片加载中占位文案(纯预览模式生效,透传给 tdesign Image loading) */
11
+ loading?: string;
12
+ /** 图片加载失败占位文案(纯预览模式生效,透传给 tdesign Image error) */
13
+ loadFailed?: string;
14
+ }
15
+ export interface PntImageProps {
16
+ /**
17
+ * 图片地址
18
+ * @description 图片的完整 URL 地址;为空则展示 defaultImg 或内置 uploadImg
19
+ */
20
+ src: string | undefined;
21
+ /**
22
+ * alt 文本
23
+ * @description 图片加载失败时的替代文本,纯预览模式必传以提升可访问性
24
+ */
25
+ alt?: string;
26
+ /**
27
+ * 默认图片
28
+ * @description src 为空时展示的占位图;不传则使用内置的 uploadImg
29
+ */
30
+ defaultImg?: string;
31
+ /**
32
+ * 自定义样式
33
+ * @description 一般用于控制图片宽高
34
+ */
35
+ style?: React.CSSProperties;
36
+ /**
37
+ * 上传中状态
38
+ * @description 当为 true 时显示上传中 loading 占位,阻止其他操作;仅在上传预览模式(传入 onRemove)生效
39
+ */
40
+ loading?: boolean;
41
+ /**
42
+ * 删除回调
43
+ * @description 传入即启用「上传预览模式」,mask 含预览 + 删除按钮;不传则为「纯预览模式」
44
+ * @param e - 事件对象
45
+ */
46
+ onRemove?: (e: any) => void;
47
+ /**
48
+ * attach 容器
49
+ * @description 弹窗场景下需要透传给 tdesign ImageViewer 的 attach,避免预览浮层被父容器裁剪
50
+ */
51
+ container?: HTMLElement | (() => HTMLElement);
52
+ /**
53
+ * 多语言文案
54
+ * @description 传入即覆盖默认中文文案;仅对应字段会覆盖,未传字段仍用默认值
55
+ */
56
+ texts?: PntImageTexts;
57
+ }
58
+ /**
59
+ * PntImage 业务图片组件
60
+ * @description 统一覆盖「上传图片预览」和「纯图片预览」两种业务场景,避免业务侧维护两套组件
61
+ *
62
+ * 模式判定:传入 `onRemove` 即为上传预览模式,否则为纯预览模式
63
+ *
64
+ * @example
65
+ * ```tsx
66
+ * // 上传预览模式
67
+ * <PntImage
68
+ * src={iconUrl}
69
+ * loading={loading}
70
+ * defaultImg={defaultImg}
71
+ * onRemove={handleRemove}
72
+ * style={{ width: 136, height: 136 }}
73
+ * />
74
+ *
75
+ * // 纯预览模式
76
+ * <PntImage
77
+ * src={url}
78
+ * alt="avatar"
79
+ * style={{ width: 60, height: 60 }}
80
+ * container={container}
81
+ * />
82
+ * ```
83
+ *
84
+ * @returns {ReactElement} 业务图片组件
85
+ */
86
+ declare const PntImage: FC<PntImageProps>;
87
+ export default PntImage;
@@ -0,0 +1,181 @@
1
+ import uploadImg from "../../assets/images/uploadImg.png";
2
+ import React from 'react';
3
+ import { BrowseIcon, DeleteIcon, ImageErrorIcon, ImageIcon, LoadingIcon } from 'tdesign-icons-react';
4
+ import { Image, ImageViewer, Space } from 'tdesign-react';
5
+ import "./index.scss";
6
+
7
+ /**
8
+ * PntImage 文案集合
9
+ * @description 所有内部展示文案均可通过 texts prop 自定义,用于多语言场景
10
+ */
11
+ import { jsx as _jsx } from "react/jsx-runtime";
12
+ import { jsxs as _jsxs } from "react/jsx-runtime";
13
+ import { Fragment as _Fragment } from "react/jsx-runtime";
14
+ /**
15
+ * 默认中文文案
16
+ */
17
+ const DEFAULT_TEXTS = {
18
+ uploading: '上传中',
19
+ loading: '加载中',
20
+ loadFailed: '加载失败'
21
+ };
22
+ /**
23
+ * PntImage 业务图片组件
24
+ * @description 统一覆盖「上传图片预览」和「纯图片预览」两种业务场景,避免业务侧维护两套组件
25
+ *
26
+ * 模式判定:传入 `onRemove` 即为上传预览模式,否则为纯预览模式
27
+ *
28
+ * @example
29
+ * ```tsx
30
+ * // 上传预览模式
31
+ * <PntImage
32
+ * src={iconUrl}
33
+ * loading={loading}
34
+ * defaultImg={defaultImg}
35
+ * onRemove={handleRemove}
36
+ * style={{ width: 136, height: 136 }}
37
+ * />
38
+ *
39
+ * // 纯预览模式
40
+ * <PntImage
41
+ * src={url}
42
+ * alt="avatar"
43
+ * style={{ width: 60, height: 60 }}
44
+ * container={container}
45
+ * />
46
+ * ```
47
+ *
48
+ * @returns {ReactElement} 业务图片组件
49
+ */
50
+ const PntImage = ({
51
+ src,
52
+ alt = '',
53
+ defaultImg,
54
+ style,
55
+ loading = false,
56
+ onRemove,
57
+ container,
58
+ texts
59
+ }) => {
60
+ // 模式判定:传入 onRemove 即为上传预览模式
61
+ const isUploadMode = typeof onRemove === 'function';
62
+ const finalSrc = src?.length ? src : defaultImg || uploadImg;
63
+ const attach = container ? typeof container === 'function' ? container : () => container : undefined;
64
+ // 合并文案:texts 字段覆盖默认中文
65
+ const finalTexts = {
66
+ ...DEFAULT_TEXTS,
67
+ ...texts
68
+ };
69
+
70
+ /**
71
+ * 上传预览模式的 loading 占位
72
+ * @param isImageLoading - 是否为 tdesign Image 内部图片加载状态(区别于上传中状态)
73
+ */
74
+ const UploadLoadingContent = isImageLoading => /*#__PURE__*/_jsx("div", {
75
+ className: isImageLoading ? 'pnt-image-progress' : 'pnt-image-upload-progress',
76
+ style: style,
77
+ children: /*#__PURE__*/_jsxs("div", {
78
+ className: "pnt-image-loading",
79
+ children: [/*#__PURE__*/_jsx(LoadingIcon, {
80
+ size: "18px",
81
+ name: "loading"
82
+ }), /*#__PURE__*/_jsx("p", {
83
+ children: finalTexts.uploading
84
+ })]
85
+ })
86
+ });
87
+
88
+ /**
89
+ * 纯预览模式:图片加载中占位(透传给 tdesign Image loading)
90
+ */
91
+ const basicImageLoading = /*#__PURE__*/_jsxs(Space, {
92
+ direction: "vertical",
93
+ align: "center",
94
+ size: "small",
95
+ style: {
96
+ color: 'var(--td-text-color-disabled)'
97
+ },
98
+ children: [/*#__PURE__*/_jsx(ImageIcon, {
99
+ size: 24
100
+ }), finalTexts.loading]
101
+ });
102
+
103
+ /**
104
+ * 纯预览模式:图片加载失败占位(透传给 tdesign Image error)
105
+ */
106
+ const basicImageError = /*#__PURE__*/_jsxs(Space, {
107
+ direction: "vertical",
108
+ align: "center",
109
+ size: "small",
110
+ children: [/*#__PURE__*/_jsx(ImageErrorIcon, {
111
+ size: 24
112
+ }), finalTexts.loadFailed]
113
+ });
114
+
115
+ /**
116
+ * 纯预览模式 mask:半透明遮罩,点击触发预览
117
+ */
118
+ const basicMask = open => /*#__PURE__*/_jsx("div", {
119
+ className: "pnt-image-mask pnt-image-mask--basic",
120
+ style: {
121
+ background: 'rgba(0,0,0,.1)',
122
+ height: '100%'
123
+ },
124
+ onClick: open
125
+ });
126
+
127
+ /**
128
+ * 上传预览模式 mask:预览按钮 + 分隔线 + 删除按钮
129
+ */
130
+ const uploadMask = open => /*#__PURE__*/_jsxs("div", {
131
+ className: "pnt-image-mask pnt-image-mask--upload",
132
+ children: [/*#__PURE__*/_jsx("span", {
133
+ children: /*#__PURE__*/_jsx(BrowseIcon, {
134
+ onClick: open,
135
+ size: "16px",
136
+ name: "browse"
137
+ })
138
+ }), /*#__PURE__*/_jsx("span", {
139
+ className: "pnt-image-divider"
140
+ }), /*#__PURE__*/_jsx("span", {
141
+ children: /*#__PURE__*/_jsx(DeleteIcon, {
142
+ onClick: onRemove,
143
+ size: "16px",
144
+ name: "delete"
145
+ })
146
+ })]
147
+ });
148
+ return /*#__PURE__*/_jsx("div", {
149
+ className: "pnt-image-wrapper",
150
+ onClick: e => {
151
+ // 上传预览模式:图片已上传或上传中时阻止冒泡,避免触发外层 Upload
152
+ if (isUploadMode && (src?.length || loading)) {
153
+ e.stopPropagation();
154
+ }
155
+ },
156
+ children: isUploadMode && loading ? UploadLoadingContent(false) : /*#__PURE__*/_jsx(ImageViewer, {
157
+ images: [finalSrc],
158
+ closeOnOverlay: true
159
+ // @ts-expect-error - attach 在 tdesign-react 运行时支持但未在类型定义中声明(弹窗 attach 容器)
160
+ ,
161
+ attach: attach,
162
+ trigger: ({
163
+ open
164
+ }) => {
165
+ const mask = isUploadMode ? uploadMask(open) : basicMask(open);
166
+ return /*#__PURE__*/_jsx(Image, {
167
+ alt: alt,
168
+ src: finalSrc,
169
+ loading: isUploadMode ? UploadLoadingContent(true) : basicImageLoading,
170
+ error: isUploadMode ? undefined : basicImageError,
171
+ overlayContent: isUploadMode ? src ? mask : /*#__PURE__*/_jsx(_Fragment, {}) : mask,
172
+ overlayTrigger: "hover",
173
+ fit: "contain",
174
+ className: "pnt-image",
175
+ style: style
176
+ });
177
+ }
178
+ })
179
+ });
180
+ };
181
+ export default PntImage;
@@ -1,15 +1,15 @@
1
- .pnt-image-preview-wrapper {
1
+ .pnt-image-wrapper {
2
2
  position: relative;
3
3
 
4
- .pnt-image-preview-progress,
5
- .pnt-image-preview-upload-progress {
4
+ .pnt-image-progress,
5
+ .pnt-image-upload-progress {
6
6
  width: 136px;
7
7
  height: 136px;
8
8
  display: flex;
9
9
  align-items: center;
10
10
  justify-content: center;
11
11
 
12
- .pnt-image-preview-loading {
12
+ .pnt-image-loading {
13
13
  width: 100%;
14
14
  height: 100%;
15
15
  text-align: center;
@@ -33,18 +33,25 @@
33
33
  }
34
34
  }
35
35
 
36
- .pnt-image-preview {
36
+ .pnt-image {
37
37
  width: 136px;
38
38
  height: 136px;
39
39
 
40
- .pnt-image-preview-mask {
40
+ .pnt-image-mask {
41
41
  background: rgba(0, 0, 0, 60%);
42
42
  color: #fff;
43
43
  height: 100%;
44
44
  display: flex;
45
45
  align-items: center;
46
46
  justify-content: center;
47
- .pnt-image-preview-divider {
47
+
48
+ // 纯预览模式:半透明遮罩,鼠标手型
49
+ &--basic {
50
+ cursor: pointer;
51
+ }
52
+
53
+ // 上传预览模式:分隔线
54
+ .pnt-image-divider {
48
55
  margin: 0 var(--td-comp-margin-l);
49
56
  border-left: 1px var(--td-text-color-anti) solid;
50
57
  height: var(--td-comp-size-xxxs);
@@ -1,5 +1,5 @@
1
1
  export { PntProvider, usePntConfig, type PntConfig, type commonEesType, } from './config';
2
- export { default as PntImagePreview } from './components/PntImagePreview';
2
+ export { default as PntImage } from './components/PntImage';
3
3
  export { default as PntBusinessSelect } from './components/PntBusinessSelect';
4
4
  export { default as PntSecureBox } from './components/PntSecureBox';
5
5
  export { default as PntGeneralLayout } from './components/PntGeneralLayout';
package/lib/esm/index.js CHANGED
@@ -8,7 +8,7 @@
8
8
  export { PntProvider, usePntConfig } from "./config";
9
9
 
10
10
  // ---------- L1 基础展示组件 ----------
11
- export { default as PntImagePreview } from "./components/PntImagePreview";
11
+ export { default as PntImage } from "./components/PntImage";
12
12
 
13
13
  // ---------- L2 业务复合组件 ----------
14
14
  export { default as PntBusinessSelect } from "./components/PntBusinessSelect";
@@ -1 +1 @@
1
- .pnt-image-preview-wrapper{position:relative}.pnt-image-preview-wrapper .pnt-image-preview-progress,.pnt-image-preview-wrapper .pnt-image-preview-upload-progress{align-items:center;display:flex;height:8.5rem;justify-content:center;width:8.5rem}.pnt-image-preview-wrapper .pnt-image-preview-progress .pnt-image-preview-loading,.pnt-image-preview-wrapper .pnt-image-preview-upload-progress .pnt-image-preview-loading{align-items:center;background-color:#f7f8fa;border-radius:.25rem;display:flex;flex-direction:column;height:100%;justify-content:center;text-align:center;width:100%}.pnt-image-preview-wrapper .pnt-image-preview-progress .pnt-image-preview-loading svg,.pnt-image-preview-wrapper .pnt-image-preview-upload-progress .pnt-image-preview-loading svg{color:var(--td-brand-color);font-size:1.5rem}.pnt-image-preview-wrapper .pnt-image-preview-progress .pnt-image-preview-loading p,.pnt-image-preview-wrapper .pnt-image-preview-upload-progress .pnt-image-preview-loading p{color:#808191;font-size:.75rem;margin-top:.25rem}.pnt-image-preview-wrapper .pnt-image-preview{height:8.5rem;width:8.5rem}.pnt-image-preview-wrapper .pnt-image-preview .pnt-image-preview-mask{align-items:center;background:rgba(0,0,0,.6);color:#fff;display:flex;height:100%;justify-content:center}.pnt-image-preview-wrapper .pnt-image-preview .pnt-image-preview-mask .pnt-image-preview-divider{border-left:.0625rem solid var(--td-text-color-anti);height:var(--td-comp-size-xxxs);margin:0 var(--td-comp-margin-l)}.pnt-business-select{width:100%}.pnt-business-select-option-label{display:block;width:100%}.pnt-business-select-popup .t-popup__content .t-loading,.pnt-business-select-popup .t-popup__content .total-wrapper{align-items:center;display:flex;font-weight:400;height:2.25rem;line-height:1.25rem;padding:0 .875rem}.pnt-business-select-popup .t-popup__content .total-wrapper{color:#808191;font-size:.875rem}.pnt-secure-box{color:#333;max-width:-moz-fit-content;max-width:fit-content;position:relative}.pnt-secure-box .view-icon{color:#3f8cff!important;cursor:pointer;font-size:small;position:absolute;right:-1.875rem;top:.0625rem}.pnt-secure-box .security-value{position:relative;top:.1875rem}.pnt-general-layout{--pnt-layout-body-padding:1.5rem;--pnt-layout-card-radius:0.25rem;background-color:transparent;height:100%}.pnt-general-layout .t-layout__header{align-items:stretch;border-bottom:.0625rem solid #f0f3f6;display:flex;flex-shrink:0;height:auto;justify-content:space-between}.pnt-general-layout .t-layout__header .header-title{align-items:center;display:inline-flex;padding:1.5rem}.pnt-general-layout .t-layout__header .header-title .goback-icon{color:#3f8cff;cursor:pointer;margin-right:.75rem}.pnt-general-layout .t-layout__header .header-title .title{font-size:1.25rem;font-weight:600;line-height:1.5rem}.pnt-general-layout .t-layout__header .header-operation{align-items:center;display:flex;padding-right:1.5rem}.pnt-general-layout .t-layout__header .header-operation .t-button+.t-button{margin-left:.75rem}.pnt-general-layout--borderless .t-layout__header{border-bottom:none}.pnt-general-layout .general-layout-sub-header{border-bottom:.0625rem solid #f0f3f6;flex-shrink:0}.pnt-general-layout .general-layout-body{background:#fafafa;flex:1 1 auto;min-height:0;overflow-y:auto;padding:var(--pnt-layout-body-padding)}.pnt-general-layout .general-layout-body>div.t-card,.pnt-general-layout .general-layout-body>div.t-loading__parent>div.t-card,.pnt-general-layout .general-layout-body>div.tea-card,.pnt-general-layout .general-layout-body>div[class*=-block],.pnt-general-layout .general-layout-body>div[class*=-wrapper]{border-radius:var(--pnt-layout-card-radius);box-shadow:none;margin-bottom:1.5rem}.pnt-general-layout .general-layout-body>div.t-card .t-card__body,.pnt-general-layout .general-layout-body>div.t-loading__parent>div.t-card .t-card__body,.pnt-general-layout .general-layout-body>div.tea-card .t-card__body,.pnt-general-layout .general-layout-body>div[class*=-block] .t-card__body,.pnt-general-layout .general-layout-body>div[class*=-wrapper] .t-card__body{border-radius:var(--pnt-layout-card-radius)}.pnt-general-layout .general-layout-body>div.t-loading__parent>div:last-child.t-card,.pnt-general-layout .general-layout-body>div:last-child,.pnt-general-layout .general-layout-body>div:last-child.t-card,.pnt-general-layout .general-layout-body>div:last-child.tea-card,.pnt-general-layout .general-layout-body>div:last-child[class*=-block],.pnt-general-layout .general-layout-body>div:last-child[class*=-wrapper]{margin-bottom:0}.pnt-general-layout .t-layout__footer{background:#fff;border-top:.0625rem solid #f0f3f6;flex-shrink:0;padding:1.125rem 1.5rem}.pnt-general-layout .t-layout__footer .t-button{font-size:.875rem;font-weight:600;height:2.25rem;min-width:5.75rem}.pnt-general-layout .t-layout__footer .t-button+.t-button{margin-left:.75rem}.pnt-general-layout--footer-auto .t-layout__footer .t-button{font-size:inherit;font-weight:inherit;height:auto;min-width:0}
1
+ .pnt-image-wrapper{position:relative}.pnt-image-wrapper .pnt-image-progress,.pnt-image-wrapper .pnt-image-upload-progress{align-items:center;display:flex;height:8.5rem;justify-content:center;width:8.5rem}.pnt-image-wrapper .pnt-image-progress .pnt-image-loading,.pnt-image-wrapper .pnt-image-upload-progress .pnt-image-loading{align-items:center;background-color:#f7f8fa;border-radius:.25rem;display:flex;flex-direction:column;height:100%;justify-content:center;text-align:center;width:100%}.pnt-image-wrapper .pnt-image-progress .pnt-image-loading svg,.pnt-image-wrapper .pnt-image-upload-progress .pnt-image-loading svg{color:var(--td-brand-color);font-size:1.5rem}.pnt-image-wrapper .pnt-image-progress .pnt-image-loading p,.pnt-image-wrapper .pnt-image-upload-progress .pnt-image-loading p{color:#808191;font-size:.75rem;margin-top:.25rem}.pnt-image-wrapper .pnt-image{height:8.5rem;width:8.5rem}.pnt-image-wrapper .pnt-image .pnt-image-mask{align-items:center;background:rgba(0,0,0,.6);color:#fff;display:flex;height:100%;justify-content:center}.pnt-image-wrapper .pnt-image .pnt-image-mask--basic{cursor:pointer}.pnt-image-wrapper .pnt-image .pnt-image-mask .pnt-image-divider{border-left:.0625rem solid var(--td-text-color-anti);height:var(--td-comp-size-xxxs);margin:0 var(--td-comp-margin-l)}.pnt-business-select{width:100%}.pnt-business-select-option-label{display:block;width:100%}.pnt-business-select-popup .t-popup__content .t-loading,.pnt-business-select-popup .t-popup__content .total-wrapper{align-items:center;display:flex;font-weight:400;height:2.25rem;line-height:1.25rem;padding:0 .875rem}.pnt-business-select-popup .t-popup__content .total-wrapper{color:#808191;font-size:.875rem}.pnt-secure-box{color:#333;max-width:-moz-fit-content;max-width:fit-content;position:relative}.pnt-secure-box .view-icon{color:#3f8cff!important;cursor:pointer;font-size:small;position:absolute;right:-1.875rem;top:.0625rem}.pnt-secure-box .security-value{position:relative;top:.1875rem}.pnt-general-layout{--pnt-layout-body-padding:1.5rem;--pnt-layout-card-radius:0.25rem;background-color:transparent;height:100%}.pnt-general-layout .t-layout__header{align-items:stretch;border-bottom:.0625rem solid #f0f3f6;display:flex;flex-shrink:0;height:auto;justify-content:space-between}.pnt-general-layout .t-layout__header .header-title{align-items:center;display:inline-flex;padding:1.5rem}.pnt-general-layout .t-layout__header .header-title .goback-icon{color:#3f8cff;cursor:pointer;margin-right:.75rem}.pnt-general-layout .t-layout__header .header-title .title{font-size:1.25rem;font-weight:600;line-height:1.5rem}.pnt-general-layout .t-layout__header .header-operation{align-items:center;display:flex;padding-right:1.5rem}.pnt-general-layout .t-layout__header .header-operation .t-button+.t-button{margin-left:.75rem}.pnt-general-layout--borderless .t-layout__header{border-bottom:none}.pnt-general-layout .general-layout-sub-header{border-bottom:.0625rem solid #f0f3f6;flex-shrink:0}.pnt-general-layout .general-layout-body{background:#fafafa;flex:1 1 auto;min-height:0;overflow-y:auto;padding:var(--pnt-layout-body-padding)}.pnt-general-layout .general-layout-body>div.t-card,.pnt-general-layout .general-layout-body>div.t-loading__parent>div.t-card,.pnt-general-layout .general-layout-body>div.tea-card,.pnt-general-layout .general-layout-body>div[class*=-block],.pnt-general-layout .general-layout-body>div[class*=-wrapper]{border-radius:var(--pnt-layout-card-radius);box-shadow:none;margin-bottom:1.5rem}.pnt-general-layout .general-layout-body>div.t-card .t-card__body,.pnt-general-layout .general-layout-body>div.t-loading__parent>div.t-card .t-card__body,.pnt-general-layout .general-layout-body>div.tea-card .t-card__body,.pnt-general-layout .general-layout-body>div[class*=-block] .t-card__body,.pnt-general-layout .general-layout-body>div[class*=-wrapper] .t-card__body{border-radius:var(--pnt-layout-card-radius)}.pnt-general-layout .general-layout-body>div.t-loading__parent>div:last-child.t-card,.pnt-general-layout .general-layout-body>div:last-child,.pnt-general-layout .general-layout-body>div:last-child.t-card,.pnt-general-layout .general-layout-body>div:last-child.tea-card,.pnt-general-layout .general-layout-body>div:last-child[class*=-block],.pnt-general-layout .general-layout-body>div:last-child[class*=-wrapper]{margin-bottom:0}.pnt-general-layout .t-layout__footer{background:#fff;border-top:.0625rem solid #f0f3f6;flex-shrink:0;padding:1.125rem 1.5rem}.pnt-general-layout .t-layout__footer .t-button{font-size:.875rem;font-weight:600;height:2.25rem;min-width:5.75rem}.pnt-general-layout .t-layout__footer .t-button+.t-button{margin-left:.75rem}.pnt-general-layout--footer-auto .t-layout__footer .t-button{font-size:inherit;font-weight:inherit;height:auto;min-width:0}