提交 6b10e913 作者: 吴佳伟

Merge branch 'main' of https://gitlab.yiring.com/digital-agri/agri-app into dev

{
"name": "数字农服",
"version": "1.0.14",
"version": "1.0.15",
"description": "数字农服",
"keywords": [
"app",
......
......@@ -3,7 +3,9 @@ import { otherHttp } from '/@/utils/http/axios'
enum Api {
getUserInfo = '/sys/user/login/setting/getUserData', // 查询登录用户信息
logout = '/sys/logout', // 登出
sysLogin = '/app/user/login', // 登陆
sysLogin = '/sys/mLogin', // 登陆
phoneLogin = '/sys/phoneLogin',
sms = '/sys/sms',
dictList = '/sys/dict/queryAllDictItems', // 获取字典数据
location = '/tianditu/geocode', // 根据经纬度获取地址
sysSmsCode = '/app/user/getSmsCode', // 短信验证码
......@@ -32,6 +34,28 @@ export function sysLogin(params = {}) {
}
/**
* 手机号登录
* @param params 参数
*/
export function phoneLogin(params = {}) {
return otherHttp.post({
url: Api.phoneLogin,
data: params
})
}
/**
* @param params 请求参数
* @description: 获取短信验证码
*/
export function sysSms(params = {}) {
return otherHttp.post({
url: Api.sms,
data: params
})
}
/**
* @param params 请求参数
* @description: 退出登录
*/
......
<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>
......@@ -2,8 +2,8 @@
"name": "数字农服",
"appid": "__UNI__FD09823",
"description": "数字农服 APP",
"versionName": "1.0.14",
"versionCode": 10014,
"versionName": "1.0.15",
"versionCode": 10015,
"transformPx": false,
"locale": "zh-Hans",
"vueVersion": "3",
......
......@@ -442,6 +442,38 @@
}
}
}
},
// === AI 聊天助手 ===
{
"path": "pages/common/chat/index",
"style": {
"navigationStyle": "custom",
"navigationBarTextStyle": "black",
"backgroundColor": "#ffffff",
// #ifdef H5
"titleNView": false,
// #endif
"disableScroll": true,
"app-plus": {
"titleNView": false,
"bounce": "none"
}
}
},
{
"path": "pages/common/chat/webview",
"style": {
"navigationStyle": "custom",
"backgroundColor": "#ffffff",
// #ifdef H5
"titleNView": false,
// #endif
"disableScroll": true,
"app-plus": {
"titleNView": false,
"bounce": "none"
}
}
}
],
"easycom": {
......
......@@ -392,7 +392,7 @@
</view>
</view>
</view>
<fui-fab position="right" distance="10" bottom="240" width="96" @click="handlePublish">
<fui-fab position="right" distance="30" bottom="150" width="96" @click="handlePublish">
<view v-show="pageData.currentTransactionTab === 1" class="text-white text-center">
<view class="fab-icon" />
<view style="font-size: 24rpx">发布</view>
......
<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>
<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>
......@@ -251,8 +251,15 @@
console.log('点击助农金融产品:', product)
// 在这里添加具体的产品点击逻辑
// 跳转到助农金融界面
if (product.name === '惠农贷') {
Navigate.to('/pages/zhunongjinrong/zhunongjinrong?id=1')
} else if (product.name === '灾害险') {
Navigate.to('/pages/zhunongjinrong/zhunongjinrong?id=3')
} else {
Navigate.to('/pages/zhunongjinrong/zhunongjinrong')
}
}
// 查看全部助农金融产品
function onViewAllFinancialProducts() {
......
......@@ -64,6 +64,13 @@
countdown: 0, // 倒计时秒数
countdownTimer: null, // 倒计时定时器
form: {
phoneRules: [
{
name: 'username',
rule: ['required'],
msg: ['请输入手机号'],
},
],
rules: [
{
name: 'username',
......@@ -112,13 +119,13 @@
if (res.isPassed) {
// 登录参数
const params = {
username: model.form.data.username,
mobile: model.form.data.username,
captcha: model.form.data.code,
}
// 短信登录
model.loading = true
API.sysLogin(params)
API.phoneLogin(params)
.then(async (body) => {
console.log('body', body)
if (body) {
......@@ -147,7 +154,7 @@
* 获取验证码
*/
function smsCode() {
form?.value.validator(model.form.data, model.form.rulesPhone).then(async (res: { isPassed: boolean }) => {
form?.value.validator(model.form.data, model.form.phoneRules).then(async (res: { isPassed: boolean }) => {
if (res.isPassed) {
// 如果已经在倒计时中,不重复发送
if (model.countdown > 0) {
......@@ -155,10 +162,12 @@
}
const params = {
phone: model.form.data.phone,
mobile: model.form.data.username,
smsmode: '0',
}
API.sysSmsCode(params)
API.sysSms(params)
.then(async (body) => {
Message.toast('验证码已发送')
console.log('body', body)
// 开始倒计时
startCountdown()
......@@ -269,7 +278,7 @@
<!-- <text class="text-#999 text-24">{{ '*小程序仅供内部员工使用' }}</text> -->
</view>
</view>
<fui-form class="form" ref="form" top="50" :padding="['0rpx', '32rpx']">
<fui-form class="form" ref="form" top="50" :padding="['0rpx', '32rpx']" background="#e46962">
<fui-input
height="100rpx"
class="input"
......
......@@ -87,10 +87,12 @@
}
const params = {
phone: model.form.data.phone,
mobile: model.form.data.phone,
smsmode: 1,
}
API.sysSmsCode(params)
API.sysSms(params)
.then(async (body) => {
Message.toast('验证码已发送')
console.log('body', body)
// 开始倒计时
startCountdown()
......@@ -182,7 +184,7 @@
<view class="logo-text">数字农业服务平台</view>
</view>
</view>
<fui-form class="form" ref="form" top="50" :padding="['0rpx', '32rpx']">
<fui-form class="form" ref="form" top="50" :padding="['0rpx', '32rpx']" background="#e46962">
<view class="reigister-form-item">
<image class="reigister-form-image" src="/static/images/register/user.png" />
<text>手机号</text>
......
......@@ -335,6 +335,8 @@
function onViewFinancialServices() {
console.log('查看金融服务')
// 在这里添加具体的查看逻辑
Navigate.to('/pages/zhunongjinrong/zhunongjinrong')
}
// 查看更多农技学习
......@@ -784,7 +786,7 @@
:title="video.title"
:controls="true"
style="width: 654rpx; height: 358rpx"
:autoplay="true"
:autoplay="false"
:muted="false"
:loop="true"
:show-play-btn="true"
......@@ -801,18 +803,16 @@
</swiper-item>
</swiper>
</fui-swiper-dot>
<view class="describe">
<view class="describe relative">
<text class="codefun-self-start font text_34">{{ pageData.agricultureClass.title }}</text>
<view
class="codefun-flex-row codefun-justify-between codefun-items-center codefun-self-stretch mt-13"
>
<!-- <view class="codefun-flex-row codefun-items-center">
<image
class="codefun-shrink-0 image_15"
src="/static/images/codefun/893f216142f5ca20cf9f2496d9b793c8.png"
src="/static/images/codefun/play.png"
mode="scaleToFill"
class="absolute w-64 h-64 top--150 left-275"
/>
<text class="font_14 text_35 ml-5">{{ pageData.agricultureClass.expert }}</text>
</view> -->
<text class="font_14 text_36">{{ pageData.agricultureClass.time }}</text>
</view>
</view>
......@@ -1836,7 +1836,6 @@
.section_20 {
position: relative;
margin-right: 28rpx;
margin-top: 32.86rpx;
height: 418rpx;
// padding: 271.06rpx 36.64rpx 22rpx 48rpx;
padding: 20rpx;
......
<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">
......
......@@ -7,6 +7,7 @@
import * as HomeAPI from '@/api/model/home'
import * as UserAPI from '@/api/model/userInfo'
import { useDictStore } from '@/store/modules/dict'
import Navigate from '@/utils/page/navigate'
const dictStore = useDictStore()
const model = reactive({
......@@ -362,7 +363,30 @@
console.log('点击菜单项:', item)
// 在这里添加具体的菜单点击逻辑
Message.toast(item.name)
if (item.jump_target?.startsWith('/')) {
const tabbarKeyWords = [
'/pages/shouye/shouye',
'/pages/nongchang/nongchang',
'/pages/fuwu/fuwu',
'/pages/chanxiao/chanxiao',
]
if (tabbarKeyWords.includes(item.jump_target)) {
uni.switchTab({
url: item.jump_target,
})
} else {
Navigate.to(item.jump_target).catch(() => {
Message.alert(`${item.jump_target} 页面打开失败`, item.name)
})
}
} else if (item.jump_target?.startsWith('http')) {
Navigate.webview(item.jump_target, item.name)
} else {
uni.showModal({
title: item.name,
content: '功能开发中...',
})
}
}
// 农产品关注点击事件
......@@ -450,6 +474,17 @@
videoContext.play()
}
function onClickWarning(item) {
console.log('点击预警信息:', item)
// 在这里添加具体的点击逻辑
uni.showModal({
title: '预警信息',
content: item.title,
showCancel: false,
})
}
onHide(() => {
// 停止所有其他视频的播放(只暂停,不重置位置)
pageData.agricultureClass.videoList.forEach((_, index) => {
......@@ -628,6 +663,7 @@
v-for="item of pageData.newsItems"
:key="item.id"
class="codefun-flex-col"
@click="onClickWarning(item)"
>
<view class="codefun-flex-row codefun-items-baseline" style="align-items: center">
<view class="font_5 text_17">最新预警</view>
......@@ -730,8 +766,9 @@
<text
class="font_13"
:class="`text_${stat.id === 1 ? 30 : stat.id === 2 ? 1 : stat.id > 4 ? 46 : 37}`"
>{{ stat.name }}</text
>
{{ stat.name }}
</text>
</view>
<view class="codefun-flex-row codefun-justify-center codefun-items-baseline mt-11 group_30">
<text class="font_12 text_37">{{ stat.num }}</text>
......@@ -782,7 +819,7 @@
:title="video.title"
:controls="true"
style="width: 654rpx; height: 358rpx"
:autoplay="true"
:autoplay="false"
:muted="false"
:loop="true"
:show-play-btn="true"
......@@ -799,18 +836,16 @@
</swiper-item>
</swiper>
</fui-swiper-dot>
<view class="describe">
<view class="describe relative">
<text class="codefun-self-start font text_34">{{ pageData.agricultureClass.title }}</text>
<view
class="codefun-flex-row codefun-justify-between codefun-items-center codefun-self-stretch mt-13"
>
<!-- <view class="codefun-flex-row codefun-items-center">
<image
class="codefun-shrink-0 image_15"
src="/static/images/codefun/893f216142f5ca20cf9f2496d9b793c8.png"
src="/static/images/codefun/play.png"
mode="scaleToFill"
class="absolute w-64 h-64 top--150 left-275"
/>
<text class="font_14 text_35 ml-5">{{ pageData.agricultureClass.expert }}</text>
</view> -->
<text class="font_14 text_36">{{ pageData.agricultureClass.time }}</text>
</view>
</view>
......@@ -1389,7 +1424,7 @@
}
.section_8 {
padding: 15.38rpx 0 12rpx;
padding: 16rpx 0 16rpx;
background-color: #ffffff;
border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH;
......
......@@ -18,12 +18,12 @@ export default {
* 服务协议地址
* @description TODO: 服务协议地址需要根据实际情况进行修改
*/
services: 'https://app.yiring.com/services.html',
services: 'https://app.yiring.com/agri/services.html',
/**
* 隐私政策地址
* @description TODO: 隐私政策地址需要根据实际情况进行修改
*/
privacy: 'https://app.yiring.com/privacy.html',
privacy: 'https://app.yiring.com/agri/privacy.html',
},
/**
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论