Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
S
saas-dml
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
saas-dml
Commits
94155133
提交
94155133
authored
2月 13, 2025
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
chore: update
上级
ec26e346
隐藏空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
342 行增加
和
15 行删除
+342
-15
index.html
index.html
+1
-1
ai.ts
src/api/ai.ts
+26
-0
useAI.js
src/composables/useAI.js
+268
-0
AIChat.vue
src/modules/material/all/components/AIChat.vue
+27
-14
vite.config.ts
vite.config.ts
+20
-0
没有找到文件。
index.html
浏览文件 @
94155133
...
@@ -10,7 +10,7 @@
...
@@ -10,7 +10,7 @@
<body>
<body>
<div
id=
"app"
></div>
<div
id=
"app"
></div>
<script
type=
"module"
src=
"/src/main.ts"
></script>
<script
type=
"module"
src=
"/src/main.ts"
></script>
<script
src=
"https://webapp-pub.ezijing.com/plugins/sky-agents/sky-agent.umd.cjs?v=
1
"
></script>
<script
src=
"https://webapp-pub.ezijing.com/plugins/sky-agents/sky-agent.umd.cjs?v=
2
"
></script>
<script
src=
"https://webapp-pub.ezijing.com/plugins/tinymce/tinymce.min.js"
></script>
<script
src=
"https://webapp-pub.ezijing.com/plugins/tinymce/tinymce.min.js"
></script>
</body>
</body>
</html>
</html>
src/api/ai.ts
0 → 100644
浏览文件 @
94155133
import
httpRequest
from
'@/utils/axios'
// 获取天工AI的使用详情
export
function
getAIUsage
(
params
:
{
marketing_material_id
:
string
})
{
return
httpRequest
.
get
(
'/api/lab/v1/experiment/marketing-ai/ai-usage-detail'
,
{
params
})
}
// 天工AI-聊天
export
function
postAIChat
(
data
:
{
marketing_material_id
:
string
context
:
string
type
:
number
chart_id
:
string
|
null
})
{
return
httpRequest
.
post
(
'/api/lab/v1/experiment/marketing-ai/sky-agents-chat'
,
data
)
}
// 天工3.0文字生成图片
export
function
postGenerateImage
(
data
:
{
marketing_material_id
:
string
context
:
string
type
:
number
chart_id
:
string
|
null
})
{
return
httpRequest
.
post
(
'/api/lab/v1/experiment/marketing-ai/sky-agent3-generate-image'
,
data
)
}
src/composables/useAI.js
0 → 100644
浏览文件 @
94155133
import
md5
from
'blueimp-md5'
import
{
useStorage
}
from
'@vueuse/core'
import
{
fetchEventSource
}
from
'@fortaine/fetch-event-source'
import
axios
from
'axios'
import
{
getAIUsage
,
postGenerateImage
}
from
'@/api/ai'
import
{
ElMessage
}
from
'element-plus'
export
function
useAI
(
config
)
{
// AI 配置列表
const
options
=
[
{
label
:
'文心一言'
,
value
:
'yiyan'
},
{
label
:
'DeepSeek'
,
value
:
'deepseek'
},
{
label
:
'通义千问'
,
value
:
'qwen'
},
{
label
:
'天工'
,
value
:
'tiangong'
},
]
const
ai
=
useStorage
(
'ai'
,
'tiangong'
)
const
messages
=
ref
([])
const
isLoading
=
ref
(
false
)
async
function
post
(
data
)
{
isLoading
.
value
=
true
try
{
switch
(
ai
.
value
)
{
case
'yiyan'
:
await
yiyan
(
data
)
break
case
'deepseek'
:
await
deepseek
(
data
)
break
case
'qwen'
:
await
qwen
(
data
)
break
case
'tiangong'
:
await
tiangong
(
data
)
break
default
:
throw
new
Error
(
'未找到对应的 AI 配置'
)
}
}
catch
(
err
)
{
console
.
error
(
'AI 请求失败:'
,
err
)
}
finally
{
isLoading
.
value
=
false
}
}
// 文心一言
async
function
yiyan
(
data
)
{
// 获取token
const
getAccessToken
=
async
()
=>
{
const
AK
=
'wY7bvMpkWeZbDVq9w3EDvpjU'
const
SK
=
'XJwpiJWxs5HXkOtbo6tQrvYPZFJAWdAy'
const
resp
=
await
axios
.
post
(
'/api/qianfan/oauth/2.0/token?grant_type=client_credentials&client_id='
+
AK
+
'&client_secret='
+
SK
)
return
resp
.
data
.
access_token
}
const
resp
=
await
axios
.
post
(
'/api/qianfan/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/eb-instant?access_token='
+
(
await
getAccessToken
()),
{
messages
:
[{
role
:
'user'
,
content
:
data
.
content
}],
}
)
messages
.
value
.
push
({
role
:
'assistant'
,
content
:
resp
.
data
.
result
.
replaceAll
(
'
\
n'
,
'<br/>'
)
})
}
// DeepSeek
async
function
deepseek
(
data
)
{
const
apiKey
=
'sk-f1a6f0a7013241de8393cb2cb108e777'
const
resp
=
await
axios
.
post
(
'/api/deepseek/chat/completions'
,
{
model
:
'deepseek-chat'
,
messages
:
[{
role
:
'user'
,
content
:
data
.
content
}],
},
{
headers
:
{
'Content-Type'
:
'application/json'
,
Authorization
:
`Bearer
${
apiKey
}
`
},
}
)
if
(
resp
.
data
)
{
const
[
choice
=
{}]
=
resp
.
data
.
choices
messages
.
value
.
push
({
role
:
'assistant'
,
content
:
choice
.
message
.
content
.
replaceAll
(
'
\
n'
,
'<br/>'
)
})
}
}
// 通义千问
async
function
qwen
(
data
)
{
const
apiKey
=
'sk-afd0fcdb53bf4058b2068b8548820150'
const
resp
=
await
axios
.
post
(
'/api/qwen/compatible-mode/v1/chat/completions'
,
{
model
:
'qwen-max'
,
messages
:
[{
role
:
'user'
,
content
:
data
.
content
}],
},
{
headers
:
{
'Content-Type'
:
'application/json'
,
Authorization
:
`Bearer
${
apiKey
}
`
},
}
)
if
(
resp
.
data
)
{
const
[
choice
=
{}]
=
resp
.
data
.
choices
messages
.
value
.
push
({
role
:
'assistant'
,
content
:
choice
.
message
.
content
.
replaceAll
(
'
\
n'
,
'<br/>'
)
})
}
}
// 天工
async
function
tiangong
(
data
)
{
const
appKey
=
'a8701b73637562d33a53c668a90ee3be'
const
appSecret
=
'e191593f486bb88a39c634f46926762dddc97b9082e192af'
const
timestamp
=
Math
.
floor
(
Date
.
now
()
/
1000
)
const
sign
=
md5
(
`
${
appKey
}${
appSecret
}${
timestamp
}
`
)
return
await
fetchEventSource
(
'/api/tiangong/sky-saas-writing/api/v1/chat'
,
{
method
:
'POST'
,
headers
:
{
'Content-Type'
:
'application/json'
,
app_key
:
appKey
,
sign
,
timestamp
,
stream
:
'true'
},
body
:
JSON
.
stringify
({
chat_history
:
[{
role
:
'user'
,
content
:
data
.
content
}],
stream_resp_type
:
'update'
,
}),
async
onopen
(
response
)
{
console
.
log
(
response
)
if
(
response
.
ok
)
{
return
response
}
else
{
throw
response
}
},
onmessage
(
res
)
{
console
.
log
(
res
.
data
)
const
message
=
JSON
.
parse
(
res
.
data
)
if
(
message
.
type
!==
1
)
return
const
messageId
=
message
.
conversation_id
const
messageIndex
=
messages
.
value
.
findIndex
((
message
)
=>
message
.
id
===
messageId
)
const
content
=
message
?.
arguments
?.[
0
]?.
messages
?.[
0
]?.
text
||
''
if
(
messageIndex
===
-
1
)
{
messages
.
value
.
push
({
id
:
messageId
,
role
:
'assistant'
,
content
})
}
else
{
messages
.
value
[
messageIndex
].
content
=
content
}
isLoading
.
value
=
false
},
onerror
(
err
)
{
isLoading
.
value
=
false
throw
err
},
})
}
const
usages
=
ref
({
chart_count
:
0
,
ai_creation_count
:
0
,
ai_polish_count
:
0
,
ai_expand_count
:
0
,
ai_refresh_count
:
0
,
chart_max_count
:
20
,
ai_creation_max_count
:
5
,
ai_polish_max_count
:
5
,
ai_expand_max_count
:
5
,
ai_refresh_max_count
:
5
,
})
async
function
fetchUsages
()
{
const
res
=
await
getAIUsage
(
config
)
usages
.
value
=
res
.
data
.
detail
}
async
function
generateText
(
data
)
{
isLoading
.
value
=
true
const
docAction
=
{
2
:
'write'
,
3
:
'rewrite'
,
4
:
'expand'
,
5
:
'rewrite'
,
7
:
'abbreviate'
,
8
:
'summary'
,
}
const
params
=
{
content
:
data
.
content
,
doc_action
:
docAction
[
data
.
type
],
full_text
:
!!
(
data
.
type
===
2
),
}
await
fetchEventSource
(
'/api/lab/v1/experiment/marketing-ai/sky-agent3-chat'
,
{
method
:
'POST'
,
headers
:
{
'Content-Type'
:
'application/json'
,
},
body
:
JSON
.
stringify
({
...
config
,
...
data
,
api_type
:
parseInt
(
data
.
type
)
===
1
?
1
:
2
,
context
:
data
.
content
,
params
:
params
,
}),
async
onopen
(
response
)
{
if
(
response
.
ok
)
{
return
}
else
{
throw
response
}
},
onmessage
(
res
)
{
const
message
=
JSON
.
parse
(
res
.
data
)
// 聊天返回内容
if
(
data
.
type
===
'1'
)
{
if
(
message
.
code
===
0
)
{
ElMessage
.
error
(
message
.
message
)
return
}
const
conversationId
=
message
.
conversation_id
const
messageIndex
=
messages
.
value
.
findIndex
((
session
)
=>
session
.
conversationId
===
conversationId
)
const
content
=
message
?.
arguments
?.
reduce
((
a
,
b
)
=>
{
a
=
b
?.
messages
[
0
]?.
text
||
''
return
a
},
''
)
if
(
messageIndex
===
-
1
)
{
messages
.
value
.
push
({
conversationId
,
role
:
'assistant'
,
content
,
input
:
data
.
context
})
}
else
{
if
(
content
)
{
messages
.
value
[
messageIndex
].
content
=
content
}
}
}
else
{
// 按钮功能返回内容
const
requestId
=
message
.
request_id
const
messageIndex
=
messages
.
value
.
findIndex
((
session
)
=>
session
.
conversationId
===
requestId
)
if
(
messageIndex
===
-
1
)
{
messages
.
value
.
push
({
conversationId
:
requestId
,
role
:
'assistant'
,
content
:
message
.
data
?.
text
||
''
,
input
:
data
.
context
,
})
}
else
{
messages
.
value
[
messageIndex
].
content
=
message
.
data
?.
text
}
}
isLoading
.
value
=
false
},
onclose
()
{
fetchUsages
()
isLoading
.
value
=
false
},
onerror
(
err
)
{
console
.
log
(
err
)
isLoading
.
value
=
false
throw
err
},
})
}
// 生成图片
async
function
generateImage
(
data
)
{
isLoading
.
value
=
true
try
{
const
res
=
await
postGenerateImage
({
...
config
,
...
data
})
if
(
res
.
data
.
detail
.
image_url
)
{
messages
.
value
.
push
({
type
:
'image'
,
role
:
'assistant'
,
...
res
.
data
.
detail
})
}
else
{
ElMessage
.
error
(
res
.
data
.
detail
.
failure_reason
)
}
fetchUsages
()
}
catch
(
error
)
{
console
.
log
(
error
)
}
isLoading
.
value
=
false
}
return
{
ai
,
options
,
post
,
messages
,
isLoading
,
usages
,
fetchUsages
,
generateText
,
generateImage
}
}
src/modules/material/all/components/AIChat.vue
浏览文件 @
94155133
<
script
setup
>
<
script
setup
>
import
{
useClipboard
}
from
'@vueuse/core'
import
{
useClipboard
}
from
'@vueuse/core'
import
{
use
Chat
}
from
'../composables/useChat
'
import
{
use
AI
}
from
'@/composables/useAI
'
import
{
useMapStore
}
from
'@/stores/map'
import
{
useMapStore
}
from
'@/stores/map'
import
{
useUserStore
}
from
'@/stores/user'
import
{
useUserStore
}
from
'@/stores/user'
import
{
useConnection
}
from
'../composables/useConnection'
import
{
useConnection
}
from
'../composables/useConnection'
...
@@ -11,7 +11,7 @@ import {
...
@@ -11,7 +11,7 @@ import {
materialUsageList
,
materialUsageList
,
materialUsersList
,
materialUsersList
,
materialPictureStyleList
,
materialPictureStyleList
,
textPurposeList
textPurposeList
,
}
from
'@/utils/dictionary'
}
from
'@/utils/dictionary'
import
IconComputer
from
'./IconComputer.vue'
import
IconComputer
from
'./IconComputer.vue'
import
IconUser
from
'./IconUser.vue'
import
IconUser
from
'./IconUser.vue'
...
@@ -31,10 +31,10 @@ const welcomeMessage = computed(() => {
...
@@ -31,10 +31,10 @@ const welcomeMessage = computed(() => {
const
data
=
form
.
value
const
data
=
form
.
value
const
way
=
getNameByValue
(
data
.
way
,
materialMethodList
)
const
way
=
getNameByValue
(
data
.
way
,
materialMethodList
)
const
type
=
getNameByValue
(
data
.
type
,
materialType
)
const
type
=
getNameByValue
(
data
.
type
,
materialType
)
const
industry
=
industryList
.
value
.
find
(
item
=>
item
.
id
==
data
.
industry_id
)?.
name
const
industry
=
industryList
.
value
.
find
(
(
item
)
=>
item
.
id
==
data
.
industry_id
)?.
name
const
personnel
=
getNameByValue
(
data
.
personnel_type
,
materialUsersList
)
const
personnel
=
getNameByValue
(
data
.
personnel_type
,
materialUsersList
)
const
scenario
=
getNameByValue
(
data
.
scenario_type
,
materialUsageList
)
const
scenario
=
getNameByValue
(
data
.
scenario_type
,
materialUsageList
)
const
connection
=
connectionList
.
value
.
find
(
item
=>
item
.
id
==
data
.
channel
)?.
type_name
const
connection
=
connectionList
.
value
.
find
(
(
item
)
=>
item
.
id
==
data
.
channel
)?.
type_name
const
extendInfo
=
data
.
extend_info
||
{}
const
extendInfo
=
data
.
extend_info
||
{}
const
pictureStyle
=
getNameByValue
(
extendInfo
.
picture_style
,
materialPictureStyleList
)
const
pictureStyle
=
getNameByValue
(
extendInfo
.
picture_style
,
materialPictureStyleList
)
const
textPurpose
=
getNameByValue
(
extendInfo
.
text_use
,
textPurposeList
)
const
textPurpose
=
getNameByValue
(
extendInfo
.
text_use
,
textPurposeList
)
...
@@ -50,13 +50,14 @@ const welcomeMessage = computed(() => {
...
@@ -50,13 +50,14 @@ const welcomeMessage = computed(() => {
const
content
=
ref
(
''
)
const
content
=
ref
(
''
)
const
route
=
useRoute
()
const
route
=
useRoute
()
const
{
usages
,
messages
,
post
,
isLoading
}
=
useChat
({
const
{
ai
,
options
,
usages
,
messages
,
post
,
isLoading
,
fetchUsages
,
generateText
,
generateImage
}
=
useAI
({
experiment_id
:
route
.
query
.
experiment_id
,
experiment_id
:
route
.
query
.
experiment_id
,
marketing_material_id
:
form
.
value
.
id
,
marketing_material_id
:
form
.
value
.
id
,
fileType
:
form
.
value
.
type
})
})
onMounted
(()
=>
{
onMounted
(()
=>
{
fetchUsages
()
messages
.
value
.
push
({
role
:
'system'
,
content
:
welcomeMessage
.
value
})
messages
.
value
.
push
({
role
:
'system'
,
content
:
welcomeMessage
.
value
})
// if (form.value.content) {
// if (form.value.content) {
// messages.value.push({ role: 'bot', content: form.value.content })
// messages.value.push({ role: 'bot', content: form.value.content })
...
@@ -78,7 +79,11 @@ watch(welcomeMessage, () => {
...
@@ -78,7 +79,11 @@ watch(welcomeMessage, () => {
async
function
postMessage
()
{
async
function
postMessage
()
{
if
(
!
content
.
value
)
return
if
(
!
content
.
value
)
return
messages
.
value
.
push
({
role
:
'user'
,
content
:
content
.
value
})
messages
.
value
.
push
({
role
:
'user'
,
content
:
content
.
value
})
post
({
content
:
content
.
value
,
type
:
'1'
})
if
(
form
.
value
.
type
==
2
)
{
generateImage
({
content
:
content
.
value
})
}
else
{
post
({
content
:
content
.
value
,
type
:
'1'
})
}
content
.
value
=
''
content
.
value
=
''
}
}
...
@@ -93,7 +98,7 @@ async function handleSendType(type, content) {
...
@@ -93,7 +98,7 @@ async function handleSendType(type, content) {
content
=
xss
(
content
,
{
content
=
xss
(
content
,
{
whiteList
:
{},
// 白名单为空,表示过滤所有标签
whiteList
:
{},
// 白名单为空,表示过滤所有标签
stripIgnoreTag
:
true
,
// 过滤所有非白名单标签的HTML
stripIgnoreTag
:
true
,
// 过滤所有非白名单标签的HTML
stripIgnoreTagBody
:
[
'script'
]
// script标签较特殊,需要过滤标签中间的内容
stripIgnoreTagBody
:
[
'script'
]
,
// script标签较特殊,需要过滤标签中间的内容
})
})
switch
(
type
)
{
switch
(
type
)
{
case
2
:
case
2
:
...
@@ -112,7 +117,11 @@ async function handleSendType(type, content) {
...
@@ -112,7 +117,11 @@ async function handleSendType(type, content) {
content
=
`我是
${
userName
}
,请帮我总结以下内容:
${
content
.
replace
(
'请帮我创作一个'
,
''
)}
`
content
=
`我是
${
userName
}
,请帮我总结以下内容:
${
content
.
replace
(
'请帮我创作一个'
,
''
)}
`
break
break
}
}
post
({
type
,
content
})
if
(
type
==
99
)
{
generateImage
({
type
,
content
})
}
else
{
generateText
({
type
,
content
})
}
}
}
const
chatRef
=
ref
()
const
chatRef
=
ref
()
...
@@ -129,7 +138,7 @@ function handleCopy(content) {
...
@@ -129,7 +138,7 @@ function handleCopy(content) {
const
html
=
xss
(
content
,
{
const
html
=
xss
(
content
,
{
whiteList
:
{},
// 白名单为空,表示过滤所有标签
whiteList
:
{},
// 白名单为空,表示过滤所有标签
stripIgnoreTag
:
true
,
// 过滤所有非白名单标签的HTML
stripIgnoreTag
:
true
,
// 过滤所有非白名单标签的HTML
stripIgnoreTagBody
:
[
'script'
]
// script标签较特殊,需要过滤标签中间的内容
stripIgnoreTagBody
:
[
'script'
]
,
// script标签较特殊,需要过滤标签中间的内容
})
})
copy
(
html
)
copy
(
html
)
}
}
...
@@ -168,7 +177,7 @@ async function handleSave(message) {
...
@@ -168,7 +177,7 @@ async function handleSave(message) {
size=
"small"
size=
"small"
type=
"primary"
type=
"primary"
@
click=
"handleSendType(5, item.input || item.content)"
@
click=
"handleSendType(5, item.input || item.content)"
v-if=
"item.role == '
bo
t'"
v-if=
"item.role == '
assistan
t'"
>
刷新(
{{
usages
.
ai_refresh_count
}}
/
{{
usages
.
ai_refresh_max_count
}}
)
</el-button
>
刷新(
{{
usages
.
ai_refresh_count
}}
/
{{
usages
.
ai_refresh_max_count
}}
)
</el-button
>
>
<el-button
size=
"small"
type=
"primary"
@
click=
"handleSendType(2, item.content)"
<el-button
size=
"small"
type=
"primary"
@
click=
"handleSendType(2, item.content)"
...
@@ -195,7 +204,7 @@ async function handleSave(message) {
...
@@ -195,7 +204,7 @@ async function handleSave(message) {
>
生成(
{{
usages
.
ai_generate_image_count
}}
/
{{
usages
.
ai_generate_image_max_count
}}
)
</el-button
>
生成(
{{
usages
.
ai_generate_image_count
}}
/
{{
usages
.
ai_generate_image_max_count
}}
)
</el-button
>
>
</
template
>
</
template
>
<
template
v-if=
"item.role == '
bo
t'"
>
<
template
v-if=
"item.role == '
assistan
t'"
>
<el-button
size=
"small"
type=
"primary"
@
click=
"handleSendType(99, item.content)"
<el-button
size=
"small"
type=
"primary"
@
click=
"handleSendType(99, item.content)"
>
重画(
{{
usages
.
ai_generate_image_count
}}
/
{{
usages
.
ai_generate_image_max_count
}}
)
</el-button
>
重画(
{{
usages
.
ai_generate_image_count
}}
/
{{
usages
.
ai_generate_image_max_count
}}
)
</el-button
>
>
...
@@ -213,13 +222,17 @@ async function handleSave(message) {
...
@@ -213,13 +222,17 @@ async function handleSave(message) {
</div>
</div>
</div>
</div>
<div
class=
"chat-footer"
>
<div
class=
"chat-footer"
>
<el-select-v2
:options=
"options"
v-model=
"ai"
style=
"width: 100%; margin-bottom: 10px"
v-if=
"form.type == 1"
></el-select-v2>
<el-input
<el-input
type=
"textarea"
type=
"textarea"
:autosize=
"{ minRows: 1, maxRows: 12 }"
:autosize=
"{ minRows: 1, maxRows: 12 }"
placeholder=
"发消息"
placeholder=
"发消息"
v-model=
"content"
v-model=
"content"
@
keydown
.
enter=
"handleSend"
@
keydown
.
enter=
"handleSend"
></el-input>
></el-input>
<el-button
text
type=
"primary"
@
click=
"handleSend"
>
发送
</el-button>
<el-button
text
type=
"primary"
@
click=
"handleSend"
>
发送
</el-button>
</div>
</div>
</template>
</template>
...
...
vite.config.ts
浏览文件 @
94155133
...
@@ -30,6 +30,26 @@ export default defineConfig(({ mode }) => ({
...
@@ -30,6 +30,26 @@ export default defineConfig(({ mode }) => ({
// cert: fs.readFileSync(path.join(__dirname, './https/ezijing.com.pem'))
// cert: fs.readFileSync(path.join(__dirname, './https/ezijing.com.pem'))
// },
// },
proxy
:
{
proxy
:
{
'/api/tiangong'
:
{
target
:
'https://api.singularity-ai.com'
,
changeOrigin
:
true
,
rewrite
:
(
path
)
=>
path
.
replace
(
/^
\/
api
\/
tiangong/
,
''
),
},
'/api/deepseek'
:
{
target
:
'https://api.deepseek.com'
,
changeOrigin
:
true
,
rewrite
:
(
path
)
=>
path
.
replace
(
/^
\/
api
\/
deepseek/
,
''
),
},
'/api/qwen'
:
{
target
:
'https://dashscope.aliyuncs.com'
,
changeOrigin
:
true
,
rewrite
:
(
path
)
=>
path
.
replace
(
/^
\/
api
\/
qwen/
,
''
),
},
'/api/qianfan'
:
{
target
:
'https://aip.baidubce.com'
,
changeOrigin
:
true
,
rewrite
:
(
path
)
=>
path
.
replace
(
/^
\/
api
\/
qianfan/
,
''
),
},
// '/api/resource': {
// '/api/resource': {
// target: 'http://com-resource-admin-test.ezijing.com/',
// target: 'http://com-resource-admin-test.ezijing.com/',
// changeOrigin: true,
// changeOrigin: true,
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论