Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
basic-uniapp-v3
概览
概览
详情
活动
周期分析
版本库
存储库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
1
合并请求
1
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
Basic
basic-uniapp-v3
Commits
74a5f17c
提交
74a5f17c
authored
11月 11, 2025
作者:
方治民
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: 新增 AI 农技助手、农业大模型步骤弹窗提示
上级
8754aa1b
隐藏空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
348 行增加
和
5 行删除
+348
-5
chat.html
src/hybrid/html/chat.html
+137
-0
pages.json
src/pages.json
+32
-0
index.vue
src/pages/common/chat/index.vue
+129
-0
webview.vue
src/pages/common/chat/webview.vue
+19
-0
nongyedamoxing.vue
src/pages/nongyedamoxing/nongyedamoxing.vue
+31
-5
没有找到文件。
src/hybrid/html/chat.html
0 → 100644
浏览文件 @
74a5f17c
<html
lang=
"en"
>
<head>
<meta
charset=
"UTF-8"
/>
<meta
content=
"width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0,viewport-fit=cover"
name=
"viewport"
/>
<title>
AI Chat
</title>
<style>
body
{
margin
:
0
;
padding
:
0
;
font-family
:
-apple-system
,
BlinkMacSystemFont
,
'Segoe UI'
,
Roboto
,
'Helvetica Neue'
,
Arial
,
sans-serif
;
background-color
:
#fff
;
}
#chat-bot
{
position
:
fixed
;
inset
:
0
;
z-index
:
9999
;
box-sizing
:
border-box
;
/*
兼容
iOS
<
11.2
*/
padding-bottom
:
constant
(
safe-area-inset-bottom
);
/* 兼容 iOS >= 11.2 */
padding-bottom
:
env
(
safe-area-inset-bottom
);
/*
兼容
iOS
<
11.2
*/
padding-top
:
constant
(
safe-area-inset-top
);
/* 兼容 iOS >= 11.2 */
padding-top
:
env
(
safe-area-inset-top
);
}
.close-btn
{
z-index
:
99999
;
position
:
absolute
;
right
:
12px
;
top
:
calc
(
18px
+
constant
(
safe-area-inset-top
));
top
:
calc
(
18px
+
env
(
safe-area-inset-top
));
padding
:
8px
;
}
.android
#chat-bot
{
/*
兼容
iOS
<
11.2
*/
padding-top
:
calc
(
18px
+
constant
(
safe-area-inset-top
));
/* 兼容 iOS >= 11.2 */
padding-top
:
calc
(
18px
+
env
(
safe-area-inset-top
));
}
.android
.close-btn
{
/*
兼容
iOS
<
11.2
*/
top
:
calc
(
18px
+
18px
+
constant
(
safe-area-inset-top
));
/* 兼容 iOS >= 11.2 */
top
:
calc
(
18px
+
18px
+
env
(
safe-area-inset-top
));
}
</style>
</head>
<body>
<script
type=
"text/javascript"
src=
"https://hntq-res.oss-cn-shenzhen.aliyuncs.com/uni.webview.1.5.6.js"
></script>
<script
type=
"text/javascript"
>
const
u
=
navigator
.
userAgent
const
isAndroid
=
u
.
includes
(
'Android'
)
||
u
.
includes
(
'Adr'
)
if
(
isAndroid
)
{
document
.
body
.
classList
.
add
(
'android'
)
}
// 待触发 `UniAppJSBridgeReady` 事件后,即可调用 uni 的 API。
document
.
addEventListener
(
'UniAppJSBridgeReady'
,
function
()
{
// 添加关闭按钮
const
div
=
document
.
createElement
(
'div'
)
div
.
className
=
'close-btn'
div
.
innerHTML
=
'<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24"><path fill="#666" d="m12 13.4l-4.9 4.9q-.275.275-.7.275t-.7-.275t-.275-.7t.275-.7l4.9-4.9l-4.9-4.9q-.275-.275-.275-.7t.275-.7t.7-.275t.7.275l4.9 4.9l4.9-4.9q.275-.275.7-.275t.7.275t.275.7t-.275.7L13.4 12l4.9 4.9q.275.275.275.7t-.275.7t-.7.275t-.7-.275z"/></svg>'
div
.
onclick
=
function
()
{
uni
.
navigateBack
()
}
document
.
body
.
appendChild
(
div
)
})
</script>
<div
id=
"chat-bot"
></div>
<script
src=
"https://lf-cdn.coze.cn/obj/unpkg/flow-platform/chat-app-sdk/1.1.0-beta.0/libs/cn/index.js"
></script>
<script>
function
getUrlParams
(
url
)
{
const
paramsObj
=
{}
if
(
!
url
)
{
url
=
window
.
location
.
href
}
const
questionIndex
=
url
.
indexOf
(
'?'
)
if
(
questionIndex
!==
-
1
)
{
const
paramStr
=
url
.
slice
(
questionIndex
+
1
)
const
paramArr
=
paramStr
.
split
(
'&'
)
paramArr
.
forEach
((
param
)
=>
{
const
[
key
,
value
]
=
param
.
split
(
'='
)
paramsObj
[
key
]
=
decodeURIComponent
(
value
)
})
}
return
paramsObj
}
const
params
=
getUrlParams
()
const
cozeWebSDK
=
new
CozeWebSDK
.
WebChatClient
({
config
:
{
bot_id
:
'7571349247409979402'
,
},
userInfo
:
{
id
:
params
.
userId
,
url
:
'https://hntq.yiring.com/minio/public/system/ai/hntq-ai-user-2.png'
,
// nickname: "壹润科技",
},
ui
:
{
base
:
{
layout
:
'mobile'
,
lang
:
'zh-CN'
,
icon
:
'https://hntq.yiring.com/minio/public/system/ai/hntq-ai-logo.png'
,
},
header
:
{
isNeedClose
:
false
,
},
footer
:
{
isShow
:
false
,
},
chatBot
:
{
title
:
'AI 农技助手'
,
uploadable
:
false
,
el
:
document
.
getElementById
(
'chat-bot'
),
},
asstBtn
:
{
isNeed
:
false
,
},
},
})
cozeWebSDK
.
showChatBot
()
</script>
</body>
</html>
src/pages.json
浏览文件 @
74a5f17c
...
...
@@ -442,6 +442,38 @@
}
}
}
},
//
===
AI
聊天助手
===
{
"path"
:
"pages/common/chat/index"
,
"style"
:
{
"navigationStyle"
:
"custom"
,
"navigationBarTextStyle"
:
"black"
,
"backgroundColor"
:
"#ffffff"
,
//
#ifdef
H
5
"titleNView"
:
false
,
//
#endif
"disableScroll"
:
true
,
"app-plus"
:
{
"titleNView"
:
false
,
"bounce"
:
"none"
}
}
},
{
"path"
:
"pages/common/chat/webview"
,
"style"
:
{
"navigationStyle"
:
"custom"
,
"backgroundColor"
:
"#ffffff"
,
//
#ifdef
H
5
"titleNView"
:
false
,
//
#endif
"disableScroll"
:
true
,
"app-plus"
:
{
"titleNView"
:
false
,
"bounce"
:
"none"
}
}
}
],
"easycom"
:
{
...
...
src/pages/common/chat/index.vue
0 → 100644
浏览文件 @
74a5f17c
<
script
lang=
"ts"
setup
>
const
page
=
reactive
({
security
:
false
,
title
:
''
,
link
:
''
,
styles
:
{
progress
:
{
color
:
'#42c02e'
,
height
:
'1%'
,
},
},
})
onLoad
(({
title
,
link
,
sub
})
=>
{
page
.
title
=
title
?
decodeURIComponent
(
title
)
:
''
page
.
link
=
decodeURIComponent
(
link
)
// 嵌入页面进行二级子页面跳转时,参数会被多次 encode
if
(
sub
)
{
page
.
title
=
decodeURIComponent
(
page
.
title
)
page
.
link
=
decodeURIComponent
(
page
.
link
)
}
if
(
!
link
)
{
Message
.
toast
(
'页面打开失败,参数错误'
)
uni
.
navigateBack
()
return
}
// 设置标题栏为文件名
if
(
page
.
title
&&
page
.
title
!==
'undefined'
)
{
uni
.
setNavigationBarTitle
({
title
:
page
.
title
,
})
}
Message
.
loading
()
// #ifdef APP-PLUS
const
system
=
uni
.
getSystemInfoSync
()
// 对于不安全或不信任的网站地址或可能触发 plus API 的来源,采用手动创建 webview 的方式打开
const
webview
=
plus
.
webview
.
create
(
page
.
link
,
'no-security-webview'
,
{
progress
:
page
.
styles
.
progress
,
})
// FIXED: 处理 iOS 下意外的高度兼容性问题
if
(
system
.
platform
===
'ios'
)
{
webview
.
setStyle
({
popGesture
:
'none'
,
scrollIndicator
:
'none'
,
// top: `${system.statusBarHeight}px`,
bottom
:
`
${
system
.
safeAreaInsets
.
bottom
}
px`
,
background
:
'transparent'
,
statusbar
:
{
background
:
'#ffffff'
},
})
}
webview
.
addEventListener
(
'loaded'
,
()
=>
{
// FIX: classId 可能随着每个 Web SDK 版本会更新,需要注意,一旦发生变更可能会丢失部分样式(用户头像)
const
classId
=
'ca5e07ec94ad125e02ca'
let
paddingTop
=
`
${
system
.
statusBarHeight
}
px`
if
(
system
.
platform
===
'ios'
)
{
paddingTop
=
'0px'
}
webview
.
appendJsFile
(
'_www/static/uni.webview.1.5.6.js'
)
webview
.
evalJS
(
`
document.addEventListener('UniAppJSBridgeReady', function() {
uni.getEnv(function(res) {
console.log('当前环境:' + JSON.stringify(res));
})
})
// 禁止页面缩放
var meta = document.createElement('meta')
meta.name = 'viewport'
meta.content = 'width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no'
document.head.appendChild(meta)
// 隐藏底部描述和图片上传能力
var style = document.createElement('style')
style.id = 'no-security-webview-style'
style.innerHTML = 'footer { display: none !important; } .close-btn { z-index: 99999; position: absolute; right: 12px; top: calc(18px +
${
paddingTop
}
); padding: 8px; } html { padding-top:
${
paddingTop
}
; background: white; } .semi-avatar>img { border-radius: 50% !important; } .
${
classId
}
-content>div:last-child .semi-avatar-img img { opacity: 0; } .
${
classId
}
-content>div:last-child .semi-avatar-img { position: relative; background-image: url(https://hntq.yiring.com/minio/public/system/ai/hntq-ai-user-2.png); background-size: cover; background-position: center; }'
document.body.appendChild(style)
// 添加关闭按钮
var div = document.createElement('div')
div.className = 'close-btn'
div.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24"><path fill="#666" d="m12 13.4l-4.9 4.9q-.275.275-.7.275t-.7-.275t-.275-.7t.275-.7l4.9-4.9l-4.9-4.9q-.275-.275-.275-.7t.275-.7t.7-.275t.7.275l4.9 4.9l4.9-4.9q.275-.275.7-.275t.7.275t.275.7t-.275.7L13.4 12l4.9 4.9q.275.275.275.7t-.275.7t-.7.275t-.7-.275z"/></svg>'
div.onclick = function() {
uni.navigateBack()
}
document.body.appendChild(div)
setTimeout(() => {
var header = document.querySelector('header')
if (!header) {
var ok = confirm('抱歉,发现了不兼容的问题,请您检查系统版本是否过于旧,欢迎升级后再尝试体验,感谢您的支持~')
uni.navigateBack()
}
}, 5000);
`
)
},
false
,
)
const
pages
=
getCurrentPages
()
const
currentPage
=
pages
[
pages
.
length
-
1
]
const
currentWebview
=
currentPage
.
$getAppWebview
()
currentWebview
.
setStyle
({
progress
:
page
.
styles
.
progress
,
popGesture
:
'none'
})
currentWebview
.
append
(
webview
)
// #endif
// #ifndef APP-PLUS
page
.
security
=
true
// #endif
setTimeout
(()
=>
{
Message
.
hideLoading
()
},
2000
)
})
</
script
>
<
template
>
<view
class=
"wrap"
v-if=
"page.link"
>
<template
v-if=
"page.security"
>
<web-view
:src=
"page.link"
:update-title=
"!page.title"
:webview-styles=
"page.styles"
/>
</
template
>
</view>
</template>
src/pages/common/chat/webview.vue
0 → 100644
浏览文件 @
74a5f17c
<
script
setup
lang=
"ts"
>
const
webviewStyles
=
reactive
({
progress
:
{
color
:
'#42c02e'
,
height
:
'1%'
,
},
})
const
src
=
ref
<
string
>
()
onLoad
(({
token
,
userId
})
=>
{
src
.
value
=
`/hybrid/html/chat.html?token=
${
token
}
&userId=
${
userId
}
`
})
</
script
>
<
template
>
<view>
<web-view
:webview-styles=
"webviewStyles"
:src=
"src"
/>
</view>
</
template
>
src/pages/nongyedamoxing/nongyedamoxing.vue
浏览文件 @
74a5f17c
<
script
setup
lang=
"ts"
></
script
>
<
script
setup
lang=
"ts"
>
import
{
useUserStore
}
from
'@/store/modules/user'
const
userStore
=
useUserStore
()
function
openAITools
()
{
uni
.
navigateTo
({
animationType
:
'slide-in-bottom'
,
// 最新版 SDK Webview 嵌入版本,支持绑定用户 ID,支持自定义样式等
url
:
`/pages/common/chat/webview?token=&userId=
${
userStore
.
getUserInfo
?.
id
}
`,
})
}
function openStep() {
uni.showModal({
title: '温馨提示',
content: '此处仅为信息展示显示',
showCancel: false,
})
}
</
script
>
<
template
>
<view
class=
"codefun-flex-col page"
>
...
...
@@ -115,7 +135,7 @@
<view
class=
"codefun-flex-col codefun-mt-24"
>
<text
class=
"codefun-self-start font text_20"
>
三步上手
</text>
<view
class=
"codefun-flex-row codefun-items-start equal-division_2 section_7 codefun-mt-16"
>
<view
class=
"codefun-flex-col equal-division-item_4 group_16"
>
<view
class=
"codefun-flex-col equal-division-item_4 group_16"
@
click=
"openStep"
>
<image
class=
"codefun-self-center image_13"
src=
"/static/images/codefun/8d95c077ff410c467d25f1d02b84cd3c.png"
...
...
@@ -125,7 +145,7 @@
<text
class=
"codefun-self-stretch font_10 text_23 codefun-mt-4"
>
填写果园基本信息
</text>
</view>
</view>
<view
class=
"codefun-flex-col equal-division-item_5 group_17"
>
<view
class=
"codefun-flex-col equal-division-item_5 group_17"
@
click=
"openStep"
>
<image
class=
"codefun-self-center image_14"
src=
"/static/images/codefun/e4453ccb0959797614bc6ffb5d62d56f.png"
...
...
@@ -141,7 +161,10 @@
<text
class=
"codefun-self-center font_10 text_24"
>
根据需求选择适用模型
</text>
</view>
</view>
<view
class=
"codefun-flex-row codefun-justify-between equal-division-item_6 group_18"
>
<view
class=
"codefun-flex-row codefun-justify-between equal-division-item_6 group_18"
@
click=
"openStep"
>
<image
class=
"codefun-self-start image_9 image_17"
src=
"/static/images/codefun/b31cf305e90b1547bca2725e5a2ea5be.png"
...
...
@@ -161,7 +184,10 @@
</view>
<view
class=
"codefun-flex-col codefun-mt-24"
>
<text
class=
"codefun-self-start font text_26"
>
AI农技助手
</text>
<view
class=
"codefun-flex-col codefun-self-stretch codefun-relative section_8 codefun-mt-16"
>
<view
class=
"codefun-flex-col codefun-self-stretch codefun-relative section_8 codefun-mt-16"
@
click=
"openAITools"
>
<text
class=
"codefun-self-start font_2 text_27"
>
Hi~有什么可以帮您吗?
</text>
<view
class=
"codefun-flex-col codefun-self-stretch group_21"
>
<view
class=
"codefun-flex-col codefun-justify-start codefun-items-start text-wrapper_3"
>
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论