@skopon-cool/form-sdk 0.6.0 → 0.6.2
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/README.md +30 -2
- package/dist/adapter/formSchema.d.ts +3 -0
- package/dist/adapter/formSchema.d.ts.map +1 -1
- package/dist/blocks/resume_multiselect/adapter.d.ts.map +1 -1
- package/dist/catalog/contentSearchContext.d.ts +35 -0
- package/dist/catalog/contentSearchContext.d.ts.map +1 -0
- package/dist/catalog/pairResumeContent.d.ts +20 -0
- package/dist/catalog/pairResumeContent.d.ts.map +1 -0
- package/dist/catalog/skoponResumeSelect.d.ts.map +1 -1
- package/dist/client/authStorage.d.ts +9 -0
- package/dist/client/authStorage.d.ts.map +1 -1
- package/dist/client/contentSearchClient.d.ts +36 -0
- package/dist/client/contentSearchClient.d.ts.map +1 -0
- package/dist/client/resumeSearchClient.d.ts.map +1 -1
- package/dist/client/skoponSdkClients.d.ts +4 -0
- package/dist/client/skoponSdkClients.d.ts.map +1 -1
- package/dist/client/uploadClient.d.ts +1 -1
- package/dist/client/uploadClient.d.ts.map +1 -1
- package/dist/components/AskUserFormCard.d.ts +3 -0
- package/dist/components/AskUserFormCard.d.ts.map +1 -1
- package/dist/components/SkoponA2uiStreamRenderer.d.ts +4 -1
- package/dist/components/SkoponA2uiStreamRenderer.d.ts.map +1 -1
- package/dist/components/SkoponFormRenderer.d.ts +3 -0
- package/dist/components/SkoponFormRenderer.d.ts.map +1 -1
- package/dist/form-sdk.css +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1963 -1625
- package/dist/types/index.d.ts +25 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/adapter/formSchema.test.ts +8 -0
- package/src/adapter/formSchema.ts +49 -0
- package/src/blocks/resume_multiselect/adapter.ts +31 -0
- package/src/catalog/contentSearchContext.tsx +53 -0
- package/src/catalog/pairResumeContent.test.ts +34 -0
- package/src/catalog/pairResumeContent.ts +55 -0
- package/src/catalog/skoponResumeSelect.tsx +348 -153
- package/src/catalog/skoponSelectLoading.test.tsx +84 -5
- package/src/client/authStorage.test.ts +67 -1
- package/src/client/authStorage.ts +67 -0
- package/src/client/contentSearchClient.test.ts +123 -0
- package/src/client/contentSearchClient.ts +156 -0
- package/src/client/resumeSearchClient.test.ts +5 -0
- package/src/client/resumeSearchClient.ts +5 -0
- package/src/client/skoponSdkClients.ts +9 -0
- package/src/client/uploadClient.test.ts +41 -2
- package/src/client/uploadClient.ts +7 -3
- package/src/components/AskUserFormCard.tsx +5 -0
- package/src/components/SkoponA2uiStreamRenderer.tsx +15 -9
- package/src/components/SkoponFormRenderer.tsx +20 -12
- package/src/index.ts +19 -0
- package/src/styles/a2ui-preview.css +4 -4
- package/src/styles/index.css +158 -13
- package/src/submit/submit.test.ts +1 -0
- package/src/types/index.ts +26 -1
|
@@ -23,7 +23,13 @@ describe('uploadFileToCdn', () => {
|
|
|
23
23
|
})
|
|
24
24
|
|
|
25
25
|
it('uploads multipart data to the fixed endpoint with session Bearer auth', async () => {
|
|
26
|
-
sessionStorage.setItem(
|
|
26
|
+
sessionStorage.setItem(
|
|
27
|
+
'auth_user',
|
|
28
|
+
JSON.stringify({
|
|
29
|
+
token: 'token-1',
|
|
30
|
+
skopon_api_base_url: 'https://admin-test.hibot.lol/api/skopon/api/v1/',
|
|
31
|
+
}),
|
|
32
|
+
)
|
|
27
33
|
const fetchMock = vi.fn(async () =>
|
|
28
34
|
response({
|
|
29
35
|
success: true,
|
|
@@ -39,7 +45,9 @@ describe('uploadFileToCdn', () => {
|
|
|
39
45
|
})
|
|
40
46
|
expect(fetchMock).toHaveBeenCalledTimes(1)
|
|
41
47
|
const [url, init] = fetchMock.mock.calls[0] as unknown as [string, RequestInit]
|
|
42
|
-
expect(url).toBe(
|
|
48
|
+
expect(url).toBe(
|
|
49
|
+
`https://admin-test.hibot.lol/api/skopon/api/v1${CDN_UPLOAD_PATH}`,
|
|
50
|
+
)
|
|
43
51
|
expect(init.method).toBe('POST')
|
|
44
52
|
expect(init.headers).toEqual({ Authorization: 'Bearer token-1' })
|
|
45
53
|
expect((init.headers as Record<string, string>)['Content-Type']).toBeUndefined()
|
|
@@ -48,6 +56,37 @@ describe('uploadFileToCdn', () => {
|
|
|
48
56
|
expect((init.body as FormData).get('purpose')).toBeNull()
|
|
49
57
|
})
|
|
50
58
|
|
|
59
|
+
it('falls back to the current origin API base when session config is missing', async () => {
|
|
60
|
+
const fetchMock = vi.fn(async () =>
|
|
61
|
+
response({ success: true, data: { url: 'https://cdn.example.com/a.txt' } }),
|
|
62
|
+
)
|
|
63
|
+
vi.stubGlobal('fetch', fetchMock)
|
|
64
|
+
|
|
65
|
+
await uploadFileToCdn(new File(['x'], 'x.txt'))
|
|
66
|
+
|
|
67
|
+
expect(fetchMock).toHaveBeenCalledWith(
|
|
68
|
+
`${window.location.origin}/api/v1${CDN_UPLOAD_PATH}`,
|
|
69
|
+
expect.objectContaining({ method: 'POST' }),
|
|
70
|
+
)
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
it('rejects an invalid configured base URL without sending a request', async () => {
|
|
74
|
+
sessionStorage.setItem(
|
|
75
|
+
'auth_user',
|
|
76
|
+
JSON.stringify({
|
|
77
|
+
token: 'token-1',
|
|
78
|
+
skopon_api_base_url: '/api/v1',
|
|
79
|
+
}),
|
|
80
|
+
)
|
|
81
|
+
const fetchMock = vi.fn()
|
|
82
|
+
vi.stubGlobal('fetch', fetchMock)
|
|
83
|
+
|
|
84
|
+
await expect(uploadFileToCdn(new File(['x'], 'x.txt'))).rejects.toThrow(
|
|
85
|
+
'skopon_api_base_url 格式无效,无法上传文件',
|
|
86
|
+
)
|
|
87
|
+
expect(fetchMock).not.toHaveBeenCalled()
|
|
88
|
+
})
|
|
89
|
+
|
|
51
90
|
it.each([
|
|
52
91
|
[{ success: false, message: '七牛上传失败', data: {} }, '七牛上传失败'],
|
|
53
92
|
[{ success: true, data: { url: ' ' } }, '响应缺少文件地址'],
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { parseEnvelope } from './apiEnvelope'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
resolveSkoponApiBaseUrl,
|
|
4
|
+
resolveSkoponAuthHeaders,
|
|
5
|
+
} from './authStorage'
|
|
3
6
|
|
|
4
|
-
export const CDN_UPLOAD_PATH = '/
|
|
7
|
+
export const CDN_UPLOAD_PATH = '/univ/upload/cdn'
|
|
5
8
|
export const CDN_UPLOAD_TIMEOUT_MS = 120_000
|
|
6
9
|
|
|
7
10
|
export interface CdnUploadResult {
|
|
@@ -27,6 +30,7 @@ export async function uploadFileToCdn(
|
|
|
27
30
|
file: File,
|
|
28
31
|
options: { signal?: AbortSignal } = {},
|
|
29
32
|
): Promise<CdnUploadResult> {
|
|
33
|
+
const uploadUrl = `${resolveSkoponApiBaseUrl()}${CDN_UPLOAD_PATH}`
|
|
30
34
|
const controller = new AbortController()
|
|
31
35
|
let timedOut = false
|
|
32
36
|
|
|
@@ -45,7 +49,7 @@ export async function uploadFileToCdn(
|
|
|
45
49
|
try {
|
|
46
50
|
const formData = new FormData()
|
|
47
51
|
formData.append('file', file)
|
|
48
|
-
const response = await fetch(
|
|
52
|
+
const response = await fetch(uploadUrl, {
|
|
49
53
|
method: 'POST',
|
|
50
54
|
headers: resolveSkoponAuthHeaders(),
|
|
51
55
|
body: formData,
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
} from '../submit/submitAnswerAgent'
|
|
28
28
|
import { validateFormSubmitValues } from '../submit/validateFormSubmit'
|
|
29
29
|
import type { CaseSearchFn } from '../catalog/caseSearchContext'
|
|
30
|
+
import type { ContentSearchFn } from '../catalog/contentSearchContext'
|
|
30
31
|
import type { ResumeSearchFn } from '../catalog/resumeSearchContext'
|
|
31
32
|
import { FormRuntimeProvider, useFormRuntime } from '../runtime/formRuntimeContext'
|
|
32
33
|
import { FormRuntimeWsClient } from '../runtime/formRuntimeWs'
|
|
@@ -75,6 +76,8 @@ export interface AskUserFormCardProps {
|
|
|
75
76
|
onNotify?: (type: 'success' | 'error', message: string) => void
|
|
76
77
|
/** 简历多选组件:注入搜索函数 */
|
|
77
78
|
resumeSearch?: ResumeSearchFn | null
|
|
79
|
+
/** 简历多选组件:内容制作搜索 */
|
|
80
|
+
contentSearch?: ContentSearchFn | null
|
|
78
81
|
/** 案例单选组件:注入搜索函数 */
|
|
79
82
|
caseSearch?: CaseSearchFn | null
|
|
80
83
|
}
|
|
@@ -95,6 +98,7 @@ function AskUserFormCardBody({
|
|
|
95
98
|
fetchFormDetail,
|
|
96
99
|
onNotify,
|
|
97
100
|
resumeSearch = null,
|
|
101
|
+
contentSearch = null,
|
|
98
102
|
caseSearch = null,
|
|
99
103
|
onSurfaceReadyChange,
|
|
100
104
|
onAutoControlReady,
|
|
@@ -491,6 +495,7 @@ function AskUserFormCardBody({
|
|
|
491
495
|
interactive
|
|
492
496
|
wrapProvider={false}
|
|
493
497
|
resumeSearch={resumeSearch}
|
|
498
|
+
contentSearch={contentSearch}
|
|
494
499
|
caseSearch={caseSearch}
|
|
495
500
|
onUploadingChange={setUploading}
|
|
496
501
|
/>
|
|
@@ -7,6 +7,7 @@ import { buildSkoponCatalog } from '../catalog/a2uiCustomCatalog'
|
|
|
7
7
|
import { A2uiPreviewModeProvider } from '../catalog/a2uiPreviewContext'
|
|
8
8
|
import { FileUploadStatusProvider } from '../catalog/fileUploadStatusContext'
|
|
9
9
|
import { CaseSearchProvider, type CaseSearchFn } from '../catalog/caseSearchContext'
|
|
10
|
+
import { ContentSearchProvider, type ContentSearchFn } from '../catalog/contentSearchContext'
|
|
10
11
|
import { ResumeSearchProvider, type ResumeSearchFn } from '../catalog/resumeSearchContext'
|
|
11
12
|
import SkoponFormProvider from './SkoponFormProvider'
|
|
12
13
|
|
|
@@ -18,6 +19,8 @@ export interface SkoponA2uiStreamRendererProps {
|
|
|
18
19
|
interactive?: boolean
|
|
19
20
|
/** 简历多选组件:注入搜索函数 */
|
|
20
21
|
resumeSearch?: ResumeSearchFn | null
|
|
22
|
+
/** 简历多选组件:内容制作搜索 */
|
|
23
|
+
contentSearch?: ContentSearchFn | null
|
|
21
24
|
/** 案例单选组件:注入搜索函数 */
|
|
22
25
|
caseSearch?: CaseSearchFn | null
|
|
23
26
|
}
|
|
@@ -32,6 +35,7 @@ export default function SkoponA2uiStreamRenderer({
|
|
|
32
35
|
emptyHint = null,
|
|
33
36
|
interactive = true,
|
|
34
37
|
resumeSearch = null,
|
|
38
|
+
contentSearch = null,
|
|
35
39
|
caseSearch = null,
|
|
36
40
|
}: SkoponA2uiStreamRendererProps) {
|
|
37
41
|
useEffect(() => {
|
|
@@ -185,15 +189,17 @@ export default function SkoponA2uiStreamRenderer({
|
|
|
185
189
|
<SkoponFormProvider>
|
|
186
190
|
<FileUploadStatusProvider>
|
|
187
191
|
<ResumeSearchProvider resumeSearch={resumeSearch}>
|
|
188
|
-
<
|
|
189
|
-
<
|
|
190
|
-
<
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
192
|
+
<ContentSearchProvider contentSearch={contentSearch}>
|
|
193
|
+
<CaseSearchProvider caseSearch={caseSearch}>
|
|
194
|
+
<A2uiPreviewModeProvider interactive={interactive}>
|
|
195
|
+
<div className="a2ui-surface a2ui-container">
|
|
196
|
+
{surfaces.map((surface) => (
|
|
197
|
+
<A2uiSurface key={surface.id} surface={surface} />
|
|
198
|
+
))}
|
|
199
|
+
</div>
|
|
200
|
+
</A2uiPreviewModeProvider>
|
|
201
|
+
</CaseSearchProvider>
|
|
202
|
+
</ContentSearchProvider>
|
|
197
203
|
</ResumeSearchProvider>
|
|
198
204
|
</FileUploadStatusProvider>
|
|
199
205
|
</SkoponFormProvider>
|
|
@@ -17,6 +17,7 @@ import { SKOPON_CATALOG_ID, buildSkoponCatalog } from '../catalog/a2uiCustomCata
|
|
|
17
17
|
import { A2uiPreviewModeProvider } from '../catalog/a2uiPreviewContext'
|
|
18
18
|
import { FileUploadStatusProvider } from '../catalog/fileUploadStatusContext'
|
|
19
19
|
import { CaseSearchProvider, type CaseSearchFn } from '../catalog/caseSearchContext'
|
|
20
|
+
import { ContentSearchProvider, type ContentSearchFn } from '../catalog/contentSearchContext'
|
|
20
21
|
import { ResumeSearchProvider, type ResumeSearchFn } from '../catalog/resumeSearchContext'
|
|
21
22
|
import SkoponFormProvider from './SkoponFormProvider'
|
|
22
23
|
|
|
@@ -34,6 +35,8 @@ export interface SkoponFormRendererProps {
|
|
|
34
35
|
fieldNames?: string[]
|
|
35
36
|
/** 简历多选组件:注入搜索函数 */
|
|
36
37
|
resumeSearch?: ResumeSearchFn | null
|
|
38
|
+
/** 简历多选组件:内容制作搜索 */
|
|
39
|
+
contentSearch?: ContentSearchFn | null
|
|
37
40
|
/** 案例单选组件:注入搜索函数 */
|
|
38
41
|
caseSearch?: CaseSearchFn | null
|
|
39
42
|
/** 任意文件上传任务的聚合状态 */
|
|
@@ -51,6 +54,7 @@ const SkoponFormRenderer = forwardRef<SkoponFormRendererRef, SkoponFormRendererP
|
|
|
51
54
|
interactive = true,
|
|
52
55
|
fieldNames = [],
|
|
53
56
|
resumeSearch = null,
|
|
57
|
+
contentSearch = null,
|
|
54
58
|
caseSearch = null,
|
|
55
59
|
onUploadingChange,
|
|
56
60
|
wrapProvider = true,
|
|
@@ -128,9 +132,11 @@ const SkoponFormRenderer = forwardRef<SkoponFormRendererRef, SkoponFormRendererP
|
|
|
128
132
|
const empty = (
|
|
129
133
|
<FileUploadStatusProvider onUploadingChange={onUploadingChange}>
|
|
130
134
|
<ResumeSearchProvider resumeSearch={resumeSearch}>
|
|
131
|
-
<
|
|
132
|
-
<
|
|
133
|
-
|
|
135
|
+
<ContentSearchProvider contentSearch={contentSearch}>
|
|
136
|
+
<CaseSearchProvider caseSearch={caseSearch}>
|
|
137
|
+
<A2uiPreviewModeProvider interactive={interactive}>{emptyHint}</A2uiPreviewModeProvider>
|
|
138
|
+
</CaseSearchProvider>
|
|
139
|
+
</ContentSearchProvider>
|
|
134
140
|
</ResumeSearchProvider>
|
|
135
141
|
</FileUploadStatusProvider>
|
|
136
142
|
)
|
|
@@ -140,15 +146,17 @@ const SkoponFormRenderer = forwardRef<SkoponFormRendererRef, SkoponFormRendererP
|
|
|
140
146
|
const content = (
|
|
141
147
|
<FileUploadStatusProvider onUploadingChange={onUploadingChange}>
|
|
142
148
|
<ResumeSearchProvider resumeSearch={resumeSearch}>
|
|
143
|
-
<
|
|
144
|
-
<
|
|
145
|
-
<
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
149
|
+
<ContentSearchProvider contentSearch={contentSearch}>
|
|
150
|
+
<CaseSearchProvider caseSearch={caseSearch}>
|
|
151
|
+
<A2uiPreviewModeProvider interactive={interactive}>
|
|
152
|
+
<div className="a2ui-surface a2ui-container">
|
|
153
|
+
{surfaces.map((surface) => (
|
|
154
|
+
<A2uiSurface key={surface.id} surface={surface} />
|
|
155
|
+
))}
|
|
156
|
+
</div>
|
|
157
|
+
</A2uiPreviewModeProvider>
|
|
158
|
+
</CaseSearchProvider>
|
|
159
|
+
</ContentSearchProvider>
|
|
152
160
|
</ResumeSearchProvider>
|
|
153
161
|
</FileUploadStatusProvider>
|
|
154
162
|
)
|
package/src/index.ts
CHANGED
|
@@ -8,6 +8,7 @@ export type {
|
|
|
8
8
|
FormBlockOption,
|
|
9
9
|
FormBlockType,
|
|
10
10
|
FormCaseFilter,
|
|
11
|
+
FormContentFilter,
|
|
11
12
|
FormConditionOperator,
|
|
12
13
|
FormDefinitionPayload,
|
|
13
14
|
FormDetailResult,
|
|
@@ -106,6 +107,7 @@ export {
|
|
|
106
107
|
export {
|
|
107
108
|
resolveAnswerAgentCallbackUrl,
|
|
108
109
|
resolveRealtimeWsUrl,
|
|
110
|
+
resolveSkoponApiBaseUrl,
|
|
109
111
|
resolveSkoponAuthHeaders,
|
|
110
112
|
resolveSubmitAuthHeaders,
|
|
111
113
|
resolveClientHeaders,
|
|
@@ -113,7 +115,9 @@ export {
|
|
|
113
115
|
DEFAULT_AUTH_TOKEN_FIELD,
|
|
114
116
|
DEFAULT_AUTH_ANSWER_AGENT_CALLBACK_URL_FIELD,
|
|
115
117
|
DEFAULT_AUTH_REALTIME_WS_URL_FIELD,
|
|
118
|
+
DEFAULT_AUTH_SKOPON_API_BASE_URL_FIELD,
|
|
116
119
|
DEFAULT_ANSWER_AGENT_CALLBACK_URL,
|
|
120
|
+
DEFAULT_SKOPON_API_BASE_PATH,
|
|
117
121
|
type SkoponAuthStorageOptions,
|
|
118
122
|
type ClientHeadersOptions,
|
|
119
123
|
} from './client/authStorage'
|
|
@@ -121,6 +125,11 @@ export {
|
|
|
121
125
|
createResumeSearchClient,
|
|
122
126
|
type ResumeSearchClientOptions,
|
|
123
127
|
} from './client/resumeSearchClient'
|
|
128
|
+
export {
|
|
129
|
+
createContentSearchClient,
|
|
130
|
+
DEFAULT_CONTENT_FLOW_TYPE,
|
|
131
|
+
type ContentSearchClientOptions,
|
|
132
|
+
} from './client/contentSearchClient'
|
|
124
133
|
export {
|
|
125
134
|
createCaseSearchClient,
|
|
126
135
|
type CaseSearchClientOptions,
|
|
@@ -134,6 +143,7 @@ export {
|
|
|
134
143
|
export { default as SkoponFormRenderer } from './components/SkoponFormRenderer'
|
|
135
144
|
export type { SkoponFormRendererProps, SkoponFormRendererRef } from './components/SkoponFormRenderer'
|
|
136
145
|
export type { ResumeSearchFn as SkoponResumeSearchFn } from './catalog/resumeSearchContext'
|
|
146
|
+
export type { ContentSearchFn as SkoponContentSearchFn } from './catalog/contentSearchContext'
|
|
137
147
|
export type { CaseSearchFn as SkoponCaseSearchFn } from './catalog/caseSearchContext'
|
|
138
148
|
|
|
139
149
|
export { default as SkoponA2uiStreamRenderer } from './components/SkoponA2uiStreamRenderer'
|
|
@@ -152,6 +162,15 @@ export { antdTheme as skoponAntdTheme } from './theme/antd-theme'
|
|
|
152
162
|
export { brandColors as skoponBrandColors } from './theme/brand-colors'
|
|
153
163
|
|
|
154
164
|
|
|
165
|
+
export {
|
|
166
|
+
ContentSearchProvider,
|
|
167
|
+
useContentSearch,
|
|
168
|
+
type ContentSearchFn,
|
|
169
|
+
type ContentSearchItem,
|
|
170
|
+
type ContentSearchParams,
|
|
171
|
+
type ContentSearchResult,
|
|
172
|
+
} from './catalog/contentSearchContext'
|
|
173
|
+
|
|
155
174
|
export {
|
|
156
175
|
ResumeSearchProvider,
|
|
157
176
|
useResumeSearch,
|
|
@@ -255,7 +255,7 @@
|
|
|
255
255
|
}
|
|
256
256
|
|
|
257
257
|
/* 原生 A2UI 按钮/chip;勿作用于 Ant Design(Switch、Select、Picker 等)及 Skopon 简历/案例卡片 */
|
|
258
|
-
.a2ui-surface.a2ui-container button:not([class*='ant-']):not(.skopon-resume-select-card) {
|
|
258
|
+
.a2ui-surface.a2ui-container button:not([class*='ant-']):not(.skopon-resume-select-card):not(.skopon-resume-select-card-stage-button) {
|
|
259
259
|
min-height: var(--button-height-md);
|
|
260
260
|
padding: 0 var(--button-padding-x-md);
|
|
261
261
|
font-family: var(--font-sans);
|
|
@@ -273,12 +273,12 @@
|
|
|
273
273
|
color var(--duration-fast) var(--ease-default);
|
|
274
274
|
}
|
|
275
275
|
|
|
276
|
-
.a2ui-surface.a2ui-container button:not([class*='ant-']):not(.skopon-resume-select-card):hover:not(:disabled) {
|
|
276
|
+
.a2ui-surface.a2ui-container button:not([class*='ant-']):not(.skopon-resume-select-card):not(.skopon-resume-select-card-stage-button):hover:not(:disabled) {
|
|
277
277
|
border-color: var(--color-border-strong);
|
|
278
278
|
background: var(--color-bg-subtle);
|
|
279
279
|
}
|
|
280
280
|
|
|
281
|
-
.a2ui-surface.a2ui-container button:not([class*='ant-']):not(.skopon-resume-select-card):disabled {
|
|
281
|
+
.a2ui-surface.a2ui-container button:not([class*='ant-']):not(.skopon-resume-select-card):not(.skopon-resume-select-card-stage-button):disabled {
|
|
282
282
|
cursor: not-allowed;
|
|
283
283
|
opacity: 0.45;
|
|
284
284
|
}
|
|
@@ -313,7 +313,7 @@
|
|
|
313
313
|
color: var(--color-danger-text) !important;
|
|
314
314
|
}
|
|
315
315
|
|
|
316
|
-
.a2ui-surface.a2ui-container img:not(.form-media-item) {
|
|
316
|
+
.a2ui-surface.a2ui-container img:not(.form-media-item):not(.skopon-resume-select-card-cover-img) {
|
|
317
317
|
max-width: 100%;
|
|
318
318
|
height: auto;
|
|
319
319
|
border-radius: var(--radius-md);
|
package/src/styles/index.css
CHANGED
|
@@ -286,6 +286,7 @@
|
|
|
286
286
|
display: flex;
|
|
287
287
|
flex-direction: row;
|
|
288
288
|
flex-wrap: nowrap;
|
|
289
|
+
align-items: flex-start;
|
|
289
290
|
gap: var(--space-3, 12px);
|
|
290
291
|
margin-top: var(--space-2, 8px);
|
|
291
292
|
overflow-x: auto;
|
|
@@ -316,19 +317,163 @@
|
|
|
316
317
|
}
|
|
317
318
|
.skopon-resume-select-card--profile {
|
|
318
319
|
flex-direction: column;
|
|
319
|
-
align-items:
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
320
|
+
align-items: stretch;
|
|
321
|
+
align-self: flex-start;
|
|
322
|
+
gap: 8px;
|
|
323
|
+
width: 240px;
|
|
324
|
+
min-width: 240px;
|
|
325
|
+
max-width: 240px;
|
|
326
|
+
height: fit-content;
|
|
327
|
+
min-height: 0;
|
|
328
|
+
max-height: none;
|
|
329
|
+
padding: 12px;
|
|
330
|
+
overflow: hidden;
|
|
331
|
+
border-radius: 8px;
|
|
332
|
+
}
|
|
333
|
+
.skopon-resume-select-card--disabled {
|
|
334
|
+
cursor: not-allowed;
|
|
335
|
+
opacity: 0.72;
|
|
336
|
+
}
|
|
337
|
+
.skopon-resume-select-card-person {
|
|
338
|
+
display: flex;
|
|
339
|
+
align-items: flex-start;
|
|
340
|
+
gap: 8px;
|
|
341
|
+
min-width: 0;
|
|
342
|
+
}
|
|
343
|
+
.skopon-resume-select-card-person-text {
|
|
344
|
+
flex: 1;
|
|
345
|
+
min-width: 0;
|
|
346
|
+
}
|
|
347
|
+
.skopon-resume-select-card-person-name {
|
|
348
|
+
font-size: 14px;
|
|
349
|
+
font-weight: 600;
|
|
350
|
+
line-height: 1.3;
|
|
351
|
+
text-align: left;
|
|
352
|
+
color: var(--color-text, rgba(0, 0, 0, 0.88));
|
|
353
|
+
overflow: hidden;
|
|
354
|
+
text-overflow: ellipsis;
|
|
355
|
+
white-space: nowrap;
|
|
356
|
+
}
|
|
357
|
+
.skopon-resume-select-card-specialties {
|
|
358
|
+
display: flex;
|
|
359
|
+
flex-wrap: wrap;
|
|
360
|
+
gap: 4px;
|
|
361
|
+
margin-top: 4px;
|
|
362
|
+
}
|
|
363
|
+
.skopon-resume-select-card-content-title {
|
|
364
|
+
flex: none;
|
|
365
|
+
margin: 0;
|
|
366
|
+
padding: 0;
|
|
367
|
+
font-size: 13px;
|
|
368
|
+
font-weight: 500;
|
|
369
|
+
line-height: 1.4;
|
|
370
|
+
text-align: left;
|
|
371
|
+
color: var(--color-text, rgba(0, 0, 0, 0.88));
|
|
372
|
+
display: -webkit-box;
|
|
373
|
+
-webkit-line-clamp: 2;
|
|
374
|
+
-webkit-box-orient: vertical;
|
|
327
375
|
overflow: hidden;
|
|
328
376
|
}
|
|
329
|
-
.
|
|
330
|
-
|
|
331
|
-
|
|
377
|
+
.skopon-resume-select-card-content-tags {
|
|
378
|
+
display: flex;
|
|
379
|
+
flex-direction: column;
|
|
380
|
+
gap: 4px;
|
|
381
|
+
min-width: 0;
|
|
382
|
+
}
|
|
383
|
+
.skopon-resume-select-card-content-tags-label {
|
|
384
|
+
color: var(--color-text-secondary, rgba(0, 0, 0, 0.45));
|
|
385
|
+
font-size: 11px;
|
|
386
|
+
line-height: 1.2;
|
|
387
|
+
}
|
|
388
|
+
.skopon-resume-select-card-content-tags-list {
|
|
389
|
+
display: flex;
|
|
390
|
+
flex-wrap: wrap;
|
|
391
|
+
gap: 4px;
|
|
392
|
+
}
|
|
393
|
+
.skopon-resume-select-card-content-tag {
|
|
394
|
+
margin: 0;
|
|
395
|
+
border-color: color-mix(in srgb, var(--color-primary, #208368) 24%, transparent);
|
|
396
|
+
background: color-mix(in srgb, var(--color-primary, #208368) 8%, transparent);
|
|
397
|
+
color: var(--color-primary, #208368);
|
|
398
|
+
font-size: 11px;
|
|
399
|
+
line-height: 18px;
|
|
400
|
+
}
|
|
401
|
+
.skopon-resume-select-card-stage {
|
|
402
|
+
position: relative;
|
|
403
|
+
flex: none;
|
|
404
|
+
align-self: stretch;
|
|
405
|
+
width: 100%;
|
|
406
|
+
height: auto;
|
|
407
|
+
aspect-ratio: 9 / 16;
|
|
408
|
+
margin: 0;
|
|
409
|
+
padding: 0;
|
|
410
|
+
overflow: hidden;
|
|
411
|
+
border-radius: 6px;
|
|
412
|
+
background: #111;
|
|
413
|
+
}
|
|
414
|
+
.skopon-resume-select-card-stage-button,
|
|
415
|
+
.skopon-resume-select-card-stage-video {
|
|
416
|
+
position: absolute;
|
|
417
|
+
top: 0;
|
|
418
|
+
right: 0;
|
|
419
|
+
bottom: 0;
|
|
420
|
+
left: 0;
|
|
421
|
+
display: block;
|
|
422
|
+
width: 100%;
|
|
423
|
+
height: 100%;
|
|
424
|
+
margin: 0;
|
|
425
|
+
padding: 0;
|
|
426
|
+
border: 0;
|
|
427
|
+
border-radius: 0;
|
|
428
|
+
background: #111;
|
|
429
|
+
cursor: pointer;
|
|
430
|
+
overflow: hidden;
|
|
431
|
+
}
|
|
432
|
+
.skopon-resume-select-card-stage-button:disabled {
|
|
433
|
+
cursor: default;
|
|
434
|
+
}
|
|
435
|
+
.a2ui-surface.a2ui-container .skopon-resume-select-card-stage img.skopon-resume-select-card-cover-img,
|
|
436
|
+
.a2ui-surface.a2ui-container .skopon-resume-select-card-stage video.skopon-resume-select-card-stage-video,
|
|
437
|
+
.skopon-resume-select-card-stage img.skopon-resume-select-card-cover-img,
|
|
438
|
+
.skopon-resume-select-card-stage video.skopon-resume-select-card-stage-video {
|
|
439
|
+
position: absolute;
|
|
440
|
+
top: 0;
|
|
441
|
+
right: 0;
|
|
442
|
+
bottom: 0;
|
|
443
|
+
left: 0;
|
|
444
|
+
display: block;
|
|
445
|
+
width: 100%;
|
|
446
|
+
height: 100%;
|
|
447
|
+
max-width: none;
|
|
448
|
+
max-height: none;
|
|
449
|
+
margin: 0;
|
|
450
|
+
border-radius: 0;
|
|
451
|
+
object-fit: cover;
|
|
452
|
+
object-position: center;
|
|
453
|
+
}
|
|
454
|
+
.skopon-resume-select-card-cover-placeholder {
|
|
455
|
+
position: absolute;
|
|
456
|
+
left: 50%;
|
|
457
|
+
top: 50%;
|
|
458
|
+
font-size: 22px;
|
|
459
|
+
color: rgba(255, 255, 255, 0.45);
|
|
460
|
+
transform: translate(-50%, -50%);
|
|
461
|
+
}
|
|
462
|
+
.skopon-resume-select-card-play {
|
|
463
|
+
position: absolute;
|
|
464
|
+
left: 50%;
|
|
465
|
+
top: 50%;
|
|
466
|
+
display: flex;
|
|
467
|
+
align-items: center;
|
|
468
|
+
justify-content: center;
|
|
469
|
+
width: 36px;
|
|
470
|
+
height: 36px;
|
|
471
|
+
margin: -18px 0 0 -18px;
|
|
472
|
+
border-radius: 50%;
|
|
473
|
+
background: rgba(0, 0, 0, 0.55);
|
|
474
|
+
color: #fff;
|
|
475
|
+
font-size: 16px;
|
|
476
|
+
pointer-events: none;
|
|
332
477
|
}
|
|
333
478
|
.skopon-resume-select-card:not(.skopon-resume-select-card--profile) {
|
|
334
479
|
flex-direction: row;
|
|
@@ -342,7 +487,6 @@
|
|
|
342
487
|
}
|
|
343
488
|
.skopon-resume-select-card--selected {
|
|
344
489
|
border-color: var(--color-primary, #208368);
|
|
345
|
-
background: color-mix(in srgb, var(--color-primary, #208368) 8%, transparent);
|
|
346
490
|
}
|
|
347
491
|
.skopon-resume-select-card:disabled {
|
|
348
492
|
cursor: not-allowed;
|
|
@@ -352,7 +496,8 @@
|
|
|
352
496
|
flex-shrink: 0;
|
|
353
497
|
}
|
|
354
498
|
.skopon-resume-select-card--profile .skopon-resume-select-card-avatar {
|
|
355
|
-
margin
|
|
499
|
+
margin: 0;
|
|
500
|
+
flex-shrink: 0;
|
|
356
501
|
}
|
|
357
502
|
.skopon-resume-select-card-name {
|
|
358
503
|
font-weight: 600;
|
package/src/types/index.ts
CHANGED
|
@@ -99,13 +99,32 @@ export interface FormBlockCondition {
|
|
|
99
99
|
/** 简历多选组件:渲染时用于 /univ/resume/search 的筛选条件 */
|
|
100
100
|
export interface FormResumeFilter {
|
|
101
101
|
names?: string[]
|
|
102
|
-
/**
|
|
102
|
+
/**
|
|
103
|
+
* 智能体类型 unique_id。
|
|
104
|
+
* 运行时作为 agent_type:先找出该类型的智能体,再查他们的简历。
|
|
105
|
+
*/
|
|
103
106
|
agentKind?: string
|
|
104
107
|
agentUniqueIds?: string[]
|
|
108
|
+
/** 智能体标签 unique_id,多值 AND;与 agentKind 一起定位智能体后再查简历 */
|
|
109
|
+
tagUniqueIds?: string[]
|
|
105
110
|
resumeUniqueIds?: string[]
|
|
106
111
|
pageSize?: number
|
|
107
112
|
}
|
|
108
113
|
|
|
114
|
+
/** 内容制作搜索:渲染时用于 /univ/flow/list?owner_scope=content */
|
|
115
|
+
export interface FormContentFilter {
|
|
116
|
+
/** 流程类型 unique_id,默认 content-production */
|
|
117
|
+
flowType?: string
|
|
118
|
+
/** 流程类别 unique_id */
|
|
119
|
+
category?: string
|
|
120
|
+
/** 内容标签 unique_id */
|
|
121
|
+
tagUniqueIds?: string[]
|
|
122
|
+
/** 多标签匹配方式;all=全部命中,any=命中任一 */
|
|
123
|
+
tagMatch?: 'all' | 'any'
|
|
124
|
+
/** 每次向内容接口请求的条数,不是一屏展示张数 */
|
|
125
|
+
pageSize?: number
|
|
126
|
+
}
|
|
127
|
+
|
|
109
128
|
/** 案例多选组件:渲染时用于 /univ/case/list 的筛选条件 */
|
|
110
129
|
export interface FormCaseFilter {
|
|
111
130
|
/** Agent 类型(编辑器辅助,运行时不用) */
|
|
@@ -155,8 +174,14 @@ export interface FormBlock {
|
|
|
155
174
|
resumeMinCount?: number
|
|
156
175
|
/** 简历多选:最多选中数量,配置值 ≥ 1 */
|
|
157
176
|
resumeMaxCount?: number
|
|
177
|
+
/** 简历多选:一轮展示几张,默认 5。不是最多可选数,也不是接口 page_size */
|
|
178
|
+
/** content-only 仅选内容,提交 flow_unique_id;默认仍为简历与内容组合。 */
|
|
179
|
+
resumeDisplayMode?: 'profile-content' | 'content-only'
|
|
180
|
+
resumeDisplayCount?: number
|
|
158
181
|
/** 简历多选:列表筛选条件(持久化进 block json) */
|
|
159
182
|
resumeFilter?: FormResumeFilter
|
|
183
|
+
/** 简历多选:内容制作筛选(持久化进 block json) */
|
|
184
|
+
contentFilter?: FormContentFilter
|
|
160
185
|
/** 案例单选:是否显示「换一批」 */
|
|
161
186
|
caseEnableRefresh?: boolean
|
|
162
187
|
/** 案例多选:最少选中数量,配置值 ≥ 1 */
|