feat(order-service): 优化用户引导图配置与展示
This commit is contained in:
@@ -71,6 +71,7 @@ type OrderServiceFormValues = {
|
||||
name: string
|
||||
title: string
|
||||
description: string
|
||||
guideImageDescription: string
|
||||
submitText: string
|
||||
successText: string
|
||||
postSubmitText: string
|
||||
@@ -230,6 +231,14 @@ function buildPresetFields(keys: string[]) {
|
||||
})
|
||||
}
|
||||
|
||||
function resolveGuideImage(value: unknown): UploadedFile | null {
|
||||
if (!value || typeof value !== 'object' || Array.isArray(value)) return null
|
||||
const source = value as Record<string, unknown>
|
||||
const url = String(source.url || '').trim()
|
||||
const objectKey = String(source.objectKey || source.object_key || '').trim()
|
||||
return url || objectKey ? (value as UploadedFile) : null
|
||||
}
|
||||
|
||||
export default function OrderServicePanel() {
|
||||
const { message } = App.useApp()
|
||||
const queryClient = useQueryClient()
|
||||
@@ -275,7 +284,10 @@ export default function OrderServicePanel() {
|
||||
).length
|
||||
const selectedCategory = categories.find((item) => item.categoryId === selectedCategoryId) || null
|
||||
const profile = (selectedCategoryId ? profileByCategoryId.get(selectedCategoryId) : null) || null
|
||||
const guideFiles = useMemo(() => (guideImage ? [guideImage as UploadedFile] : []), [guideImage])
|
||||
const guideFiles = useMemo(() => {
|
||||
const image = resolveGuideImage(guideImage)
|
||||
return image ? [image] : []
|
||||
}, [guideImage])
|
||||
const handleGuideImageChange = useCallback((files: UploadedFile[]) => {
|
||||
setGuideImage(files[0] || null)
|
||||
}, [])
|
||||
@@ -302,6 +314,7 @@ export default function OrderServicePanel() {
|
||||
name: nextProfile?.name || selectedCategory?.name || '',
|
||||
title: nextProfile?.title || '',
|
||||
description: nextProfile?.description || '',
|
||||
guideImageDescription: nextProfile?.guideImageDescription || '',
|
||||
submitText: nextProfile?.submitText || '提交资料',
|
||||
successText: nextProfile?.successText || '资料已提交,请等待处理',
|
||||
postSubmitText: nextProfile?.postSubmitText || DEFAULT_POST_SUBMIT_TEXT,
|
||||
@@ -315,7 +328,7 @@ export default function OrderServicePanel() {
|
||||
nextProfile ? nextProfile.fields : buildPresetFields(GAME_BASIC_PRESET_KEYS),
|
||||
),
|
||||
)
|
||||
setGuideImage(nextProfile?.guideImage || null)
|
||||
setGuideImage(resolveGuideImage(nextProfile?.guideImage))
|
||||
}
|
||||
|
||||
async function refresh() {
|
||||
@@ -413,6 +426,7 @@ export default function OrderServicePanel() {
|
||||
title: values.title || '',
|
||||
description: values.description || '',
|
||||
guideImage: guideImage || {},
|
||||
guideImageDescription: values.guideImageDescription || '',
|
||||
fields: normalizedFields,
|
||||
screenshots: values.screenshots,
|
||||
autoPublish: values.autoPublish,
|
||||
@@ -652,7 +666,7 @@ export default function OrderServicePanel() {
|
||||
/>
|
||||
</div>
|
||||
<div className="order-service-basic-grid">
|
||||
<div>
|
||||
<div className="order-service-basic-fields">
|
||||
<Row gutter={[12, 0]}>
|
||||
<Col xs={24} md={12}>
|
||||
<Form.Item label="配置名称" name="name" rules={[{ required: true }]}>
|
||||
@@ -699,16 +713,36 @@ export default function OrderServicePanel() {
|
||||
</Row>
|
||||
</div>
|
||||
<div className="order-service-guide">
|
||||
<Text strong>用户引导图</Text>
|
||||
<Text type="secondary">首版一张,展示在字段上方</Text>
|
||||
<ImageUpload
|
||||
scene="order-service"
|
||||
scope="admin"
|
||||
maxCount={1}
|
||||
value={guideFiles}
|
||||
onChange={handleGuideImageChange}
|
||||
uploader={uploadGuideImage}
|
||||
/>
|
||||
<div className="order-service-guide-head">
|
||||
<Text strong>用户引导图</Text>
|
||||
<Text type="secondary">
|
||||
一张,显示在客户页“买家主页截图”上传区右侧,可点击放大查看
|
||||
</Text>
|
||||
</div>
|
||||
<div className="order-service-guide-upload">
|
||||
<ImageUpload
|
||||
scene="order-service"
|
||||
scope="admin"
|
||||
maxCount={1}
|
||||
value={guideFiles}
|
||||
onChange={handleGuideImageChange}
|
||||
uploader={uploadGuideImage}
|
||||
/>
|
||||
</div>
|
||||
<Form.Item
|
||||
className="order-service-guide-description"
|
||||
extra="选填,显示在引导图下方;建议说明截图范围或关键识别信息。"
|
||||
label="图片说明"
|
||||
name="guideImageDescription"
|
||||
>
|
||||
<Input.TextArea
|
||||
autoSize={{ minRows: 2, maxRows: 4 }}
|
||||
disabled={!guideImage}
|
||||
maxLength={200}
|
||||
placeholder="例如:请截取买家个人主页,并确认游戏 ID 清晰可见"
|
||||
showCount
|
||||
/>
|
||||
</Form.Item>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -601,6 +601,8 @@ function OrderServiceForm({
|
||||
label: '截图',
|
||||
helpText: '',
|
||||
}
|
||||
const guideImageUrl =
|
||||
item.guideImage && 'url' in item.guideImage ? String(item.guideImage.url || '').trim() : ''
|
||||
|
||||
return (
|
||||
<Card size="small" className="collect-link-order-card">
|
||||
@@ -618,14 +620,6 @@ function OrderServiceForm({
|
||||
{item.title ? <Title level={5}>{item.title}</Title> : null}
|
||||
{item.description ? <Text type="secondary">{item.description}</Text> : null}
|
||||
|
||||
{item.guideImage && 'url' in item.guideImage && item.guideImage.url ? (
|
||||
<img
|
||||
alt="填写引导图"
|
||||
src={String(item.guideImage.url)}
|
||||
style={{ width: '100%', borderRadius: 8 }}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{item.fields && item.fields.length > 0 ? (
|
||||
<Form layout="vertical" initialValues={item.values || {}} onFinish={onSubmit}>
|
||||
{item.fields.map((field) => (
|
||||
@@ -672,24 +666,47 @@ function OrderServiceForm({
|
||||
}
|
||||
extra={rule.helpText}
|
||||
>
|
||||
<ImageUpload
|
||||
scene="collect-material"
|
||||
scope="collect"
|
||||
maxCount={rule.maxCount}
|
||||
showPasteHint
|
||||
captureGlobalPaste
|
||||
value={screenshots}
|
||||
onChange={onScreenshotsChange}
|
||||
uploader={async (file, scene) => {
|
||||
const response = await uploadOrderServiceFile(
|
||||
file,
|
||||
scene,
|
||||
code,
|
||||
item.workOrderId,
|
||||
)
|
||||
return response.data.file
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
className={`collect-link-screenshot-control ${guideImageUrl ? 'has-guide' : ''}`}
|
||||
>
|
||||
<div className="collect-link-screenshot-upload">
|
||||
<ImageUpload
|
||||
scene="collect-material"
|
||||
scope="collect"
|
||||
maxCount={rule.maxCount}
|
||||
showPasteHint
|
||||
captureGlobalPaste
|
||||
value={screenshots}
|
||||
onChange={onScreenshotsChange}
|
||||
uploader={async (file, scene) => {
|
||||
const response = await uploadOrderServiceFile(
|
||||
file,
|
||||
scene,
|
||||
code,
|
||||
item.workOrderId,
|
||||
)
|
||||
return response.data.file
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{guideImageUrl ? (
|
||||
<aside className="collect-link-guide-example">
|
||||
<Image
|
||||
alt="买家主页截图填写示例"
|
||||
height={88}
|
||||
preview={{ mask: '查看大图' }}
|
||||
src={guideImageUrl}
|
||||
width={128}
|
||||
/>
|
||||
<div className="collect-link-guide-copy">
|
||||
<Text strong>截图填写参考</Text>
|
||||
<Text type="secondary">
|
||||
{item.guideImageDescription?.trim() || '点击图片可查看大图'}
|
||||
</Text>
|
||||
</div>
|
||||
</aside>
|
||||
) : null}
|
||||
</div>
|
||||
</Form.Item>
|
||||
) : null}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user