Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
admin
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
61bf6fb8
authored
Jul 09, 2024
by
YunaiV
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
【代码优化】AI:绘图 index.vue 代码梳理 60%(StableDiffusion.vue)
parent
ac46a376
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
310 additions
and
238 deletions
+310
-238
src/api/ai/image/index.ts
+3
-3
src/views/ai/image/index/components/ImageDetail.vue
+75
-7
src/views/ai/image/index/components/stableDiffusion/index.vue
+58
-224
src/views/ai/image/index/index.vue
+3
-3
src/views/ai/utils/constants.ts
+170
-0
src/views/ai/utils/utils.ts
+1
-1
No files found.
src/api/ai/image/index.ts
View file @
61bf6fb8
...
...
@@ -12,11 +12,11 @@ export interface ImageVO {
publicStatus
:
boolean
// 公开状态
picUrl
:
string
// 任务地址
errorMessage
:
string
// 错误信息
options
:
object
// 配置 Map<string, string>
options
:
any
// 配置 Map<string, string>
taskId
:
number
// 任务编号
buttons
:
ImageMidjourneyButtonsVO
[]
// mj 操作按钮
createTime
:
string
// 创建时间
finishTime
:
string
// 完成时间
createTime
:
Date
// 创建时间
finishTime
:
Date
// 完成时间
}
export
interface
ImageDrawReqVO
{
...
...
src/views/ai/image/index/components/ImageDetail.vue
View file @
61bf6fb8
...
...
@@ -20,8 +20,8 @@
<div
class=
"item"
>
<div
class=
"tip"
>
时间
</div>
<div
class=
"body"
>
<div>
提交时间:
{{
detail
.
createTime
}}
</div>
<div>
生成时间:
{{
detail
.
finishTime
}}
</div>
<div>
提交时间:
{{
formatTime
(
detail
.
createTime
,
'yyyy-MM-dd HH:mm:ss'
)
}}
</div>
<div>
生成时间:
{{
formatTime
(
detail
.
finishTime
,
'yyyy-MM-dd HH:mm:ss'
)
}}
</div>
</div>
</div>
<!-- 模型 -->
...
...
@@ -43,13 +43,73 @@
{{
detail
.
picUrl
}}
</div>
</div>
<!-- 风格 -->
<div
class=
"item"
v-if=
"detail?.options?.style"
>
<!-- StableDiffusion 专属区域 -->
<div
class=
"item"
v-if=
"detail.platform === AiPlatformEnum.STABLE_DIFFUSION && detail?.options?.sampler"
>
<div
class=
"tip"
>
采样方法
</div>
<div
class=
"body"
>
{{
StableDiffusionSamplers
.
find
(
(
item
:
ImageModelVO
)
=>
item
.
key
===
detail
?.
options
?.
sampler
)?.
name
}}
</div>
</div>
<div
class=
"item"
v-if=
"
detail.platform === AiPlatformEnum.STABLE_DIFFUSION && detail?.options?.clipGuidancePreset
"
>
<div
class=
"tip"
>
CLIP
</div>
<div
class=
"body"
>
{{
StableDiffusionClipGuidancePresets
.
find
(
(
item
:
ImageModelVO
)
=>
item
.
key
===
detail
?.
options
?.
clipGuidancePreset
)?.
name
}}
</div>
</div>
<div
class=
"item"
v-if=
"detail.platform === AiPlatformEnum.STABLE_DIFFUSION && detail?.options?.stylePreset"
>
<div
class=
"tip"
>
风格
</div>
<div
class=
"body"
>
<!-- TODO @fan:貌似需要把 imageStyleList 搞到 api/image/index.ts 枚举起来? -->
<!-- TODO @fan:这里的展示,可能需要按照平台做区分 -->
{{
detail
?.
options
?.
style
}}
{{
StableDiffusionStylePresets
.
find
(
(
item
:
ImageModelVO
)
=>
item
.
key
===
detail
?.
options
?.
stylePreset
)?.
name
}}
</div>
</div>
<div
class=
"item"
v-if=
"detail.platform === AiPlatformEnum.STABLE_DIFFUSION && detail?.options?.steps"
>
<div
class=
"tip"
>
迭代步数
</div>
<div
class=
"body"
>
{{
detail
?.
options
?.
steps
}}
</div>
</div>
<div
class=
"item"
v-if=
"detail.platform === AiPlatformEnum.STABLE_DIFFUSION && detail?.options?.scale"
>
<div
class=
"tip"
>
引导系数
</div>
<div
class=
"body"
>
{{
detail
?.
options
?.
scale
}}
</div>
</div>
<div
class=
"item"
v-if=
"detail.platform === AiPlatformEnum.STABLE_DIFFUSION && detail?.options?.seed"
>
<div
class=
"tip"
>
随机因子
</div>
<div
class=
"body"
>
{{
detail
?.
options
?.
seed
}}
</div>
</div>
</el-drawer>
...
...
@@ -58,6 +118,14 @@
<
script
setup
lang=
"ts"
>
import
{
ImageApi
,
ImageVO
}
from
'@/api/ai/image'
import
ImageCard
from
'./ImageCard.vue'
import
{
AiPlatformEnum
,
ImageModelVO
,
StableDiffusionClipGuidancePresets
,
StableDiffusionSamplers
,
StableDiffusionStylePresets
}
from
'@/views/ai/utils/constants'
import
{
formatTime
}
from
'@/utils'
const
showDrawer
=
ref
<
boolean
>
(
false
)
// 是否显示
const
detail
=
ref
<
ImageVO
>
({}
as
ImageVO
)
// 图片详细信息
...
...
src/views/ai/image/index/
stable-d
iffusion/index.vue
→
src/views/ai/image/index/
components/stableD
iffusion/index.vue
View file @
61bf6fb8
...
...
@@ -3,12 +3,11 @@
<div
class=
"prompt"
>
<el-text
tag=
"b"
>
画面描述
</el-text>
<el-text
tag=
"p"
>
建议使用“形容词+动词+风格”的格式,使用“,”隔开
</el-text>
<!-- TODO @fan:style 看看能不能哟 unocss 替代 -->
<el-input
v-model=
"prompt"
maxlength=
"1024"
rows=
"5"
style=
"width: 100%; margin-top:
15px"
class=
"w-100% mt-
15px"
input-style=
"border-radius: 7px;"
placeholder=
"例如:童话里的小屋应该是什么样子?"
show-word-limit
...
...
@@ -24,7 +23,7 @@
round
class=
"btn"
:type=
"selectHotWord === hotWord ? 'primary' : 'default'"
v-for=
"hotWord in
hot
Words"
v-for=
"hotWord in
ImageHotEnglish
Words"
:key=
"hotWord"
@
click=
"handleHotWordClick(hotWord)"
>
...
...
@@ -37,8 +36,13 @@
<el-text
tag=
"b"
>
采样方法
</el-text>
</div>
<el-space
wrap
class=
"group-item-body"
>
<el-select
v-model=
"selectSampler"
placeholder=
"Select"
size=
"large"
style=
"width: 350px"
>
<el-option
v-for=
"item in sampler"
:key=
"item.key"
:label=
"item.name"
:value=
"item.key"
/>
<el-select
v-model=
"sampler"
placeholder=
"Select"
size=
"large"
class=
"!w-350px"
>
<el-option
v-for=
"item in StableDiffusionSamplers"
:key=
"item.key"
:label=
"item.name"
:value=
"item.key"
/>
</el-select>
</el-space>
</div>
...
...
@@ -47,14 +51,9 @@
<el-text
tag=
"b"
>
CLIP
</el-text>
</div>
<el-space
wrap
class=
"group-item-body"
>
<el-select
v-model=
"selectClipGuidancePreset"
placeholder=
"Select"
size=
"large"
style=
"width: 350px"
>
<el-select
v-model=
"clipGuidancePreset"
placeholder=
"Select"
size=
"large"
class=
"!w-350px"
>
<el-option
v-for=
"item in
c
lipGuidancePresets"
v-for=
"item in
StableDiffusionC
lipGuidancePresets"
:key=
"item.key"
:label=
"item.name"
:value=
"item.key"
...
...
@@ -67,9 +66,9 @@
<el-text
tag=
"b"
>
风格
</el-text>
</div>
<el-space
wrap
class=
"group-item-body"
>
<el-select
v-model=
"s
electStylePreset"
placeholder=
"Select"
size=
"large"
style=
"width:
350px"
>
<el-select
v-model=
"s
tylePreset"
placeholder=
"Select"
size=
"large"
class=
"!w-
350px"
>
<el-option
v-for=
"item in
s
tylePresets"
v-for=
"item in
StableDiffusionS
tylePresets"
:key=
"item.key"
:label=
"item.name"
:value=
"item.key"
...
...
@@ -82,8 +81,8 @@
<el-text
tag=
"b"
>
图片尺寸
</el-text>
</div>
<el-space
wrap
class=
"group-item-body"
>
<el-input
v-model=
"
imageWidth"
style=
"width:
170px"
placeholder=
"图片宽度"
/>
<el-input
v-model=
"
imageHeight"
style=
"width:
170px"
placeholder=
"图片高度"
/>
<el-input
v-model=
"
width"
class=
"w-
170px"
placeholder=
"图片宽度"
/>
<el-input
v-model=
"
height"
class=
"w-
170px"
placeholder=
"图片高度"
/>
</el-space>
</div>
<div
class=
"group-item"
>
...
...
@@ -95,7 +94,7 @@
v-model=
"steps"
type=
"number"
size=
"large"
style=
"width:
350px"
class=
"!w-
350px"
placeholder=
"Please input"
/>
</el-space>
...
...
@@ -109,7 +108,7 @@
v-model=
"scale"
type=
"number"
size=
"large"
style=
"width:
350px"
class=
"!w-
350px"
placeholder=
"Please input"
/>
</el-space>
...
...
@@ -123,7 +122,7 @@
v-model=
"seed"
type=
"number"
size=
"large"
style=
"width:
350px"
class=
"!w-
350px"
placeholder=
"Please input"
/>
</el-space>
...
...
@@ -137,218 +136,53 @@
<
script
setup
lang=
"ts"
>
import
{
ImageApi
,
ImageDrawReqVO
,
ImageVO
}
from
'@/api/ai/image'
import
{
hasChinese
}
from
'@/views/ai/utils/utils'
import
{
ImageHotEnglishWords
,
StableDiffusionClipGuidancePresets
,
StableDiffusionSamplers
,
StableDiffusionStylePresets
}
from
'@/views/ai/utils/constants'
// image 模型
interface
ImageModelVO
{
key
:
string
name
:
string
}
const
message
=
useMessage
()
// 消息弹窗
// 定义属性
const
prompt
=
ref
<
string
>
(
''
)
// 提示词
const
drawIn
=
ref
<
boolean
>
(
false
)
// 生成中
const
selectHotWord
=
ref
<
string
>
(
''
)
// 选中的热词
const
imageWidth
=
ref
<
number
>
(
512
)
// 图片宽度
const
imageHeight
=
ref
<
number
>
(
512
)
// 图片高度
const
hotWords
=
ref
<
string
[]
>
([
'中国旗袍'
,
'古装美女'
,
'卡通头像'
,
'机甲战士'
,
'童话小屋'
,
'中国长城'
])
// 热词
// message
const
message
=
useMessage
()
// 采样方法
const
selectSampler
=
ref
<
string
>
(
'DDIM'
)
// 模型
// DDIM DDPM K_DPMPP_2M K_DPMPP_2S_ANCESTRAL K_DPM_2 K_DPM_2_ANCESTRAL K_EULER K_EULER_ANCESTRAL K_HEUN K_LMS
const
sampler
=
ref
<
ImageModelVO
[]
>
([
{
key
:
'DDIM'
,
name
:
'DDIM'
},
{
key
:
'DDPM'
,
name
:
'DDPM'
},
{
key
:
'K_DPMPP_2M'
,
name
:
'K_DPMPP_2M'
},
{
key
:
'K_DPMPP_2S_ANCESTRAL'
,
name
:
'K_DPMPP_2S_ANCESTRAL'
},
{
key
:
'K_DPM_2'
,
name
:
'K_DPM_2'
},
{
key
:
'K_DPM_2_ANCESTRAL'
,
name
:
'K_DPM_2_ANCESTRAL'
},
{
key
:
'K_EULER'
,
name
:
'K_EULER'
},
{
key
:
'K_EULER_ANCESTRAL'
,
name
:
'K_EULER_ANCESTRAL'
},
{
key
:
'K_HEUN'
,
name
:
'K_HEUN'
},
{
key
:
'K_LMS'
,
name
:
'K_LMS'
}
])
// 风格
// 3d-model analog-film anime cinematic comic-book digital-art enhance fantasy-art isometric
// line-art low-poly modeling-compound neon-punk origami photographic pixel-art tile-texture
const
selectStylePreset
=
ref
<
string
>
(
'3d-model'
)
// 模型
const
stylePresets
=
ref
<
ImageModelVO
[]
>
([
{
key
:
'3d-model'
,
name
:
'3d-model'
},
{
key
:
'analog-film'
,
name
:
'analog-film'
},
{
key
:
'anime'
,
name
:
'anime'
},
{
key
:
'cinematic'
,
name
:
'cinematic'
},
{
key
:
'comic-book'
,
name
:
'comic-book'
},
{
key
:
'digital-art'
,
name
:
'digital-art'
},
{
key
:
'enhance'
,
name
:
'enhance'
},
{
key
:
'fantasy-art'
,
name
:
'fantasy-art'
},
{
key
:
'isometric'
,
name
:
'isometric'
},
{
key
:
'line-art'
,
name
:
'line-art'
},
{
key
:
'low-poly'
,
name
:
'low-poly'
},
{
key
:
'modeling-compound'
,
name
:
'modeling-compound'
},
// neon-punk origami photographic pixel-art tile-texture
{
key
:
'neon-punk'
,
name
:
'neon-punk'
},
{
key
:
'origami'
,
name
:
'origami'
},
{
key
:
'photographic'
,
name
:
'photographic'
},
{
key
:
'pixel-art'
,
name
:
'pixel-art'
},
{
key
:
'tile-texture'
,
name
:
'tile-texture'
}
])
// 文本提示相匹配的图像(clip_guidance_preset) 简称 CLIP
// https://platform.stability.ai/docs/api-reference#tag/SDXL-and-SD1.6/operation/textToImage
// FAST_BLUE FAST_GREEN NONE SIMPLE SLOW SLOWER SLOWEST
const
selectClipGuidancePreset
=
ref
<
string
>
(
'NONE'
)
// 模型
const
clipGuidancePresets
=
ref
<
ImageModelVO
[]
>
([
{
key
:
'NONE'
,
name
:
'NONE'
},
{
key
:
'FAST_BLUE'
,
name
:
'FAST_BLUE'
},
{
key
:
'FAST_GREEN'
,
name
:
'FAST_GREEN'
},
{
key
:
'SIMPLE'
,
name
:
'SIMPLE'
},
{
key
:
'SLOW'
,
name
:
'SLOW'
},
{
key
:
'SLOWER'
,
name
:
'SLOWER'
},
{
key
:
'SLOWEST'
,
name
:
'SLOWEST'
}
])
// 表单
const
prompt
=
ref
<
string
>
(
''
)
// 提示词
const
width
=
ref
<
number
>
(
512
)
// 图片宽度
const
height
=
ref
<
number
>
(
512
)
// 图片高度
const
sampler
=
ref
<
string
>
(
'DDIM'
)
// 采样方法
const
steps
=
ref
<
number
>
(
20
)
// 迭代步数
const
seed
=
ref
<
number
>
(
42
)
// 控制生成图像的随机性
const
scale
=
ref
<
number
>
(
7.5
)
// 引导系数
const
clipGuidancePreset
=
ref
<
string
>
(
'NONE'
)
// 文本提示相匹配的图像(clip_guidance_preset) 简称 CLIP
const
stylePreset
=
ref
<
string
>
(
'3d-model'
)
// 风格
// 定义 Props
const
props
=
defineProps
({})
// 定义 emits
const
emits
=
defineEmits
([
'onDrawStart'
,
'onDrawComplete'
])
const
emits
=
defineEmits
([
'onDrawStart'
,
'onDrawComplete'
])
// 定义 emits
/**
热词 - click
*/
/**
选择热词
*/
const
handleHotWordClick
=
async
(
hotWord
:
string
)
=>
{
// 取消选中
//
情况一:
取消选中
if
(
selectHotWord
.
value
==
hotWord
)
{
selectHotWord
.
value
=
''
return
}
// 选中
selectHotWord
.
value
=
hotWord
// 替换提示词
prompt
.
value
=
hotWord
// 情况二:选中
selectHotWord
.
value
=
hotWord
// 选中
prompt
.
value
=
hotWord
// 替换提示词
}
/**
图片生产
*/
/**
图片生成
*/
const
handleGenerateImage
=
async
()
=>
{
// 二次确认
await
message
.
confirm
(
`确认生成内容?`
)
if
(
await
hasChinese
(
prompt
.
value
))
{
if
(
hasChinese
(
prompt
.
value
))
{
message
.
alert
(
'暂不支持中文!'
)
return
}
await
message
.
confirm
(
`确认生成内容?`
)
try
{
// 加载中
drawIn
.
value
=
true
...
...
@@ -359,15 +193,15 @@ const handleGenerateImage = async () => {
platform
:
'StableDiffusion'
,
model
:
'stable-diffusion-v1-6'
,
prompt
:
prompt
.
value
,
// 提示词
width
:
imageW
idth
.
value
,
// 图片宽度
height
:
imageH
eight
.
value
,
// 图片高度
width
:
w
idth
.
value
,
// 图片宽度
height
:
h
eight
.
value
,
// 图片高度
options
:
{
seed
:
seed
.
value
,
// 随机种子
steps
:
steps
.
value
,
// 图片生成步数
scale
:
scale
.
value
,
// 引导系数
sampler
:
s
electS
ampler
.
value
,
// 采样算法
clipGuidancePreset
:
selectC
lipGuidancePreset
.
value
,
// 文本提示相匹配的图像 CLIP
stylePreset
:
s
electS
tylePreset
.
value
// 风格
sampler
:
sampler
.
value
,
// 采样算法
clipGuidancePreset
:
c
lipGuidancePreset
.
value
,
// 文本提示相匹配的图像 CLIP
stylePreset
:
stylePreset
.
value
// 风格
}
}
as
ImageDrawReqVO
await
ImageApi
.
drawImage
(
form
)
...
...
@@ -380,16 +214,16 @@ const handleGenerateImage = async () => {
}
/** 填充值 */
const
settingValues
=
async
(
imageD
etail
:
ImageVO
)
=>
{
prompt
.
value
=
imageD
etail
.
prompt
imageWidth
.
value
=
imageD
etail
.
width
imageHeight
.
value
=
imageD
etail
.
height
seed
.
value
=
imageD
etail
.
options
?.
seed
steps
.
value
=
imageD
etail
.
options
?.
steps
scale
.
value
=
imageD
etail
.
options
?.
scale
s
electSampler
.
value
=
imageD
etail
.
options
?.
sampler
selectClipGuidancePreset
.
value
=
imageD
etail
.
options
?.
clipGuidancePreset
s
electStylePreset
.
value
=
imageD
etail
.
options
?.
stylePreset
const
settingValues
=
async
(
d
etail
:
ImageVO
)
=>
{
prompt
.
value
=
d
etail
.
prompt
width
.
value
=
d
etail
.
width
height
.
value
=
d
etail
.
height
seed
.
value
=
d
etail
.
options
?.
seed
steps
.
value
=
d
etail
.
options
?.
steps
scale
.
value
=
d
etail
.
options
?.
scale
s
ampler
.
value
=
d
etail
.
options
?.
sampler
clipGuidancePreset
.
value
=
d
etail
.
options
?.
clipGuidancePreset
s
tylePreset
.
value
=
d
etail
.
options
?.
stylePreset
}
/** 暴露组件方法 */
...
...
src/views/ai/image/index/index.vue
View file @
61bf6fb8
...
...
@@ -27,12 +27,12 @@
</
template
>
<
script
setup
lang=
"ts"
>
import
Dall3
from
'./dall3/index.vue'
import
Midjourney
from
'./midjourney/index.vue'
import
StableDiffusion
from
'./stable-diffusion/index.vue'
import
ImageList
from
'./components/ImageList.vue'
import
{
AiPlatformEnum
}
from
'@/views/ai/utils/constants'
import
{
ImageVO
}
from
'@/api/ai/image'
import
Dall3
from
'./dall3/index.vue'
import
Midjourney
from
'./midjourney/index.vue'
import
StableDiffusion
from
'./components/stableDiffusion/index.vue'
const
imageListRef
=
ref
<
any
>
()
// image 列表 ref
const
dall3Ref
=
ref
<
any
>
()
// openai ref
...
...
src/views/ai/utils/constants.ts
View file @
61bf6fb8
...
...
@@ -40,3 +40,173 @@ export const AiMusicStatusEnum = {
SUCCESS
:
20
,
// 已完成
FAIL
:
30
// 已失败
}
// ========== 【图片 UI】相关的枚举 ==========
export
const
ImageHotWords
=
[
'中国旗袍'
,
'古装美女'
,
'卡通头像'
,
'机甲战士'
,
'童话小屋'
,
'中国长城'
]
// 图片热词
export
const
ImageHotEnglishWords
=
[
'Chinese Cheongsam'
,
'Ancient Beauty'
,
'Cartoon Avatar'
,
'Mech Warrior'
,
'Fairy Tale Cottage'
,
'The Great Wall of China'
]
// 图片热词(英文)
export
interface
ImageModelVO
{
key
:
string
name
:
string
}
export
const
StableDiffusionSamplers
=
ref
<
ImageModelVO
[]
>
([
{
key
:
'DDIM'
,
name
:
'DDIM'
},
{
key
:
'DDPM'
,
name
:
'DDPM'
},
{
key
:
'K_DPMPP_2M'
,
name
:
'K_DPMPP_2M'
},
{
key
:
'K_DPMPP_2S_ANCESTRAL'
,
name
:
'K_DPMPP_2S_ANCESTRAL'
},
{
key
:
'K_DPM_2'
,
name
:
'K_DPM_2'
},
{
key
:
'K_DPM_2_ANCESTRAL'
,
name
:
'K_DPM_2_ANCESTRAL'
},
{
key
:
'K_EULER'
,
name
:
'K_EULER'
},
{
key
:
'K_EULER_ANCESTRAL'
,
name
:
'K_EULER_ANCESTRAL'
},
{
key
:
'K_HEUN'
,
name
:
'K_HEUN'
},
{
key
:
'K_LMS'
,
name
:
'K_LMS'
}
])
export
const
StableDiffusionStylePresets
=
ref
<
ImageModelVO
[]
>
([
{
key
:
'3d-model'
,
name
:
'3d-model'
},
{
key
:
'analog-film'
,
name
:
'analog-film'
},
{
key
:
'anime'
,
name
:
'anime'
},
{
key
:
'cinematic'
,
name
:
'cinematic'
},
{
key
:
'comic-book'
,
name
:
'comic-book'
},
{
key
:
'digital-art'
,
name
:
'digital-art'
},
{
key
:
'enhance'
,
name
:
'enhance'
},
{
key
:
'fantasy-art'
,
name
:
'fantasy-art'
},
{
key
:
'isometric'
,
name
:
'isometric'
},
{
key
:
'line-art'
,
name
:
'line-art'
},
{
key
:
'low-poly'
,
name
:
'low-poly'
},
{
key
:
'modeling-compound'
,
name
:
'modeling-compound'
},
// neon-punk origami photographic pixel-art tile-texture
{
key
:
'neon-punk'
,
name
:
'neon-punk'
},
{
key
:
'origami'
,
name
:
'origami'
},
{
key
:
'photographic'
,
name
:
'photographic'
},
{
key
:
'pixel-art'
,
name
:
'pixel-art'
},
{
key
:
'tile-texture'
,
name
:
'tile-texture'
}
])
export
const
StableDiffusionClipGuidancePresets
=
ref
<
ImageModelVO
[]
>
([
{
key
:
'NONE'
,
name
:
'NONE'
},
{
key
:
'FAST_BLUE'
,
name
:
'FAST_BLUE'
},
{
key
:
'FAST_GREEN'
,
name
:
'FAST_GREEN'
},
{
key
:
'SIMPLE'
,
name
:
'SIMPLE'
},
{
key
:
'SLOW'
,
name
:
'SLOW'
},
{
key
:
'SLOWER'
,
name
:
'SLOWER'
},
{
key
:
'SLOWEST'
,
name
:
'SLOWEST'
}
])
src/views/ai/utils/utils.ts
View file @
61bf6fb8
...
...
@@ -8,6 +8,6 @@
*/
/** 判断字符串是否包含中文 */
export
const
hasChinese
=
async
(
str
)
=>
{
export
const
hasChinese
=
(
str
:
string
)
=>
{
return
/
[\u
4e00-
\u
9fa5
]
/
.
test
(
str
)
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment