forked from natuka/web.puabadge.com
修改:生图失败文案提示和用户头像调整
This commit is contained in:
1 parent
02d926e91e
commit
31754ef398
4 files changed
+72
-19
No files matched your search
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
@@ -1,5 +1,6 @@
|
|||||||
import logoAvatar from '@/assets/jingdong/logo-mark.png'
|
import logoAvatar from '@/assets/jingdong/logo-mark.png'
|
||||||
import logoIcon from '@/assets/jingdong/logo_1.png'
|
import logoIcon from '@/assets/jingdong/logo_1.png'
|
||||||
|
import userAvatar from '@/assets/jingdong/jingdong.png'
|
||||||
import caseOriginal from '@/assets/jingdong/原图.png'
|
import caseOriginal from '@/assets/jingdong/原图.png'
|
||||||
import caseEffect from '@/assets/jingdong/效果图.png'
|
import caseEffect from '@/assets/jingdong/效果图.png'
|
||||||
import caseScene from '@/assets/jingdong/场景图.png'
|
import caseScene from '@/assets/jingdong/场景图.png'
|
||||||
@@ -19,9 +20,11 @@ export const jingdongConfig = {
|
|||||||
background: '#F5F5F5',
|
background: '#F5F5F5',
|
||||||
|
|
||||||
images: {
|
images: {
|
||||||
/** 顶栏 / 对话头像 */
|
/** 顶栏 / Agent 对话头像 */
|
||||||
avatar: logoAvatar,
|
avatar: logoAvatar,
|
||||||
logo: logoAvatar,
|
logo: logoAvatar,
|
||||||
|
/** 用户侧对话头像 */
|
||||||
|
userAvatar,
|
||||||
/** 浏览器标签 favicon */
|
/** 浏览器标签 favicon */
|
||||||
logoIcon,
|
logoIcon,
|
||||||
caseOriginal,
|
caseOriginal,
|
||||||
@@ -74,5 +77,8 @@ export const jingdongConfig = {
|
|||||||
effectPreparing: '效果图准备中,请稍后再试',
|
effectPreparing: '效果图准备中,请稍后再试',
|
||||||
generateFail: '这次没生成成功,请换个描述或照片再试',
|
generateFail: '这次没生成成功,请换个描述或照片再试',
|
||||||
editFail: '这次调整没成功,请换个描述再试',
|
editFail: '这次调整没成功,请换个描述再试',
|
||||||
|
/** 内容安全策略拒绝(未成年 / 公众人物等) */
|
||||||
|
contentPolicyFail:
|
||||||
|
'当前照片不符合内容规范,可能涉及未成年或公众人物,请换一张照片再试',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
/** 将后端 / 网络 / 前端技术错误转成用户可读提示 */
|
/** 将后端 / 网络 / 前端技术错误转成用户可读提示 */
|
||||||
|
|
||||||
|
import { jingdongConfig } from '@/config/jingdong'
|
||||||
|
|
||||||
const KNOWN: Record<string, string> = {
|
const KNOWN: Record<string, string> = {
|
||||||
未登录: '登录已失效,请关闭后重新进入再试',
|
未登录: '登录已失效,请关闭后重新进入再试',
|
||||||
请求失败: '服务繁忙,请稍后重试',
|
请求失败: '服务繁忙,请稍后重试',
|
||||||
@@ -17,7 +19,7 @@ const KNOWN: Record<string, string> = {
|
|||||||
'签发上传地址失败:缺少 upload_url': '照片上传失败,请稍后重试',
|
'签发上传地址失败:缺少 upload_url': '照片上传失败,请稍后重试',
|
||||||
'获取 upload_id 失败': '照片上传失败,请稍后重试',
|
'获取 upload_id 失败': '照片上传失败,请稍后重试',
|
||||||
'upload/url 响应无法解析': '照片上传失败,请稍后重试',
|
'upload/url 响应无法解析': '照片上传失败,请稍后重试',
|
||||||
生成失败: '这次没生成成功,请换个描述或照片再试',
|
生成失败: jingdongConfig.messages.generateFail,
|
||||||
提交生成失败: '提交失败了,请稍后重试',
|
提交生成失败: '提交失败了,请稍后重试',
|
||||||
没有生成结果: '这次没有生成出效果图,请再试一次',
|
没有生成结果: '这次没有生成出效果图,请再试一次',
|
||||||
生成超时: '生成时间有点久,请稍后重试',
|
生成超时: '生成时间有点久,请稍后重试',
|
||||||
@@ -32,6 +34,32 @@ const KNOWN: Record<string, string> = {
|
|||||||
'product_id不在Agent开放分类': '当前产品暂不支持在线生图,请联系客服',
|
'product_id不在Agent开放分类': '当前产品暂不支持在线生图,请联系客服',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 生图 / 编辑:内容策略单独翻译;Processing/ApiError 走场景兜底文案 */
|
||||||
|
const GENERATE_EDIT_RULES: Array<{ test: RegExp; tipKey: 'contentPolicyFail' | 'processingFail' }> = [
|
||||||
|
{
|
||||||
|
test: /content\s*policy|minor|public\s*figure|recognizable\s*public/i,
|
||||||
|
tipKey: 'contentPolicyFail',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /processing\s*failed|ApiError/i,
|
||||||
|
tipKey: 'processingFail',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
/** 前端自抛、可原样映射的短文案(生图场景仍保留) */
|
||||||
|
const GENERATE_EDIT_KEEP = new Set([
|
||||||
|
'已取消生成',
|
||||||
|
'生成超时',
|
||||||
|
'生成超时,请稍后重试',
|
||||||
|
'提交生成失败',
|
||||||
|
'没有生成结果',
|
||||||
|
'请先上传照片',
|
||||||
|
'缺少可编辑的效果图',
|
||||||
|
'缺少会话信息,请刷新后重试',
|
||||||
|
'缺少产品信息,请刷新后重试',
|
||||||
|
'product_id不在Agent开放分类',
|
||||||
|
])
|
||||||
|
|
||||||
const PATTERN_RULES: Array<{ test: RegExp; tip: string }> = [
|
const PATTERN_RULES: Array<{ test: RegExp; tip: string }> = [
|
||||||
{ test: /timeout|超时|ETIMEDOUT|ECONNABORTED/i, tip: '等待超时,请稍后重试' },
|
{ test: /timeout|超时|ETIMEDOUT|ECONNABORTED/i, tip: '等待超时,请稍后重试' },
|
||||||
{ test: /network|fetch failed|ERR_NETWORK|断网|网络/i, tip: '网络异常,请检查网络后重试' },
|
{ test: /network|fetch failed|ERR_NETWORK|断网|网络/i, tip: '网络异常,请检查网络后重试' },
|
||||||
@@ -49,8 +77,8 @@ const PATTERN_RULES: Array<{ test: RegExp; tip: string }> = [
|
|||||||
export type FriendlyErrorScene = 'generate' | 'edit' | 'upload' | 'inspect' | 'download' | 'common'
|
export type FriendlyErrorScene = 'generate' | 'edit' | 'upload' | 'inspect' | 'download' | 'common'
|
||||||
|
|
||||||
const SCENE_FALLBACK: Record<FriendlyErrorScene, string> = {
|
const SCENE_FALLBACK: Record<FriendlyErrorScene, string> = {
|
||||||
generate: '这次没生成成功,请换个描述或照片再试',
|
generate: jingdongConfig.messages.generateFail,
|
||||||
edit: '这次调整没成功,请换个描述再试',
|
edit: jingdongConfig.messages.editFail,
|
||||||
upload: '照片上传失败,请换一张或稍后重试',
|
upload: '照片上传失败,请换一张或稍后重试',
|
||||||
inspect: '照片识别失败,请换一张或稍后重试',
|
inspect: '照片识别失败,请换一张或稍后重试',
|
||||||
download: '下载失败,请换用其他浏览器,或长按效果图保存',
|
download: '下载失败,请换用其他浏览器,或长按效果图保存',
|
||||||
@@ -86,11 +114,27 @@ function looksTechnical(text: string) {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mapGenerateEditError(text: string, tip: string): string {
|
||||||
|
for (const rule of GENERATE_EDIT_RULES) {
|
||||||
|
if (!rule.test.test(text)) continue
|
||||||
|
// 内容策略用专用文案;Processing/ApiError 与其它失败一样走场景兜底
|
||||||
|
if (rule.tipKey === 'contentPolicyFail') {
|
||||||
|
return jingdongConfig.messages.contentPolicyFail
|
||||||
|
}
|
||||||
|
return tip
|
||||||
|
}
|
||||||
|
if (GENERATE_EDIT_KEEP.has(text) && KNOWN[text]) return KNOWN[text]
|
||||||
|
for (const key of GENERATE_EDIT_KEEP) {
|
||||||
|
if (key.length >= 4 && text.includes(key) && KNOWN[key]) return KNOWN[key]
|
||||||
|
}
|
||||||
|
// 生图/编辑:未识别的后端英文或其它错误,统一兜底
|
||||||
|
return tip
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任意错误 → 友好中文提示。
|
* 任意错误 → 友好中文提示。
|
||||||
* - 优先命中已知文案 / 规则
|
* - 生图/编辑:仅内容策略、Processing/ApiError 单独翻译,其余走 generateFail / editFail
|
||||||
* - 短中文业务提示可原样展示
|
* - 其它场景:已知文案 / 规则优先,技术性内容回落默认文案
|
||||||
* - 技术性内容回落场景默认文案
|
|
||||||
*/
|
*/
|
||||||
export function friendlyError(
|
export function friendlyError(
|
||||||
error: unknown,
|
error: unknown,
|
||||||
@@ -101,6 +145,10 @@ export function friendlyError(
|
|||||||
const text = rawMessage(error)
|
const text = rawMessage(error)
|
||||||
if (!text) return tip
|
if (!text) return tip
|
||||||
|
|
||||||
|
if (scene === 'generate' || scene === 'edit') {
|
||||||
|
return mapGenerateEditError(text, tip)
|
||||||
|
}
|
||||||
|
|
||||||
if (KNOWN[text]) return KNOWN[text]
|
if (KNOWN[text]) return KNOWN[text]
|
||||||
|
|
||||||
for (const [key, value] of Object.entries(KNOWN)) {
|
for (const [key, value] of Object.entries(KNOWN)) {
|
||||||
|
|||||||
@@ -17,7 +17,9 @@
|
|||||||
<div v-if="msg.role === 'agent'" class="msg__avatar" aria-hidden="true">
|
<div v-if="msg.role === 'agent'" class="msg__avatar" aria-hidden="true">
|
||||||
<img :src="config.images.avatar" alt="" />
|
<img :src="config.images.avatar" alt="" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="msg__avatar msg__avatar--user" aria-hidden="true">柚</div>
|
<div v-else class="msg__avatar msg__avatar--user" aria-hidden="true">
|
||||||
|
<img :src="config.images.userAvatar" alt="" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="msg__body">
|
<div class="msg__body">
|
||||||
<div v-if="msg.type === 'text'" class="msg__bubble">
|
<div v-if="msg.type === 'text'" class="msg__bubble">
|
||||||
@@ -1143,15 +1145,12 @@ onBeforeUnmount(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.msg__avatar--user {
|
.msg__avatar--user {
|
||||||
display: inline-flex;
|
background: #ffffff;
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
img {
|
||||||
background: #3a8e4d;
|
object-fit: cover;
|
||||||
border: 0;
|
object-position: center;
|
||||||
color: #fff;
|
}
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 600;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.msg__body {
|
.msg__body {
|
||||||
@@ -1182,7 +1181,7 @@ onBeforeUnmount(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.msg.is-user .msg__bubble {
|
.msg.is-user .msg__bubble {
|
||||||
border-radius: 16px 16px 4px 16px;
|
border-radius: 16px 4px 16px 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.msg:not(.is-user) .msg__bubble {
|
.msg:not(.is-user) .msg__bubble {
|
||||||
@@ -1197,7 +1196,7 @@ onBeforeUnmount(() => {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
background: #f0f1f3;
|
background: #e9e9eb;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
color: #222;
|
color: #222;
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user