Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
S
skyagents
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
skyagents
Commits
a9dbe94e
提交
a9dbe94e
authored
10月 09, 2026
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
chore: 更新版本号并清理无用代码
上级
917d145e
隐藏空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
60 行增加
和
182 行删除
+60
-182
deploy.mjs
deploy.mjs
+3
-3
package-lock.json
package-lock.json
+2
-38
App.vue
src/App.vue
+2
-6
useAI.js
src/composables/useAI.js
+53
-135
没有找到文件。
deploy.mjs
浏览文件 @
a9dbe94e
...
@@ -7,9 +7,9 @@ const log = console.log
...
@@ -7,9 +7,9 @@ const log = console.log
const
__dirname
=
path
.
resolve
()
const
__dirname
=
path
.
resolve
()
const
client
=
new
OSS
({
const
client
=
new
OSS
({
region
:
'oss-cn-beijing'
,
region
:
'oss-cn-beijing'
,
accessKeyId
:
'LTAI
OTuuLTaWoGJj
'
,
accessKeyId
:
'LTAI
5t6yKc2m47ZUZTBbUBuP
'
,
accessKeySecret
:
'
dE5tTGm2lh35eItct2krW2DeH2lf2I
'
,
accessKeySecret
:
'
mhuPVC43NAkzBaheHyWGjREiIrLax0
'
,
bucket
:
'webapp-pub'
bucket
:
'webapp-pub'
,
})
})
async
function
uploadTarget
(
src
,
dist
)
{
async
function
uploadTarget
(
src
,
dist
)
{
...
...
package-lock.json
浏览文件 @
a9dbe94e
{
{
"name"
:
"skyagents"
,
"name"
:
"skyagents"
,
"version"
:
"
0
.0.0"
,
"version"
:
"
1
.0.0"
,
"lockfileVersion"
:
3
,
"lockfileVersion"
:
3
,
"requires"
:
true
,
"requires"
:
true
,
"packages"
:
{
"packages"
:
{
""
:
{
""
:
{
"name"
:
"skyagents"
,
"name"
:
"skyagents"
,
"version"
:
"
0
.0.0"
,
"version"
:
"
1
.0.0"
,
"dependencies"
:
{
"dependencies"
:
{
"@floating-ui/vue"
:
"^1.1.6"
,
"@floating-ui/vue"
:
"^1.1.6"
,
"@fortaine/fetch-event-source"
:
"^3.0.6"
,
"@fortaine/fetch-event-source"
:
"^3.0.6"
,
...
@@ -1491,18 +1491,6 @@
...
@@ -1491,18 +1491,6 @@
"dev"
:
true
,
"dev"
:
true
,
"license"
:
"MIT"
"license"
:
"MIT"
},
},
"node_modules/@types/node"
:
{
"version"
:
"22.13.1"
,
"resolved"
:
"https://registry.npmjs.org/@types/node/-/node-22.13.1.tgz"
,
"integrity"
:
"sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew=="
,
"dev"
:
true
,
"license"
:
"MIT"
,
"optional"
:
true
,
"peer"
:
true
,
"dependencies"
:
{
"undici-types"
:
"~6.20.0"
}
},
"node_modules/@types/web-bluetooth"
:
{
"node_modules/@types/web-bluetooth"
:
{
"version"
:
"0.0.20"
,
"version"
:
"0.0.20"
,
"resolved"
:
"https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz"
,
"resolved"
:
"https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz"
,
...
@@ -4341,21 +4329,6 @@
...
@@ -4341,21 +4329,6 @@
"url"
:
"https://github.com/sponsors/sindresorhus"
"url"
:
"https://github.com/sponsors/sindresorhus"
}
}
},
},
"node_modules/typescript"
:
{
"version"
:
"5.7.3"
,
"resolved"
:
"https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz"
,
"integrity"
:
"sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw=="
,
"license"
:
"Apache-2.0"
,
"optional"
:
true
,
"peer"
:
true
,
"bin"
:
{
"tsc"
:
"bin/tsc"
,
"tsserver"
:
"bin/tsserver"
},
"engines"
:
{
"node"
:
">=14.17"
}
},
"node_modules/ufo"
:
{
"node_modules/ufo"
:
{
"version"
:
"1.5.4"
,
"version"
:
"1.5.4"
,
"resolved"
:
"https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz"
,
"resolved"
:
"https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz"
,
...
@@ -4363,15 +4336,6 @@
...
@@ -4363,15 +4336,6 @@
"dev"
:
true
,
"dev"
:
true
,
"license"
:
"MIT"
"license"
:
"MIT"
},
},
"node_modules/undici-types"
:
{
"version"
:
"6.20.0"
,
"resolved"
:
"https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz"
,
"integrity"
:
"sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="
,
"dev"
:
true
,
"license"
:
"MIT"
,
"optional"
:
true
,
"peer"
:
true
},
"node_modules/unescape"
:
{
"node_modules/unescape"
:
{
"version"
:
"1.0.1"
,
"version"
:
"1.0.1"
,
"resolved"
:
"https://registry.npmjs.org/unescape/-/unescape-1.0.1.tgz"
,
"resolved"
:
"https://registry.npmjs.org/unescape/-/unescape-1.0.1.tgz"
,
...
...
src/App.vue
浏览文件 @
a9dbe94e
...
@@ -2,7 +2,6 @@
...
@@ -2,7 +2,6 @@
import
{
useTextSelection
,
watchDebounced
,
useClipboard
}
from
'@vueuse/core'
import
{
useTextSelection
,
watchDebounced
,
useClipboard
}
from
'@vueuse/core'
import
{
useFloating
}
from
'@floating-ui/vue'
import
{
useFloating
}
from
'@floating-ui/vue'
import
{
useAI
}
from
'@/composables/useAI'
import
{
useAI
}
from
'@/composables/useAI'
import
{
useUser
}
from
'@/composables/useUser'
const
blacklist
=
[
'saas-x.ezijing.com'
,
'172.16.3.203'
,
'172.16.3.45'
]
const
blacklist
=
[
'saas-x.ezijing.com'
,
'172.16.3.203'
,
'172.16.3.45'
]
...
@@ -32,7 +31,6 @@ watchDebounced(
...
@@ -32,7 +31,6 @@ watchDebounced(
},
},
{
debounce
:
200
,
maxWait
:
1000
}
{
debounce
:
200
,
maxWait
:
1000
}
)
)
const
{
userName
}
=
useUser
()
const
{
ai
,
options
,
messages
,
post
,
isLoading
}
=
useAI
()
const
{
ai
,
options
,
messages
,
post
,
isLoading
}
=
useAI
()
async
function
postMessage
(
content
)
{
async
function
postMessage
(
content
)
{
if
(
!
userChatInput
.
value
)
return
if
(
!
userChatInput
.
value
)
return
...
@@ -44,10 +42,8 @@ async function postMessage(content) {
...
@@ -44,10 +42,8 @@ async function postMessage(content) {
async
function
handleSearch
()
{
async
function
handleSearch
()
{
dialogVisible
.
value
=
true
dialogVisible
.
value
=
true
let
content
=
userChatInput
.
value
const
query
=
userChatInput
.
value
.
trim
().
replace
(
/
\s
+/g
,
' '
)
if
(
userName
.
value
)
{
const
content
=
`请用通俗易懂的语言解释以下内容:\n\n
${
query
}
`
content
=
`我是
${
userName
.
value
}
,请帮我查询有关
${
userChatInput
.
value
}
的信息`
}
await
postMessage
(
content
)
await
postMessage
(
content
)
}
}
async
function
handleSend
()
{
async
function
handleSend
()
{
...
...
src/composables/useAI.js
浏览文件 @
a9dbe94e
import
md5
from
'blueimp-md5'
import
{
useStorage
}
from
'@vueuse/core'
import
{
fetchEventSource
}
from
'@fortaine/fetch-event-source'
import
axios
from
'axios'
export
function
useAI
()
{
export
function
useAI
()
{
// AI 配置列表
// AI 配置列表
const
options
=
[
const
options
=
[
{
label
:
'文心一言'
,
value
:
'yiyan'
},
//
{ label: '文心一言', value: 'yiyan' },
{
label
:
'DeepSeek'
,
value
:
'deepseek'
},
{
label
:
'DeepSeek'
,
value
:
'deepseek'
},
{
label
:
'通义千问'
,
value
:
'qwen'
},
//
{ label: '通义千问', value: 'qwen' },
{
label
:
'天工'
,
value
:
'tiangong'
},
//
{ label: '天工', value: 'tiangong' },
]
]
const
ai
=
useStorage
(
'ai'
,
'tiangong
'
)
const
ai
=
ref
(
'deepseek
'
)
const
messages
=
ref
([])
const
messages
=
ref
([])
const
isLoading
=
ref
(
false
)
const
isLoading
=
ref
(
false
)
async
function
post
(
data
)
{
async
function
post
(
data
)
{
isLoading
.
value
=
true
isLoading
.
value
=
true
try
{
try
{
switch
(
ai
.
value
)
{
await
deepseek
(
data
)
case
'yiyan'
:
await
yiyan
(
data
)
break
case
'deepseek'
:
await
siliconflow
(
data
)
break
case
'qwen'
:
await
qwen
(
data
)
break
case
'tiangong'
:
await
tiangong
(
data
)
break
default
:
throw
new
Error
(
'未找到对应的 AI 配置'
)
}
}
catch
(
err
)
{
}
catch
(
err
)
{
console
.
error
(
'AI 请求失败:'
,
err
)
console
.
error
(
'AI 请求失败:'
,
err
)
}
finally
{
}
finally
{
...
@@ -42,123 +22,61 @@ export function useAI() {
...
@@ -42,123 +22,61 @@ export function useAI() {
}
}
}
}
// 文心一言
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
// DeepSeek
async
function
deepseek
(
data
)
{
async
function
deepseek
(
data
)
{
const
apiKey
=
'sk-f1a6f0a7013241de8393cb2cb108e777'
const
apiKey
=
'sk-ezj-kZBEyE-OncdWaQJxRAbAy6L_ApqVlfga'
const
resp
=
await
axios
.
post
(
messages
.
value
.
push
({
role
:
'assistant'
,
content
:
''
})
'/api/deepseek/chat/completions'
,
const
messageIndex
=
messages
.
value
.
length
-
1
{
const
response
=
await
fetch
(
'https://node-server.ezijing.com/ai/chat/completions'
,
{
model
:
'deepseek-chat'
,
method
:
'POST'
,
headers
:
{
'Content-Type'
:
'application/json'
,
Authorization
:
`Bearer
${
apiKey
}
`
},
body
:
JSON
.
stringify
({
model
:
'deepseek-v4-1-flash'
,
messages
:
[{
role
:
'user'
,
content
:
data
.
content
}],
messages
:
[{
role
:
'user'
,
content
:
data
.
content
}],
},
stream
:
true
,
{
thinking
:
{
type
:
'disabled'
},
headers
:
{
'Content-Type'
:
'application/json'
,
Authorization
:
`Bearer
${
apiKey
}
`
},
}),
}
})
)
if
(
!
response
.
ok
)
throw
new
Error
(
`DeepSeek 请求失败:
${
response
.
status
}
`
)
if
(
resp
.
data
)
{
if
(
!
response
.
body
)
throw
new
Error
(
'DeepSeek 响应不支持流式读取'
)
const
[
choice
=
{}]
=
resp
.
data
.
choices
messages
.
value
.
push
({
role
:
'assistant'
,
content
:
choice
.
message
.
content
.
replaceAll
(
'
\
n'
,
'<br/>'
)
})
}
}
// 硅基流动
const
reader
=
response
.
body
.
getReader
()
async
function
siliconflow
(
data
)
{
const
decoder
=
new
TextDecoder
()
const
apiKey
=
'sk-bivnwauskdbvpspvmdorrgkrpwlyfxbfcezqsfsevowzubdj'
let
buffer
=
''
const
resp
=
await
axios
.
post
(
let
finished
=
false
'/api/siliconflow/v1/chat/completions'
,
{
model
:
'deepseek-ai/DeepSeek-V3'
,
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/>'
)
})
}
}
// 天工
while
(
!
finished
)
{
async
function
tiangong
(
data
)
{
const
{
value
,
done
}
=
await
reader
.
read
()
const
appKey
=
'a8701b73637562d33a53c668a90ee3be'
buffer
+=
decoder
.
decode
(
value
,
{
stream
:
!
done
})
const
appSecret
=
'e191593f486bb88a39c634f46926762dddc97b9082e192af'
finished
=
done
const
timestamp
=
Math
.
floor
(
Date
.
now
()
/
1000
)
const
sign
=
md5
(
`
${
appKey
}${
appSecret
}${
timestamp
}
`
)
return
await
fetchEventSource
(
'/api/tiangong/sky-saas-writing/api/v1/chat'
,
{
let
boundary
=
buffer
.
search
(
/
\r?\n\r?\n
/
)
method
:
'POST'
,
while
(
boundary
!==
-
1
)
{
headers
:
{
'Content-Type'
:
'application/json'
,
app_key
:
appKey
,
sign
,
timestamp
,
stream
:
'true'
},
const
frame
=
buffer
.
slice
(
0
,
boundary
)
body
:
JSON
.
stringify
({
const
separator
=
buffer
.
slice
(
boundary
).
match
(
/^
\r?\n\r?\n
/
)[
0
]
chat_history
:
[{
role
:
'user'
,
content
:
data
.
content
}],
buffer
=
buffer
.
slice
(
boundary
+
separator
.
length
)
stream_resp_type
:
'update'
,
const
eventData
=
frame
}),
.
split
(
/
\r?\n
/
)
async
onopen
(
response
)
{
.
filter
((
line
)
=>
line
.
startsWith
(
'data:'
))
console
.
log
(
response
)
.
map
((
line
)
=>
line
.
slice
(
5
).
replace
(
/^ /
,
''
))
if
(
response
.
ok
)
{
.
join
(
'
\
n'
)
return
response
}
else
{
if
(
eventData
&&
eventData
!==
'[DONE]'
)
{
throw
response
const
chunk
=
JSON
.
parse
(
eventData
)
}
const
content
=
chunk
.
choices
?.[
0
]?.
delta
?.
content
},
if
(
content
)
{
onmessage
(
res
)
{
messages
.
value
[
messageIndex
]
=
{
console
.
log
(
res
.
data
)
...
messages
.
value
[
messageIndex
],
const
message
=
JSON
.
parse
(
res
.
data
)
content
:
messages
.
value
[
messageIndex
].
content
+
content
.
replaceAll
(
'
\
n'
,
'<br/>'
),
if
(
message
.
type
!==
1
)
return
}
const
messageId
=
message
.
conversation_id
await
nextTick
()
const
messageIndex
=
messages
.
value
.
findIndex
((
message
)
=>
message
.
id
===
messageId
)
await
new
Promise
((
resolve
)
=>
requestAnimationFrame
(
resolve
))
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
},
boundary
=
buffer
.
search
(
/
\r?\n\r?\n
/
)
onerror
(
err
)
{
}
isLoading
.
value
=
false
}
throw
err
},
})
}
}
return
{
ai
,
options
,
post
,
messages
,
isLoading
}
return
{
ai
,
options
,
post
,
messages
,
isLoading
}
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论