20260325稳定版

This commit is contained in:
2026-03-25 15:54:56 +08:00
parent f2ef63d910
commit 7b30030d9b
22 changed files with 1391 additions and 58 deletions
+61 -19
View File
@@ -3,6 +3,7 @@
<HeaderItem title="AI律师咨询"/>
<view style="line-height: 35rpx"
class="flex flex-col justify-start items-start text-25 p-30">
<view class="text-25 text-gray text-center my-15 w-100p">该内容由人工智能生成</view>
<view v-for="(item, index) in list" :key="index" class="mb-25 w-100p">
<view v-if="!item.isMine" class="flex justify-start items-start">
<u-icon name="/static/robot.png" size="60rpx"/>
@@ -46,6 +47,7 @@
</view>
</view>
</view>
<Login ref="Login" @done="onLoginDone"/>
</view>
</template>
@@ -57,17 +59,20 @@ import {sendChatReq, stopChatReq} from "@/api/lawOrg";
import {getUserInfo} from "@/util/user";
import {MAIN} from "@/config/color";
import {dictDataReq} from "@/api/common";
import Login from "@/components/Login.vue";
export default {
name: "index",
components: {HeaderItem, CustomTabbar},
components: {Login, HeaderItem, CustomTabbar},
data() {
return {
list: [],
questionList: [],
content: '',
taskId: null,
answering: false
answering: false,
socket: null,
timer: null,
}
},
methods: {
@@ -118,39 +123,76 @@ export default {
}, 100)
},
async stopAI() {
console.log('stoping')
await stopChatReq({
taskId: this.taskId
})
this.answering = false
uni.closeSocket()
this.list[this.list.length - 1].done = true
},
onLoginDone(){
uni.hideLoading()
this.list.push({
content: '您好!我是法律机器人,请问您想咨询什么问题呢?',
isMine: false,
loading: false,
done: true,
})
const _this = this
this.socket = uni.connectSocket({
url: `${WS_API}/${getUserInfo().uid}`,
success: () => {
_this.ping()
},
})
uni.onSocketMessage(res => {
if (res.data === '连接成功') return
const aiData = JSON.parse(res.data)
this.list[this.list.length - 1].loading = false
if (aiData.answer !== '__END__') this.list[this.list.length - 1].content += aiData.answer
this.taskId = aiData.taskId
this.scrollToBottom()
})
},
ping() {
this.timer = setInterval(() => {
if (this.socket) {
this.socket.send({
data: 'ping'
})
}
}, 10000)
}
},
onLoad() {
this.list.push({
content: '您好!我是法律机器人,请问您想咨询什么问题呢?',
isMine: false,
loading: false,
done: true,
})
uni.connectSocket({
url: `${WS_API}/${getUserInfo().uid}`
})
uni.onSocketMessage(res => {
if (res.data === '连接成功') return
const aiData = JSON.parse(res.data)
this.list[this.list.length - 1].loading = false
if (aiData.answer !== '__END__') this.list[this.list.length - 1].content += aiData.answer
this.taskId = aiData.taskId
this.scrollToBottom()
uni.showLoading({
title: '加载中...',
})
this.$refs.Login.doLogin()
this.getQuestionsList()
},
onUnload() {
if (this.timer) clearInterval(this.timer)
uni.closeSocket()
this.stopAI()
},
onHide() {
if (this.timer) clearInterval(this.timer)
uni.closeSocket()
this.stopAI()
},
onShareAppMessage() {
return {
title: "贵港公共法律服务",
path: `/pages/ai/index`
}
},
onShareTimeline() {
return {
title: "贵港公共法律服务",
path: `/pages/ai/index`
}
},
}
</script>
<style scoped>
+74 -12
View File
@@ -1,26 +1,33 @@
<template>
<view class="min-height pos-r bg" style="background-color: #E0F2FE">
<view class="text-white title" :style="{top: top}">贵港公共法律服务</view>
<u-swiper v-if="swiperList.length" :list="swiperList" height="420rpx" indicator :custom-style="{zIndex: 0}"
@click="$jump('/lawOrgPages/pages/action')"/>
<view class="pos-a w-100p" style="left: 0; top: 360rpx">
<view class="card m-25 flex flex-col justify-start items-start shadow"
style="background-color: rgba(255,255,255,0.8); width: calc(100vw - 90rpx); padding-bottom: 45rpx">
<view class="card m-25 flex flex-col justify-start items-start shadow pos-r"
style="background-color: rgba(255,255,255,0.8); width: calc(100vw - 90rpx); padding-bottom: 15rpx">
<view class="tag">
<u-icon name="/static/line.png" size="30rpx"/>
<view>线上办事</view>
</view>
<view class="mt-20 flex justify-around items-center w-100p">
<view class="flex flex-col justify-center items-center shadow rounded-sm p-10"
style="flex: 0 0 20%"
<view class="my-25 w-100p grid-wrap">
<view class="flex flex-col justify-center items-center shadow rounded-sm p-10 mr-15"
style="flex: 0 0 28%; height: 130rpx; margin-bottom: 10rpx"
v-for="(item, index) in navList"
:key="index" @click="$jump(item.url)">
<u-icon :name="`/static/index/${index + 1}.png`" size="80rpx"/>
<u-icon :name="`/static/index/${index + 1}.png`" size="60rpx"/>
<text class=" mt-20" :class="[item.label.length > 5 ? 'text-20' : 'text-25']">{{ item.label }}</text>
</view>
</view>
<!-- <view class="pos-a" style="left: 0; top: 130rpx" v-if="showLeft">-->
<!-- <u-icon name="arrow-left" size="60rpx" color="#049DFF"/>-->
<!-- </view>-->
<!-- <view class="pos-a" style="right: 0; top: 130rpx" v-if="showRight">-->
<!-- <u-icon name="arrow-right" size="60rpx" color="#049DFF"/>-->
<!-- </view>-->
</view>
</view>
<u-gap height="220rpx"></u-gap>
<u-gap height="420rpx"></u-gap>
<view class="p-25">
<TitleItem title="企业法治体检"/>
<view class="circle w-100p mb-20 shadow"
@@ -29,8 +36,9 @@
height: 180rpx"></view>
<TitleItem title="法律自助服务"/>
<view class="flex justify-center items-center flex-wrap">
<view class="card mb-25 flex-1 flex justify-center items-center flex-shrink shadow"
style="flex:0 0 295rpx; border-radius: 16rpx; padding: 25rpx 20rpx "
<view class="card mb-25 flex-1 flex justify-start items-start flex-shrink shadow"
style="border-radius: 16rpx; padding: 25rpx 20rpx "
:style="{flex: '0 0 295rpx'}"
:class="[index % 2 === 0 ? 'mr-15' : 'ml-15']"
v-for="(item, index) in selfNavList"
@click="jump(item.url)"
@@ -51,7 +59,7 @@
style="background-image: url('https://sifa-api.wsdns.cn/api/file/20250419/propagate.png'); background-size: cover;
height: 240rpx"></view>
<TitleItem title="查询服务"/>
<view class="flex justify-center items-center flex-wrap">
<view class="flex justify-start items-center flex-wrap">
<view @click="$jump('/lawOrgPages/pages/map')"
class="card mb-20 flex-1 flex justify-center items-center flex-shrink mr-15 shadow"
style="flex:0 0 295rpx; border-radius: 16rpx; padding: 25rpx 20rpx">
@@ -70,6 +78,15 @@
<text class="text-20 mt-10" style="color: rgb(123, 160, 194)">法律人员机构查询</text>
</view>
</view>
<view @click="copy('https://www.moj.gov.cn/pub/sfbgw/zwgkztzl/2025nianzhuanti/2025gjtyflzyzgks/')"
class="card mb-20 flex-2 flex justify-center items-center flex-shrink shadow"
style="border-radius: 16rpx; padding: 25rpx 20rpx">
<u-icon name="/static/index/微信图片_20251009215218_10897_9.png" size="40rpx"/>
<view class="flex flex-col justify-center items-center ml-15">
<text class="text-28">法律职业资格考试</text>
<text class="text-20 mt-10" style="color: rgb(123, 160, 194)">法律职业资格考试查询</text>
</view>
</view>
</view>
</view>
<u-gap height="100rpx"></u-gap>
@@ -107,6 +124,14 @@ export default {
label: '民事商事仲裁',
url: '/onlineSheetPages/pages/civil'
},
{
label: '行政复议',
url: '/onlineSheetPages/pages/legalReview'
},
{
label: '人民调解',
url: '/onlineSheetPages/pages/legalMediate'
},
],
selfNavList: [
{
@@ -145,7 +170,16 @@ export default {
icon: '/static/index/self_5.png',
url: '/articlePages/pages/search'
},
]
// {
// label: '经济困难申请',
// desc: '经济困难状况申请',
// icon: '/static/index/req.png',
// url: '/onlineSheetPages/pages/economicDifficulty'
// },
],
showLeft: false,
showRight: true,
top: 0
}
},
methods: {
@@ -159,12 +193,23 @@ export default {
if (url === '/pages/ai/index') {
uni.switchTab({url})
} else uni.navigateTo({url})
},
copy(data) {
uni.setClipboardData({
data,
success: function () {
uni.showToast({
title: '复制成功,请到浏览器中粘贴访问',
icon: 'none'
})
}
})
}
},
onLoad() {
// #defif
this.$refs.Login.doLogin()
this.getSwiperList()
this.top = uni.getSystemInfoSync().statusBarHeight + 'px'
},
onShareAppMessage() {
return {
@@ -197,4 +242,21 @@ export default {
padding: 5rpx 15rpx;
border-radius: 6rpx;
}
.grid-wrap {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 15rpx;
}
.title{
position: fixed;
left: 0;
width: 100vw;
z-index: 999;
display: flex;
align-items: center;
justify-content: center;
font-size: 35rpx;
}
</style>