first commit

This commit is contained in:
2025-05-22 10:33:32 +08:00
commit f2ef63d910
581 changed files with 53162 additions and 0 deletions
+40
View File
@@ -0,0 +1,40 @@
<script>
export default {
onLaunch: function () {
console.log('App Launch')
},
onShow: function () {
console.log('App Show')
},
onHide: function () {
console.log('App Hide')
}
}
</script>
<style lang="scss">
/* 注意要写在第一行,同时给style标签加入lang="scss"属性 */
@import "@/uni_modules/uview-ui/index.scss";
@import "@/static/style/common.scss";
.wrap {
margin: 0;
padding: 0;
box-sizing: border-box;
}
checkbox .wx-checkbox-input,
checkbox .uni-checkbox-input {
border-radius: 50%;
transform: scale(0.7);
}
//设置背景色
checkbox[checked] .wx-checkbox-input,
checkbox .uni-checkbox-input {
background-color: #00C655 !important;
border-color: #00C655 !important;
color: #ffffff !important;
}
</style>
+35
View File
@@ -0,0 +1,35 @@
import post, {get} from "@/api/request";
export const areaListReq = data => post('/area/list-by-level', data)
export const areaInfoReq = data => post('/area/info', data)
export const areaInfoByNameReq = data => post('/area/info-by-name', data)
export const indexListReq = data => post('/com/publish-list/list', data)
export const swiperListReq = () => get('/sys/sys-swiper')
export const communityListReq = data => post('/community/list', data)
export const dictListReq = data => post('/system/dict/info', data)
export const addViewNumReq = data => post('/shop/user-browse/add', data)
export const sysSettingInfoReq = data => post('/sys', data)
export const dictDataReq = data => post('/system/dict-data/list-by-dict', data)
export const listArticleReq = params => get('/cms/article', {params})
export const articleInfoReq = data => post('/cms/article/info', data)
export const articleCateReq = params => get('/cms/article-category', {params})
export const feedbackReq = data => post('/law/law-feedback', data)
export const listFeedbackReq = () => get('/law/law-feedback')
export const listLegalCalTypeReq = () => get('/law/law-legal-cal-type')
export const listLawLegalCalConfig = params => get(`/law/law-legal-cal-config`, {params})
+11
View File
@@ -0,0 +1,11 @@
import post, {get} from "@/api/request";
export const listLawOrgReq = params => get('/law/law-org', {params})
export const listLawOrgPeopleReq = params => get('/law/law-org-people', {params})
export const lawOrgCheckActionReq = data => post('/law/law-org-check-log', data)
export const lawLegalAidReq = data => post('/law/law-legal-aid', data)
export const sendChatReq = data => post('/chat/message', data)
export const stopChatReq = data => post('/chat/messageStop', data)
export const lawLegalArbitrateReq = data => post('/law/law-legal-arbitrate', data)
export const lawLegalAppraisalReq = data => post('/law/law-legal-appraisal', data)
+7
View File
@@ -0,0 +1,7 @@
import post, {get} from "@/api/request";
export const listLegalDocTypeReq = () => get('/law/law-legal-doc-type')
export const legalDocTypeInfoReq = (id) => get(`/law/law-legal-doc-type/${id}`)
export const legalDocConfigReq = params => get('/law/law-legal-doc-config', {params})
export const legalDocMakeReq = data => post('/law/law-legal-doc-config/make', data)
export const legalDocSendEmailReq = data => post('/law/law-legal-doc-config/send-email', data)
+8
View File
@@ -0,0 +1,8 @@
import post, {get, put} from "@/api/request";
export const listLegalOrgCheckTypeReq = () => get('/law/law-legal-org-check-type')
export const listLegalOrgCheckTypeInfoReq = (id) => get(`/law/law-legal-org-check-type/${id}`)
export const listLegalOrgCheckConfigReq = params => get('/law/law-legal-org-check-config', {params})
export const addLegalOrgCheckContentReq = data => post('/law/law-legal-org-check-content', data)
export const updateLegalOrgCheckContentReq = data => post('/law/law-legal-org-check-content/update', data)
export const listLegalOrgCheckContentReq = () => get('/law/law-legal-org-check-content')
+7
View File
@@ -0,0 +1,7 @@
import post, {get, put} from "@/api/request";
export const listLegalOrgCheckTypeSuggestReq = () => get('/law/law-legal-org-check-type-suggest')
export const listLegalOrgCheckTypeSuggestInfoReq = (id) => get(`/law/law-legal-org-check-type-suggest/${id}`)
export const listLegalOrgCheckSuggestConfigReq = params => get('/law/law-legal-org-check-config-suggest', {params})
export const addLegalOrgCheckContentSuggestReq = data => post('/law/law-legal-org-check-content-suggest', data)
export const updateLegalOrgCheckContentSuggestReq = data => put('/law/law-legal-org-check-content-suggest', data)
+4
View File
@@ -0,0 +1,4 @@
import post, {get} from "@/api/request";
export const listNotaryConfigReq = () => get('/law/law-notary-config')
export const notaryActionReq = data => post('/law/law-notary-list', data)
+96
View File
@@ -0,0 +1,96 @@
import Request from '@/js_sdk/luch-request/luch-request/index.js'
import {API} from '@/config'
import {getUserInfo, clearUserInfo} from "@/util/user";
const http = new Request();
http.config.baseURL = API
http.interceptors.request.use((config) => {
// uni.showLoading({title: '加载中'})
const token = getUserInfo().token
if (token && token !== 'undefined') {
config.header.Authorization = token
}
config.header.tenantId = 10049
return config
}, config => {
return Promise.reject(config)
})
http.interceptors.response.use((response) => {
const url = response.config.url
// uni.hideLoading()
switch (parseInt(response.data.code)) {
case 401: {
if (['user-cart-num', 'new-order', 'user-cart-add', 'user-info'].indexOf(url) === -1) {
uni.showToast({
title: '请登录',
icon: 'error',
duration: 2000,
})
setTimeout(() => {
clearUserInfo()
}, 2000)
}
}
break;
case 500: {
if (['/user/change-pay-password', 'new-order-from-goods-list'].indexOf(url) === -1) {
console.log(response.data)
uni.showToast({
icon: 'none',
title: response.data.content.msg,
duration: 2000,
})
}
}
break;
case 502: {
uni.showToast({
icon: 'error',
title: '系统维护中',
duration: 2000,
})
}
}
return response
}, (error) => {
if (error.code === 502) {
uni.showToast({
icon: 'error',
title: '系统维护中',
duration: 2000,
})
}
return Promise.reject(error)
})
const post = (url, formData, options) => {
return new Promise((resolve, reject) => {
http.post(url, formData, options).then(res => {
if (res.data.code === 0) resolve(res.data)
else if (res.data.code === 401) reject(res.data)
else reject(res.data)
})
})
}
export const get = (url, options) => {
return new Promise((resolve, reject) => {
http.get(url, options).then(res => {
resolve(res.data)
})
})
}
export const put = (url, formData, options) => {
return new Promise((resolve, reject) => {
http.put(url, formData, options).then(res => {
if (res.data.code === 0) resolve(res.data)
else if (res.data.code === 401) reject(res.data)
else reject(res.data)
})
})
}
export default post
+21
View File
@@ -0,0 +1,21 @@
import post from "@/api/request";
export const loginReq = data => post('/shop/wx-login/getOpenId', data)
export const loginByPhoneReq = data => post('/login-by-phone', data)
export const userInfoReq = data => post('/system/user/info', data)
export const userInfoUpdateReq = data => post('/system/user/update', data)
export const userInfoUpdateDataReq = data => post('/system/user/update-data', data)
export const userSearchReq = data => post('/user/search', data)
export const userSetCardReq = data => post('/user/set-card', data)
export const userCardChargeReq = data => post('/user/card-charge', data)
export const userCardReduceReq = data => post('/user/card-reduce', data)
export const userCardUseReq = data => post('/user/card-use', data)
+134
View File
@@ -0,0 +1,134 @@
<template>
<view class="min-height bg-main-light">
<HeaderItem title="我要反馈"/>
<view class="rounded-top p-30">
<TitleItem title="基础信息"/>
<view class="my-20 card p-30">
<u-form label-width="140rpx">
<u-form-item label="活动名称" border-bottom>
<u-input v-model="formData.title" border="none" placeholder="请输入活动名称">
</u-input>
</u-form-item>
<u-form-item label="活动单位" border-bottom>
<u-input v-model="formData.company" border="none" placeholder="请输入活动单位"/>
</u-form-item>
<u-form-item label="活动地点" border-bottom>
<u-input v-model="formData.address" border="none" placeholder="请输入活动地点"/>
</u-form-item>
<u-form-item label="活动日期" border-bottom @click="showDate = true">
<u-input v-model="formData.date" border="none" placeholder="请选择活动日期" readonly>
</u-input>
</u-form-item>
<u-form-item label="上传图片" border-bottom>
<view class="flex justify-start items-start flex-wrap">
<view class="album-item pos-r" style="border: 1px dashed #ECECEC" v-for="(item, index) in pics"
:key="index">
<u-image :src="item" width="190rpx" height="190rpx" mode="aspectFill"/>
<view class="del-wrap" @click="delImage(index)">
<u-icon name="trash" color="white" size="40rpx"/>
</view>
</view>
<view class="album-item" style="border: 1px dashed #ECECEC" @click="chooseImage">
<u-icon name="plus"/>
</view>
</view>
</u-form-item>
<u-form-item label="上传视频" border-bottom>
<view class="album-item" style="border: 1px dashed #ECECEC">
<u-icon name="play-circle" v-if="!formData.video" @click="chooseVideo" size="40rpx"/>
<template v-else>
<video :src="formData.video" style="width: 190rpx; height: 190rpx" :controls="false"/>
</template>
</view>
<view class="ml-15" v-if="formData.video">
<u-button @click="chooseVideo" size="mini" type="primary">更换</u-button>
</view>
</u-form-item>
<u-form-item label="活动概览">
<u-textarea maxlength="-1" v-model="formData.content" border="none" placeholder="请输入活动概览"/>
</u-form-item>
</u-form>
</view>
<view class="mt-30">
<u-button type="primary" shape="circle" @click="save">保存</u-button>
</view>
</view>
<u-datetime-picker
:show="showDate"
v-model="checkDate"
mode="date"
@confirm="selectDate"
@cancel="showDate = false"
/>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import TitleItem from "@/components/TitleItem.vue";
import dayjs from "dayjs";
import {chooseImg, chooseVideo} from "@/util";
import {feedbackReq} from "@/api/common";
import {userInfoReq} from "@/api/user";
export default {
name: "feedback",
components: {TitleItem, HeaderItem},
data() {
return {
formData: {
title: '',
company: '',
address: '',
date: '',
pics: '',
video: '',
content: '',
},
pics: [],
showDate: false,
checkDate: Number(new Date()),
userInfo: null
}
},
methods: {
selectDate({value}) {
this.showDate = false
this.formData.date = dayjs(value).format("YYYY-MM-DD")
},
async chooseImage() {
const res = await chooseImg(9 - this.pics.length)
res.map(item => {
this.pics.push(item.path)
})
},
delImage(index) {
this.pics.splice(index, 1)
},
async chooseVideo() {
const res = await chooseVideo()
this.formData.video = res.path
},
async save() {
if (this.pics) this.formData.pics = JSON.stringify(this.pics)
if (!this.formData.title) return this.$toast('请输入活动名称')
if (!this.formData.company) return this.$toast('请输入活动单位')
if (!this.formData.address) return this.$toast('请输入活动地点')
if (!this.formData.date) return this.$toast('请选择活动日期')
await feedbackReq(this.formData)
this.$toast('提交成功')
uni.navigateBack()
},
async getUserData() {
const res = await userInfoReq()
if (res) {
this.userInfo = res.data
this.formData.company = res.data.companyName
}
}
},
onLoad() {
this.getUserData()
},
}
</script>
+47
View File
@@ -0,0 +1,47 @@
<template>
<view class="min-height bg-main-light">
<HeaderItem title="详情"/>
<template v-if="info">
<view class="bg-white p-30">
<view class="font-bold text-25">{{ info.title }}</view>
<view class="text-25 text-gray mt-20">{{ info.createTime }}</view>
</view>
<view class="card m-25">
<u-parse :content="info.content"/>
</view>
</template>
<view class="footer bg-linear text-white text-center" v-if="showFeedback" @click="$jump('/articlePages/pages/feedback')">
<view class="p-30">我要反馈</view>
</view>
</view>
</template>
<script>
import {articleInfoReq} from "@/api/common";
import HeaderItem from "@/components/HeaderItem.vue";
export default {
name: "info",
components: {HeaderItem},
data() {
return {
info: null,
showFeedback: false,
}
},
methods: {
async getInfo(articleId) {
const {data} = await articleInfoReq({
articleId
})
this.info = data
}
},
onLoad({id, showFeedback}) {
this.getInfo(id)
if (showFeedback) {
this.showFeedback = parseInt(showFeedback) === 1
}
}
}
</script>
+45
View File
@@ -0,0 +1,45 @@
<template>
<view class="min-height bg-main-light">
<HeaderItem :title="title"/>
<template v-if="list.length">
<view class="card m-20" v-for="(item, index) in list" :key="index"
@click="$jump(`/articlePages/pages/info?id=${item.articleId}`)">
<view class="flex-1 flex justify-between items-center w-100p">
<text class="text-25 font-bold">{{ item.title }}</text>
<text class="text-20 text-gray">{{ item.createTime }}</text>
</view>
</view>
</template>
<u-empty v-else icon="/lawOrgPages/static/empty.png"/>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import {listArticleReq} from "@/api/common";
export default {
name: "list",
components: {HeaderItem},
data() {
return {
title: '',
cateId: '',
list: []
}
},
methods: {
async getList() {
const {data} = await listArticleReq({
categoryId: this.cateId
})
this.list = data
}
},
onLoad({title, cateId}) {
this.title = title
this.cateId = cateId
this.getList()
}
}
</script>
+91
View File
@@ -0,0 +1,91 @@
<template>
<view class="min-height bg-white">
<HeaderItem title="法治宣传"/>
<view class="p-20 pos-r bg-linear" style="padding-bottom: 80rpx">
<u-input v-model="keyword" shape="circle" :custom-style="{background: 'white', height: '65rpx'}"
placeholder="请输入您要查找的内容"/>
<view class="pos-a" style="right: 30rpx; top: 30rpx">
<u-button shape="circle" type="primary" :custom-style="{width: '200rpx', zIndex: 9999}" @click="getList">
搜索
</u-button>
</view>
<view class="p-20 text-25 flex justify-start items-center overflow-x pos-a"
style="background-color: #E1F3FE; border-radius: 10rpx; width: 90%; bottom: -40rpx">
<text v-for="(item, index) in cateList" :key="index" class="tag"
@click="changeType(index)"
:class="[item.categoryId === activeId ? 'selected-tag' : '']">{{ item.title }}
</text>
</view>
</view>
<u-gap height="40rpx"></u-gap>
<template v-if="list.length">
<view class="card m-20 flex flex-col justify-center items-center" v-for="(item, index) in list" :key="index">
<view class="circle w-100p mb-20"
style="box-shadow: 0 2px 6px rgba(144, 144, 144, 0.4);"
@click="$jump(`/articlePages/pages/info?id=${item.articleId}&showFeedback=1`)"
:style="{backgroundImage: `url(${API()}/file${item.image})`, backgroundSize: 'cover',
height: '240rpx'}"></view>
<view class="text-25 mt-20">{{ item.title }}</view>
</view>
</template>
<u-empty v-else icon="/lawOrgPages/static/empty.png"/>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import {articleCateReq, listArticleReq} from "@/api/common";
import {API} from "@/config";
export default {
name: "publicity",
components: {HeaderItem},
data() {
return {
keyword: '',
cateList: [],
list: [],
activeId: 0
}
},
methods: {
API() {
return API
},
async getCateList() {
const {data} = await articleCateReq({
parentId: 60
})
this.cateList = data
this.changeType(0)
},
changeType(index) {
this.activeId = this.cateList[index].categoryId
this.getList()
},
async getList() {
const {data} = await listArticleReq({
categoryId: this.activeId,
title: this.keyword
})
this.list = data
}
},
onLoad() {
this.getCateList()
}
}
</script>
<style scoped lang="scss">
.tag {
padding: 10rpx 25rpx;
margin-right: 25rpx;
flex-shrink: 0;
}
.selected-tag {
background-color: #FFCA68;
border-radius: 100rpx;
}
</style>
+96
View File
@@ -0,0 +1,96 @@
<template>
<view class="min-height bg-white">
<HeaderItem title="自助查询"/>
<view class="p-20 pos-r bg-linear" style="padding-bottom: 70rpx">
<u-input v-model="keyword" shape="circle" :custom-style="{background: 'white', height: '65rpx'}"
placeholder="请输入您要查找的内容"/>
<view class="pos-a" style="right: 30rpx; top: 30rpx">
<u-button shape="circle" type="primary" :custom-style="{width: '200rpx', zIndex: 9999}" @click="getList">
搜索
</u-button>
</view>
<view class="pos-a" style="width: 100%; left: 0; bottom: -70rpx">
<view class="bg-main-light p-20 text-25 flex justify-start items-center overflow-x m-25 rounded-sm">
<text v-for="(item, index) in cateList" :key="index" class="tag"
@click="changeCate(index)"
:class="[item.id === cateId ? 'selected-tag' : '']">{{ item.title }}
</text>
</view>
</view>
</view>
<u-gap height="50rpx"></u-gap>
<template v-if="list.length">
<view class="py-15 border-bottom m-25" v-for="(item, index) in list" :key="index"
@click="$jump(`/articlePages/pages/info?id=${item.articleId}`)">
<view class="flex-1 flex justify-between items-center w-100p">
<text class="text-25 font-bold">{{ item.title }}</text>
<text class="text-20 text-gray">{{ item.createTime }}</text>
</view>
</view>
</template>
<u-empty v-else icon="/lawOrgPages/static/empty.png"/>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import {listArticleReq} from "@/api/common";
export default {
name: "list",
components: {HeaderItem},
data() {
return {
keyword: '',
cateId: 55,
cateList: [
{
title: '法律法规',
id: 55
},
{
title: '案例查询',
id: 56
},
{
title: '文书模板',
id: 67
},
],
list: [],
}
},
methods: {
changeCate(index) {
this.cateId = this.cateList[index].id
this.getList()
},
async getList() {
const {data} = await listArticleReq({
categoryId: this.cateId,
title: this.keyword
})
this.list = data
}
},
onLoad() {
this.getList()
}
}
</script>
<style scoped lang="scss">
.tag {
padding: 10rpx 25rpx;
margin-right: 25rpx;
flex-shrink: 0;
}
.selected-tag {
background-color: #FFCA68;
border-radius: 100rpx;
}
</style>
+41
View File
@@ -0,0 +1,41 @@
<template>
<u-sticky zIndex="99999">
<u-navbar fixed :auto-back="false" :bgColor="bgColor" :status-bar-bg-color="bgColor" placeholder :title="title" safeAreaInsetTop
:title-style="{color: 'white'}" auto-back left-icon-color="white" @leftClick="leftClick">
<template slot="left">
<u-icon :name="currentPages.length > 1 ? 'arrow-left' : 'home'" size="20" color="white" v-if="showBack"/>
</template>
</u-navbar>
</u-sticky>
</template>
<script>
import {LINEAR} from "@/config/color";
export default {
name: "HeaderItem",
props: {
title: String,
showBack: {
type: Boolean,
default: true
}
},
data() {
return {
bgColor: LINEAR,
currentPages: []
}
},
methods: {
leftClick() {
console.log(this.currentPages)
if (this.currentPages.length === 1) uni.switchTab({url: '/pages/index/index'})
// else uni.navigateBack()
}
},
mounted() {
this.currentPages = getCurrentPages()
}
}
</script>
+150
View File
@@ -0,0 +1,150 @@
<template>
<u-popup :show="show" close-on-click-overlay @close="refuse" round="10" :safe-area-inset-bottom="false">
<view class="p-50">
<view class="flex flex-col justify-start items-start">
<!-- <u-icon name="/static/logo.png" width="100" height="52"/>-->
<text class="text-30 font-bold mt-20">为了提供更优质的服务,需要获取</text>
</view>
<view class="my-25">
<u-text text="您的身份信息" size="16" bold margin="60rpx 0"/>
</view>
<view class="mt-20 text-25">
<checkbox-group @change="changeCheck">
<view class="flex justify-start items-center">
<checkbox value="check" :checked="check"/>
<view>
<text>我已阅读并同意</text>
<text style="color: #00004F" @click="showAgree('USER_PROTOCOL')">
《用户协议》
</text>
<text style="color: #00004F" @click="showAgree('SECRET_PROTOCOL')">
《隐私协议》
</text>
</view>
</view>
</checkbox-group>
</view>
<view class="mt-25 flex justify-between">
<view class="w-40p">
<u-button type="info" @click="refuse" :custom-style="{backgroundColor: '#F2F2F2'}">拒绝</u-button>
</view>
<view class="w-40p">
<u-button @click="doLogin"
:custom-style="agreeStyle"
:disabled="!check || disabled">允许
</u-button>
</view>
</view>
</view>
<u-popup mode="center" :show="showAgreePopup" closeable @close="showAgreePopup = false" round="10"
:custom-style="{height: '80%', width: '80%'}" closeOnClickOverlay>
<view class="p-30 overflow-y">
<u-parse :content="content"/>
</view>
</u-popup>
</u-popup>
</template>
<script>
import {loginReq} from "@/api/user";
import {setUserInfo} from "@/util/user";
import {sysSettingInfoReq} from "@/api/common";
export default {
name: "Login",
props: {
isIndex: {
type: Boolean,
default: false
},
isHide: {
type: Boolean,
default: false
}
},
data() {
return {
show: false,
check: false,
code: null,
phoneData: null,
agreeStyle: {
backgroundColor: this.check ? '#00C655' : '#F2F2F2',
border: this.check ? '#00C655' : '#F2F2F2',
color: this.check ? '#FFFFFF' : '#828282',
},
showAgreePopup: false,
content: '',
disabled: false
}
},
methods: {
changeCheck({detail}) {
const {value} = detail
this.check = value.length > 0
this.agreeStyle = {
backgroundColor: this.check ? '#00C655' : '#F2F2F2',
border: this.check ? '#00C655' : '#F2F2F2',
color: this.check ? '#FFFFFF' : '#828282',
}
},
open() {
this.disabled = false
this.show = true
},
hide() {
this.show = false
},
wxLogin() {
return new Promise(resolve => {
uni.login({
success: (loginRes) => {
this.code = loginRes.code
resolve()
}
})
})
},
auth(phoneE) {
//获取手机号
this.phoneData = phoneE.detail
this.doLogin()
},
async doLogin() {
await this.wxLogin()
this.disabled = true
// const phone_code = this.phoneData.code
const {data} = await loginReq({
// phone_code,
code: this.code,
})
console.log(data)
this.setInfo(data)
this.done()
this.disabled = false
},
setInfo(res) {
setUserInfo({
username: res.user.nickname,
header: res.user.avatar,
// phone: res.phone,
token: res.access_token,
uid: res.user.userId,
});
},
done() {
this.show = false
this.$emit('done')
},
refuse() {
this.show = false
if (!this.isHide) uni.switchTab({url: '/pages/index/index'})
},
async showAgree(enumKey) {
const {data} = await sysSettingInfoReq({'enum': enumKey})
this.content = data
this.showAgreePopup = true
}
},
}
</script>
+18
View File
@@ -0,0 +1,18 @@
<template>
<view class="mb-25 mt-25">
<u-icon name="/static/line.png" :label="title" label-pos="right" bold label-color="#4F4F4F" label-size="30rpx"/>
</view>
</template>
<script>
export default {
name: "TitleItem",
props: {
title: String
},
data() {
return {}
},
methods: {}
}
</script>
+84
View File
@@ -0,0 +1,84 @@
<template>
<view>
<m-tabbar fixed fill :current="current" safeBottom :tabbar="tabbar" native openType="switchTab" @click="tabClick">
<template v-slot:tabbar_index_1>
<view class="custom_style">
<view class="custom_style_icon">
<u-image src="/static/ai.png" width="160rpx" height="160rpx"/>
</view>
</view>
</template>
</m-tabbar>
</view>
</template>
<script>
export default {
name: "customTabbar",
props: {
current: {
default: 0,
type: Number
}
},
data() {
return {
tabbar: {
color: "#333",
selectedColor: "#2ACF8D",
borderStyle: "F0F0F0",
backgroundColor: "#FFFFFF",
list: [
{
"pagePath": "pages/index/index",
"iconPath": "static/tabbar/home.png",
"selectedIconPath": "static/tabbar/home-selected.png",
"text": "首页"
},
{},
{
"pagePath": "pages/user/index",
"iconPath": "static/tabbar/user.png",
"selectedIconPath": "static/tabbar/user-selected.png",
"text": "我的"
}
]
}
}
},
methods: {
tabClick(val){
if (val === 0 && this.current === 0) this.$jump({url: '/pages/index/index'})
}
},
mounted() {
console.log(this.current)
},
}
</script>
<style lang="scss">
.custom_style {
color: #fff;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 24rpx;
width: 100rpx;
height: 100rpx;
margin-top: -40rpx;
&_icon {
//background-color: #2ACF8D;
font-size: 80rpx;
width: 100rpx;
height: 100rpx;
border-radius: 100%;
display: flex;
justify-content: center;
align-items: center;
}
}
</style>
+18
View File
@@ -0,0 +1,18 @@
export const YELLOW = '#e2d602'
export const ORANGE = '#fd7600'
export const ORANGE_LIGHT = '#FEEDA8'
export const GREEN = '#2ACF8D'
export const GREEN_LIGHT = '#96b0a3'
export const BLUE = '#2665c4'
export const BLUE_LIGHT = '#049DFF'
export const RED = '#FE6869'
export const RED_LIGHT = '#F7B2B2'
export const PURPLE = '#7F6CDE'
export const PINK = '#FE5397'
export const PURPLE_DARK = '#7F6CDE'
export const PUBLISH = '#FDCB05'
export const GRAY = '#999'
export const PURPLE_LIGHT = '#7F6CDE'
export const MAIN = BLUE
export const LINEAR = 'linear-gradient(90deg, #049DFF, #2665c4)'
+23
View File
@@ -0,0 +1,23 @@
const MAIN_API_FN = () => {
if (process.env.NODE_ENV === 'development') {
return 'http://127.0.0.1:10051'
// return 'https://sifa-api.wsdns.cn'
} else {
return 'https://sifa-api.wsdns.cn'
}
}
const MAIN_WS_FN = () => {
if (process.env.NODE_ENV === 'development') {
// return 'ws://127.0.0.1:10051/chat'
return 'wss://sifa-api.wsdns.cn/chat'
} else {
return 'wss://sifa-api.wsdns.cn/chat'
}
}
export const MAIN_API = MAIN_API_FN()
export const WS_API = MAIN_WS_FN()
export const API = `${MAIN_API}/api`
+20
View File
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>
@@ -0,0 +1,100 @@
import buildURL from '../helpers/buildURL'
import buildFullPath from '../core/buildFullPath'
import settle from '../core/settle'
import {isUndefined} from "../utils"
/**
* 返回可选值存在的配置
* @param {Array} keys - 可选值数组
* @param {Object} config2 - 配置
* @return {{}} - 存在的配置项
*/
const mergeKeys = (keys, config2) => {
let config = {}
keys.forEach(prop => {
if (!isUndefined(config2[prop])) {
config[prop] = config2[prop]
}
})
return config
}
export default (config) => {
return new Promise((resolve, reject) => {
let fullPath = buildURL(buildFullPath(config.baseURL, config.url), config.params, config.paramsSerializer)
const _config = {
url: fullPath,
header: config.header,
complete: (response) => {
config.fullPath = fullPath
response.config = config
response.rawData = response.data
try {
// 对可能字符串不是json 的情况容错
if (typeof response.data === 'string') {
response.data = JSON.parse(response.data)
}
// eslint-disable-next-line no-empty
} catch (e) {
}
settle(resolve, reject, response)
}
}
let requestTask
if (config.method === 'UPLOAD') {
delete _config.header['content-type']
delete _config.header['Content-Type']
let otherConfig = {
// #ifdef MP-ALIPAY
fileType: config.fileType,
// #endif
filePath: config.filePath,
name: config.name
}
const optionalKeys = [
// #ifdef APP-PLUS || H5
'files',
// #endif
// #ifdef H5
'file',
// #endif
// #ifdef H5 || APP-PLUS
'timeout',
// #endif
'formData'
]
requestTask = uni.uploadFile({..._config, ...otherConfig, ...mergeKeys(optionalKeys, config)})
} else if (config.method === 'DOWNLOAD') {
// #ifdef H5 || APP-PLUS
if (!isUndefined(config['timeout'])) {
_config['timeout'] = config['timeout']
}
// #endif
requestTask = uni.downloadFile(_config)
} else {
const optionalKeys = [
'data',
'method',
// #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
'timeout',
// #endif
'dataType',
// #ifndef MP-ALIPAY
'responseType',
// #endif
// #ifdef APP-PLUS
'sslVerify',
// #endif
// #ifdef H5
'withCredentials',
// #endif
// #ifdef APP-PLUS
'firstIpv4',
// #endif
]
requestTask = uni.request({..._config, ...mergeKeys(optionalKeys, config)})
}
if (config.getTask) {
config.getTask(requestTask, config)
}
})
}
@@ -0,0 +1,51 @@
'use strict'
function InterceptorManager() {
this.handlers = []
}
/**
* Add a new interceptor to the stack
*
* @param {Function} fulfilled The function to handle `then` for a `Promise`
* @param {Function} rejected The function to handle `reject` for a `Promise`
*
* @return {Number} An ID used to remove interceptor later
*/
InterceptorManager.prototype.use = function use(fulfilled, rejected) {
this.handlers.push({
fulfilled: fulfilled,
rejected: rejected
})
return this.handlers.length - 1
}
/**
* Remove an interceptor from the stack
*
* @param {Number} id The ID that was returned by `use`
*/
InterceptorManager.prototype.eject = function eject(id) {
if (this.handlers[id]) {
this.handlers[id] = null
}
}
/**
* Iterate over all the registered interceptors
*
* This method is particularly useful for skipping over any
* interceptors that may have become `null` calling `eject`.
*
* @param {Function} fn The function to call for each interceptor
*/
InterceptorManager.prototype.forEach = function forEach(fn) {
this.handlers.forEach(h => {
if (h !== null) {
fn(h)
}
})
}
export default InterceptorManager
@@ -0,0 +1,197 @@
/**
* @Class Request
* @description luch-request http请求插件
* @Author lu-ch
* @Email webwork.s@qq.com
* 文档: https://www.quanzhan.co/luch-request/
* github: https://github.com/lei-mu/luch-request
* DCloud: http://ext.dcloud.net.cn/plugin?id=392
*/
import dispatchRequest from './dispatchRequest'
import InterceptorManager from './InterceptorManager'
import mergeConfig from './mergeConfig'
import defaults from './defaults'
import { isPlainObject } from '../utils'
import clone from '../utils/clone'
export default class Request {
/**
* @param {Object} arg - 全局配置
* @param {String} arg.baseURL - 全局根路径
* @param {Object} arg.header - 全局header
* @param {String} arg.method = [GET|POST|PUT|DELETE|CONNECT|HEAD|OPTIONS|TRACE] - 全局默认请求方式
* @param {String} arg.dataType = [json] - 全局默认的dataType
* @param {String} arg.responseType = [text|arraybuffer] - 全局默认的responseType。支付宝小程序不支持
* @param {Object} arg.custom - 全局默认的自定义参数
* @param {Number} arg.timeout - 全局默认的超时时间,单位 ms。默认60000。H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)、微信小程序(2.10.0)、支付宝小程序
* @param {Boolean} arg.sslVerify - 全局默认的是否验证 ssl 证书。默认true.仅App安卓端支持(HBuilderX 2.3.3+)
* @param {Boolean} arg.withCredentials - 全局默认的跨域请求时是否携带凭证(cookies)。默认false。仅H5支持(HBuilderX 2.6.15+)
* @param {Boolean} arg.firstIpv4 - 全DNS解析时优先使用ipv4。默认false。仅 App-Android 支持 (HBuilderX 2.8.0+)
* @param {Function(statusCode):Boolean} arg.validateStatus - 全局默认的自定义验证器。默认statusCode >= 200 && statusCode < 300
*/
constructor(arg = {}) {
if (!isPlainObject(arg)) {
arg = {}
console.warn('设置全局参数必须接收一个Object')
}
this.config = clone({...defaults, ...arg})
this.interceptors = {
request: new InterceptorManager(),
response: new InterceptorManager()
}
}
/**
* @Function
* @param {Request~setConfigCallback} f - 设置全局默认配置
*/
setConfig(f) {
this.config = f(this.config)
}
middleware(config) {
config = mergeConfig(this.config, config)
let chain = [dispatchRequest, undefined]
let promise = Promise.resolve(config)
this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
chain.unshift(interceptor.fulfilled, interceptor.rejected)
})
this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
chain.push(interceptor.fulfilled, interceptor.rejected)
})
while (chain.length) {
promise = promise.then(chain.shift(), chain.shift())
}
return promise
}
/**
* @Function
* @param {Object} config - 请求配置项
* @prop {String} options.url - 请求路径
* @prop {Object} options.data - 请求参数
* @prop {Object} [options.responseType = config.responseType] [text|arraybuffer] - 响应的数据类型
* @prop {Object} [options.dataType = config.dataType] - 如果设为 json,会尝试对返回的数据做一次 JSON.parse
* @prop {Object} [options.header = config.header] - 请求header
* @prop {Object} [options.method = config.method] - 请求方法
* @returns {Promise<unknown>}
*/
request(config = {}) {
return this.middleware(config)
}
get(url, options = {}) {
return this.middleware({
url,
method: 'GET',
...options
})
}
post(url, data, options = {}) {
return this.middleware({
url,
data,
method: 'POST',
...options
})
}
// #ifndef MP-ALIPAY || MP-KUAISHOU || MP-JD
put(url, data, options = {}) {
return this.middleware({
url,
data,
method: 'PUT',
...options
})
}
// #endif
// #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
delete(url, data, options = {}) {
return this.middleware({
url,
data,
method: 'DELETE',
...options
})
}
// #endif
// #ifdef H5 || MP-WEIXIN
connect(url, data, options = {}) {
return this.middleware({
url,
data,
method: 'CONNECT',
...options
})
}
// #endif
// #ifdef H5 || MP-WEIXIN || MP-BAIDU
head(url, data, options = {}) {
return this.middleware({
url,
data,
method: 'HEAD',
...options
})
}
// #endif
// #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
options(url, data, options = {}) {
return this.middleware({
url,
data,
method: 'OPTIONS',
...options
})
}
// #endif
// #ifdef H5 || MP-WEIXIN
trace(url, data, options = {}) {
return this.middleware({
url,
data,
method: 'TRACE',
...options
})
}
// #endif
upload(url, config = {}) {
config.url = url
config.method = 'UPLOAD'
return this.middleware(config)
}
download(url, config = {}) {
config.url = url
config.method = 'DOWNLOAD'
return this.middleware(config)
}
}
/**
* setConfig回调
* @return {Object} - 返回操作后的config
* @callback Request~setConfigCallback
* @param {Object} config - 全局默认config
*/
@@ -0,0 +1,20 @@
'use strict'
import isAbsoluteURL from '../helpers/isAbsoluteURL'
import combineURLs from '../helpers/combineURLs'
/**
* Creates a new URL by combining the baseURL with the requestedURL,
* only when the requestedURL is not already an absolute URL.
* If the requestURL is absolute, this function returns the requestedURL untouched.
*
* @param {string} baseURL The base URL
* @param {string} requestedURL Absolute or relative URL to combine
* @returns {string} The combined full path
*/
export default function buildFullPath(baseURL, requestedURL) {
if (baseURL && !isAbsoluteURL(requestedURL)) {
return combineURLs(baseURL, requestedURL)
}
return requestedURL
}
@@ -0,0 +1,31 @@
/**
* 默认的全局配置
*/
export default {
baseURL: '',
header: {},
method: 'GET',
dataType: 'json',
paramsSerializer: null,
// #ifndef MP-ALIPAY
responseType: 'text',
// #endif
custom: {},
// #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
timeout: 60000,
// #endif
// #ifdef APP-PLUS
sslVerify: true,
// #endif
// #ifdef H5
withCredentials: false,
// #endif
// #ifdef APP-PLUS
firstIpv4: false,
// #endif
validateStatus: function validateStatus(status) {
return status >= 200 && status < 300
}
}
@@ -0,0 +1,6 @@
import adapter from '../adapters/index'
export default (config) => {
return adapter(config)
}
@@ -0,0 +1,103 @@
import {deepMerge, isUndefined} from '../utils'
/**
* 合并局部配置优先的配置,如果局部有该配置项则用局部,如果全局有该配置项则用全局
* @param {Array} keys - 配置项
* @param {Object} globalsConfig - 当前的全局配置
* @param {Object} config2 - 局部配置
* @return {{}}
*/
const mergeKeys = (keys, globalsConfig, config2) => {
let config = {}
keys.forEach(prop => {
if (!isUndefined(config2[prop])) {
config[prop] = config2[prop]
} else if (!isUndefined(globalsConfig[prop])) {
config[prop] = globalsConfig[prop]
}
})
return config
}
/**
*
* @param globalsConfig - 当前实例的全局配置
* @param config2 - 当前的局部配置
* @return - 合并后的配置
*/
export default (globalsConfig, config2 = {}) => {
const method = config2.method || globalsConfig.method || 'GET'
let config = {
baseURL: config2.baseURL || globalsConfig.baseURL || '',
method: method,
url: config2.url || '',
params: config2.params || {},
custom: {...(globalsConfig.custom || {}), ...(config2.custom || {})},
header: deepMerge(globalsConfig.header || {}, config2.header || {})
}
const defaultToConfig2Keys = ['getTask', 'validateStatus', 'paramsSerializer']
config = {...config, ...mergeKeys(defaultToConfig2Keys, globalsConfig, config2)}
// eslint-disable-next-line no-empty
if (method === 'DOWNLOAD') {
// #ifdef H5 || APP-PLUS
if (!isUndefined(config2.timeout)) {
config['timeout'] = config2['timeout']
} else if (!isUndefined(globalsConfig.timeout)) {
config['timeout'] = globalsConfig['timeout']
}
// #endif
} else if (method === 'UPLOAD') {
delete config.header['content-type']
delete config.header['Content-Type']
const uploadKeys = [
// #ifdef APP-PLUS || H5
'files',
// #endif
// #ifdef MP-ALIPAY
'fileType',
// #endif
// #ifdef H5
'file',
// #endif
'filePath',
'name',
// #ifdef H5 || APP-PLUS
'timeout',
// #endif
'formData',
]
uploadKeys.forEach(prop => {
if (!isUndefined(config2[prop])) {
config[prop] = config2[prop]
}
})
// #ifdef H5 || APP-PLUS
if (isUndefined(config.timeout) && !isUndefined(globalsConfig.timeout)) {
config['timeout'] = globalsConfig['timeout']
}
// #endif
} else {
const defaultsKeys = [
'data',
// #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
'timeout',
// #endif
'dataType',
// #ifndef MP-ALIPAY
'responseType',
// #endif
// #ifdef APP-PLUS
'sslVerify',
// #endif
// #ifdef H5
'withCredentials',
// #endif
// #ifdef APP-PLUS
'firstIpv4',
// #endif
]
config = {...config, ...mergeKeys(defaultsKeys, globalsConfig, config2)}
}
return config
}
@@ -0,0 +1,16 @@
/**
* Resolve or reject a Promise based on response status.
*
* @param {Function} resolve A function that resolves the promise.
* @param {Function} reject A function that rejects the promise.
* @param {object} response The response.
*/
export default function settle(resolve, reject, response) {
const validateStatus = response.config.validateStatus
const status = response.statusCode
if (status && (!validateStatus || validateStatus(status))) {
resolve(response)
} else {
reject(response)
}
}
@@ -0,0 +1,64 @@
'use strict'
import * as utils from './../utils'
function encode(val) {
return encodeURIComponent(val).replace(/%40/gi, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',').replace(/%20/g, '+').replace(/%5B/gi, '[').replace(/%5D/gi, ']')
}
/**
* Build a URL by appending params to the end
*
* @param {string} url The base of the url (e.g., http://www.google.com)
* @param {object} [params] The params to be appended
* @returns {string} The formatted url
*/
export default function buildURL(url, params, paramsSerializer) {
/*eslint no-param-reassign:0*/
if (!params) {
return url
}
var serializedParams
if (paramsSerializer) {
serializedParams = paramsSerializer(params)
} else if (utils.isURLSearchParams(params)) {
serializedParams = params.toString()
} else {
var parts = []
utils.forEach(params, function serialize(val, key) {
if (val === null || typeof val === 'undefined') {
return
}
if (utils.isArray(val)) {
key = key + '[]'
} else {
val = [val]
}
utils.forEach(val, function parseValue(v) {
if (utils.isDate(v)) {
v = v.toISOString()
} else if (utils.isObject(v)) {
v = JSON.stringify(v)
}
parts.push(encode(key) + '=' + encode(v))
})
})
serializedParams = parts.join('&')
}
if (serializedParams) {
var hashmarkIndex = url.indexOf('#')
if (hashmarkIndex !== -1) {
url = url.slice(0, hashmarkIndex)
}
url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams
}
return url
}
@@ -0,0 +1,14 @@
'use strict'
/**
* Creates a new URL by combining the specified URLs
*
* @param {string} baseURL The base URL
* @param {string} relativeURL The relative URL
* @returns {string} The combined URL
*/
export default function combineURLs(baseURL, relativeURL) {
return relativeURL
? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '')
: baseURL
}
@@ -0,0 +1,14 @@
'use strict'
/**
* Determines whether the specified URL is absolute
*
* @param {string} url The URL to test
* @returns {boolean} True if the specified URL is absolute, otherwise false
*/
export default function isAbsoluteURL(url) {
// A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
// RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
// by any combination of letters, digits, plus, period, or hyphen.
return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url)
}
+120
View File
@@ -0,0 +1,120 @@
type AnyObject = Record<string | number | symbol, any>
type HttpPromise<T> = Promise<HttpResponse<T>>;
type Tasks = UniApp.RequestTask | UniApp.UploadTask | UniApp.DownloadTask
export interface RequestTask {
abort: () => void;
offHeadersReceived: () => void;
onHeadersReceived: () => void;
}
export interface HttpRequestConfig<T = Tasks> {
/** 请求基地址 */
baseURL?: string;
/** 请求服务器接口地址 */
url?: string;
/** 请求查询参数,自动拼接为查询字符串 */
params?: AnyObject;
/** 请求体参数 */
data?: AnyObject;
/** 文件对应的 key */
name?: string;
/** HTTP 请求中其他额外的 form data */
formData?: AnyObject;
/** 要上传文件资源的路径。 */
filePath?: string;
/** 需要上传的文件列表。使用 files 时,filePath 和 name 不生效,App、H5( 2.6.15+) */
files?: Array<{
name?: string;
file?: File;
uri: string;
}>;
/** 要上传的文件对象,仅H5(2.6.15+)支持 */
file?: File;
/** 请求头信息 */
header?: AnyObject;
/** 请求方式 */
method?: "GET" | "POST" | "PUT" | "DELETE" | "CONNECT" | "HEAD" | "OPTIONS" | "TRACE" | "UPLOAD" | "DOWNLOAD";
/** 如果设为 json,会尝试对返回的数据做一次 JSON.parse */
dataType?: string;
/** 设置响应的数据类型,支付宝小程序不支持 */
responseType?: "text" | "arraybuffer";
/** 自定义参数 */
custom?: AnyObject;
/** 超时时间,仅微信小程序(2.10.0)、支付宝小程序支持 */
timeout?: number;
/** DNS解析时优先使用ipv4,仅 App-Android 支持 (HBuilderX 2.8.0+) */
firstIpv4?: boolean;
/** 验证 ssl 证书 仅5+App安卓端支持(HBuilderX 2.3.3+) */
sslVerify?: boolean;
/** 跨域请求时是否携带凭证(cookies)仅H5支持(HBuilderX 2.6.15+) */
withCredentials?: boolean;
/** 返回当前请求的task, options。请勿在此处修改options。 */
getTask?: (task: T, options: HttpRequestConfig<T>) => void;
/** 全局自定义验证器 */
validateStatus?: (statusCode: number) => boolean | void;
/** params 参数自定义处理 */
paramsSerializer?: (params: AnyObject) => string | void;
}
export interface HttpResponse<T = any> {
config: HttpRequestConfig;
statusCode: number;
cookies: Array<string>;
data: T;
errMsg: string;
header: AnyObject;
rawData: T;
}
export interface HttpUploadResponse<T = any> {
config: HttpRequestConfig;
statusCode: number;
data: T;
errMsg: string;
rawData: T;
}
export interface HttpDownloadResponse extends HttpResponse {
tempFilePath: string;
}
export interface HttpError {
config: HttpRequestConfig;
statusCode?: number;
cookies?: Array<string>;
data?: any;
errMsg: string;
header?: AnyObject;
}
export interface HttpInterceptorManager<V, E = V> {
use(
onFulfilled?: (config: V) => Promise<V> | V,
onRejected?: (config: E) => Promise<E> | E
): void;
eject(id: number): void;
}
export abstract class HttpRequestAbstract {
constructor(config?: HttpRequestConfig);
config: HttpRequestConfig;
interceptors: {
request: HttpInterceptorManager<HttpRequestConfig, HttpRequestConfig>;
response: HttpInterceptorManager<HttpResponse, HttpError>;
}
middleware<T = any>(config: HttpRequestConfig): HttpPromise<T>;
request<T = any>(config: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
get<T = any>(url: string, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
upload<T = any>(url: string, config?: HttpRequestConfig<UniApp.UploadTask>): HttpPromise<T>;
delete<T = any>(url: string, data?: AnyObject, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
head<T = any>(url: string, data?: AnyObject, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
post<T = any>(url: string, data?: AnyObject, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
put<T = any>(url: string, data?: AnyObject, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
connect<T = any>(url: string, data?: AnyObject, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
options<T = any>(url: string, data?: AnyObject, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
trace<T = any>(url: string, data?: AnyObject, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
download(url: string, config?: HttpRequestConfig<UniApp.DownloadTask>): Promise<HttpDownloadResponse>;
setConfig(onSend: (config: HttpRequestConfig) => HttpRequestConfig): void;
}
declare class HttpRequest extends HttpRequestAbstract { }
export default HttpRequest;
@@ -0,0 +1,2 @@
import Request from './core/Request'
export default Request
+135
View File
@@ -0,0 +1,135 @@
'use strict'
// utils is a library of generic helper functions non-specific to axios
var toString = Object.prototype.toString
/**
* Determine if a value is an Array
*
* @param {Object} val The value to test
* @returns {boolean} True if value is an Array, otherwise false
*/
export function isArray (val) {
return toString.call(val) === '[object Array]'
}
/**
* Determine if a value is an Object
*
* @param {Object} val The value to test
* @returns {boolean} True if value is an Object, otherwise false
*/
export function isObject (val) {
return val !== null && typeof val === 'object'
}
/**
* Determine if a value is a Date
*
* @param {Object} val The value to test
* @returns {boolean} True if value is a Date, otherwise false
*/
export function isDate (val) {
return toString.call(val) === '[object Date]'
}
/**
* Determine if a value is a URLSearchParams object
*
* @param {Object} val The value to test
* @returns {boolean} True if value is a URLSearchParams object, otherwise false
*/
export function isURLSearchParams (val) {
return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams
}
/**
* Iterate over an Array or an Object invoking a function for each item.
*
* If `obj` is an Array callback will be called passing
* the value, index, and complete array for each item.
*
* If 'obj' is an Object callback will be called passing
* the value, key, and complete object for each property.
*
* @param {Object|Array} obj The object to iterate
* @param {Function} fn The callback to invoke for each item
*/
export function forEach (obj, fn) {
// Don't bother if no value provided
if (obj === null || typeof obj === 'undefined') {
return
}
// Force an array if not already something iterable
if (typeof obj !== 'object') {
/*eslint no-param-reassign:0*/
obj = [obj]
}
if (isArray(obj)) {
// Iterate over array values
for (var i = 0, l = obj.length; i < l; i++) {
fn.call(null, obj[i], i, obj)
}
} else {
// Iterate over object keys
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
fn.call(null, obj[key], key, obj)
}
}
}
}
/**
* 是否为boolean 值
* @param val
* @returns {boolean}
*/
export function isBoolean(val) {
return typeof val === 'boolean'
}
/**
* 是否为真正的对象{} new Object
* @param {any} obj - 检测的对象
* @returns {boolean}
*/
export function isPlainObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]'
}
/**
* Function equal to merge with the difference being that no reference
* to original objects is kept.
*
* @see merge
* @param {Object} obj1 Object to merge
* @returns {Object} Result of all merge properties
*/
export function deepMerge(/* obj1, obj2, obj3, ... */) {
let result = {}
function assignValue(val, key) {
if (typeof result[key] === 'object' && typeof val === 'object') {
result[key] = deepMerge(result[key], val)
} else if (typeof val === 'object') {
result[key] = deepMerge({}, val)
} else {
result[key] = val
}
}
for (let i = 0, l = arguments.length; i < l; i++) {
forEach(arguments[i], assignValue)
}
return result
}
export function isUndefined (val) {
return typeof val === 'undefined'
}
@@ -0,0 +1,264 @@
/* eslint-disable */
var clone = (function() {
'use strict';
function _instanceof(obj, type) {
return type != null && obj instanceof type;
}
var nativeMap;
try {
nativeMap = Map;
} catch(_) {
// maybe a reference error because no `Map`. Give it a dummy value that no
// value will ever be an instanceof.
nativeMap = function() {};
}
var nativeSet;
try {
nativeSet = Set;
} catch(_) {
nativeSet = function() {};
}
var nativePromise;
try {
nativePromise = Promise;
} catch(_) {
nativePromise = function() {};
}
/**
* Clones (copies) an Object using deep copying.
*
* This function supports circular references by default, but if you are certain
* there are no circular references in your object, you can save some CPU time
* by calling clone(obj, false).
*
* Caution: if `circular` is false and `parent` contains circular references,
* your program may enter an infinite loop and crash.
*
* @param `parent` - the object to be cloned
* @param `circular` - set to true if the object to be cloned may contain
* circular references. (optional - true by default)
* @param `depth` - set to a number if the object is only to be cloned to
* a particular depth. (optional - defaults to Infinity)
* @param `prototype` - sets the prototype to be used when cloning an object.
* (optional - defaults to parent prototype).
* @param `includeNonEnumerable` - set to true if the non-enumerable properties
* should be cloned as well. Non-enumerable properties on the prototype
* chain will be ignored. (optional - false by default)
*/
function clone(parent, circular, depth, prototype, includeNonEnumerable) {
if (typeof circular === 'object') {
depth = circular.depth;
prototype = circular.prototype;
includeNonEnumerable = circular.includeNonEnumerable;
circular = circular.circular;
}
// maintain two arrays for circular references, where corresponding parents
// and children have the same index
var allParents = [];
var allChildren = [];
var useBuffer = typeof Buffer != 'undefined';
if (typeof circular == 'undefined')
circular = true;
if (typeof depth == 'undefined')
depth = Infinity;
// recurse this function so we don't reset allParents and allChildren
function _clone(parent, depth) {
// cloning null always returns null
if (parent === null)
return null;
if (depth === 0)
return parent;
var child;
var proto;
if (typeof parent != 'object') {
return parent;
}
if (_instanceof(parent, nativeMap)) {
child = new nativeMap();
} else if (_instanceof(parent, nativeSet)) {
child = new nativeSet();
} else if (_instanceof(parent, nativePromise)) {
child = new nativePromise(function (resolve, reject) {
parent.then(function(value) {
resolve(_clone(value, depth - 1));
}, function(err) {
reject(_clone(err, depth - 1));
});
});
} else if (clone.__isArray(parent)) {
child = [];
} else if (clone.__isRegExp(parent)) {
child = new RegExp(parent.source, __getRegExpFlags(parent));
if (parent.lastIndex) child.lastIndex = parent.lastIndex;
} else if (clone.__isDate(parent)) {
child = new Date(parent.getTime());
} else if (useBuffer && Buffer.isBuffer(parent)) {
if (Buffer.from) {
// Node.js >= 5.10.0
child = Buffer.from(parent);
} else {
// Older Node.js versions
child = new Buffer(parent.length);
parent.copy(child);
}
return child;
} else if (_instanceof(parent, Error)) {
child = Object.create(parent);
} else {
if (typeof prototype == 'undefined') {
proto = Object.getPrototypeOf(parent);
child = Object.create(proto);
}
else {
child = Object.create(prototype);
proto = prototype;
}
}
if (circular) {
var index = allParents.indexOf(parent);
if (index != -1) {
return allChildren[index];
}
allParents.push(parent);
allChildren.push(child);
}
if (_instanceof(parent, nativeMap)) {
parent.forEach(function(value, key) {
var keyChild = _clone(key, depth - 1);
var valueChild = _clone(value, depth - 1);
child.set(keyChild, valueChild);
});
}
if (_instanceof(parent, nativeSet)) {
parent.forEach(function(value) {
var entryChild = _clone(value, depth - 1);
child.add(entryChild);
});
}
for (var i in parent) {
var attrs = Object.getOwnPropertyDescriptor(parent, i);
if (attrs) {
child[i] = _clone(parent[i], depth - 1);
}
try {
var objProperty = Object.getOwnPropertyDescriptor(parent, i);
if (objProperty.set === 'undefined') {
// no setter defined. Skip cloning this property
continue;
}
child[i] = _clone(parent[i], depth - 1);
} catch(e){
if (e instanceof TypeError) {
// when in strict mode, TypeError will be thrown if child[i] property only has a getter
// we can't do anything about this, other than inform the user that this property cannot be set.
continue
} else if (e instanceof ReferenceError) {
//this may happen in non strict mode
continue
}
}
}
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(parent);
for (var i = 0; i < symbols.length; i++) {
// Don't need to worry about cloning a symbol because it is a primitive,
// like a number or string.
var symbol = symbols[i];
var descriptor = Object.getOwnPropertyDescriptor(parent, symbol);
if (descriptor && !descriptor.enumerable && !includeNonEnumerable) {
continue;
}
child[symbol] = _clone(parent[symbol], depth - 1);
Object.defineProperty(child, symbol, descriptor);
}
}
if (includeNonEnumerable) {
var allPropertyNames = Object.getOwnPropertyNames(parent);
for (var i = 0; i < allPropertyNames.length; i++) {
var propertyName = allPropertyNames[i];
var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName);
if (descriptor && descriptor.enumerable) {
continue;
}
child[propertyName] = _clone(parent[propertyName], depth - 1);
Object.defineProperty(child, propertyName, descriptor);
}
}
return child;
}
return _clone(parent, depth);
}
/**
* Simple flat clone using prototype, accepts only objects, usefull for property
* override on FLAT configuration object (no nested props).
*
* USE WITH CAUTION! This may not behave as you wish if you do not know how this
* works.
*/
clone.clonePrototype = function clonePrototype(parent) {
if (parent === null)
return null;
var c = function () {};
c.prototype = parent;
return new c();
};
// private utility functions
function __objToStr(o) {
return Object.prototype.toString.call(o);
}
clone.__objToStr = __objToStr;
function __isDate(o) {
return typeof o === 'object' && __objToStr(o) === '[object Date]';
}
clone.__isDate = __isDate;
function __isArray(o) {
return typeof o === 'object' && __objToStr(o) === '[object Array]';
}
clone.__isArray = __isArray;
function __isRegExp(o) {
return typeof o === 'object' && __objToStr(o) === '[object RegExp]';
}
clone.__isRegExp = __isRegExp;
function __getRegExpFlags(re) {
var flags = '';
if (re.global) flags += 'g';
if (re.ignoreCase) flags += 'i';
if (re.multiline) flags += 'm';
return flags;
}
clone.__getRegExpFlags = __getRegExpFlags;
return clone;
})();
export default clone
+19
View File
@@ -0,0 +1,19 @@
{
"id": "luch-request",
"displayName": "luch-request",
"version": "3.0.8",
"description": "基于Promise开发的跨平台、项目级别的请求库,它有更小的体积,易用的api,方便简单的自定义能力",
"keywords": [
"request",
"axios",
"网络请求",
"拦截器",
"promise"
],
"dcloudext": {
"category": [
"JS SDK",
"通用 SDK"
]
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+117
View File
@@ -0,0 +1,117 @@
<template>
<view class="min-height bg-linear">
<HeaderItem title="企业法治检查"/>
<view class="rounded-top min-height p-30 bg-gray-light">
<view class="my-20 card p-30">
<u-form label-width="140rpx">
<u-form-item label="企业名称" border-bottom>
<u-input v-model="formData.companyName" border="none" placeholder="请输入企业名称"/>
</u-form-item>
<u-form-item label="检查单位" border-bottom>
<u-input v-model="formData.checkCompanyName" border="none" placeholder="请输入检查单位"/>
</u-form-item>
<u-form-item label="检查日期" border-bottom @click="showDate = true">
<u-input v-model="formData.checkDate" border="none" placeholder="请选择检查日期" readonly>
<u-icon
slot="right"
name="arrow-right"
></u-icon>
</u-input>
</u-form-item>
<u-form-item label="来访类型" border-bottom @click="showType = true">
<u-input v-model="formData.type" border="none" placeholder="请选择来访类型" readonly>
<u-icon
slot="right"
name="arrow-right"
></u-icon>
</u-input>
</u-form-item>
<u-form-item label="本季度检查次数" border-bottom>
<u-input v-model="formData.checkNum" border="none" placeholder="请输入本季度检查次数"/>
</u-form-item>
<u-form-item label="来访评价" border-bottom>
<u-textarea maxlength="-1" v-model="formData.comment" border="none" placeholder="请输入来访评价"/>
</u-form-item>
<u-form-item label="备注说明">
<u-textarea maxlength="-1" v-model="formData.remark" border="none" placeholder="请输入备注说明"/>
</u-form-item>
</u-form>
</view>
<view class="mt-30">
<u-button type="primary" shape="circle" @click="save"
:hairline="false"
:custom-style="{border: 0, background: 'linear-gradient(91.28deg, rgba(14,146,252,1) 27.63%,rgba(29,188,188,1) 80.08%);'}">
提交
</u-button>
</view>
</view>
<u-picker :show="showType" :columns="[typeList]" @cancel="showType = false"
@confirm="selectType" key-name="dictDataCode"
/>
<u-datetime-picker
:show="showDate"
v-model="checkDate"
mode="date"
@confirm="selectDate"
/>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import {lawOrgCheckActionReq} from "@/api/lawOrg";
import {dictDataReq} from "@/api/common";
import dayjs from 'dayjs'
export default {
name: "action",
components: {HeaderItem},
data() {
return {
formData: {
companyName: '',
checkCompanyName: '',
checkDate: '',
type: '',
checkNum: '',
comment: '',
remark: '',
},
typeList: [],
showType: false,
showDate: false,
checkDate: Number(new Date()),
}
},
methods: {
async getDictList() {
const {data} = await dictDataReq({dictId: '164'})
this.typeList = data
},
async save() {
if (!this.formData.checkCompanyName) return this.$toast('请输入检查单位')
if (!this.formData.checkDate) return this.$toast('请选择检查日期')
if (!this.formData.type) return this.$toast('请选择来访类型')
if (!this.formData.checkNum) return this.$toast('请输入本季度检查次数')
const res = await lawOrgCheckActionReq(this.formData)
if (res) {
this.$toast('提交成功')
setTimeout(() => {
uni.navigateBack()
}, 500)
}
},
selectType({value}) {
this.formData.type = value[0].dictDataCode
this.showType = false
},
selectDate({value}){
this.showDate = false
this.formData.checkDate = dayjs(value).format("YYYY-MM-DD")
}
},
onLoad() {
this.getDictList()
},
}
</script>
+13
View File
@@ -0,0 +1,13 @@
<template>
</template>
<script>
export default {
name: "aiChat",
data() {
return {}
},
methods: {}
}
</script>
+78
View File
@@ -0,0 +1,78 @@
<template>
<view class="min-height bg-main-light p-25">
<HeaderItem title="人员机构查询"/>
<TitleItem title="法律服务机构"/>
<view class="flex justify-start items-center flex-wrap mt-20">
<view v-for="(item, index) in orgTypeList" :key="index" class="mr-15 mb-15 pos-r"
style="width: 220rpx; height: 120rpx" @click="$jump(`/lawOrgPages/pages/orgList?type=${item.dictDataCode}`)">
<view class="pos-a" style="left: 0;top: 0">
<u-image src="/lawOrgPages/static/ticket.png" width="220rpx" height="120rpx"/>
</view>
<view class="flex justify-center items-center flex-col pos-a text-25"
style="z-index: 1;left: 0;top: 0; width: 220rpx; padding-top: 25rpx">
<text class="text-20">{{ item.dictDataCode }}</text>
<text class="text-red mt-30" v-if="orgList && orgList.length">{{ orgList.filter(o => o.type === item.dictDataCode).length }}</text>
</view>
</view>
</view>
<TitleItem title="法律服务人员"/>
<view class="flex justify-start items-center flex-wrap mt-20">
<view v-for="(item, index) in orgPeopleTypeList" :key="index" class="mr-15 mb-15 pos-r"
style="width: 220rpx; height: 120rpx" @click="$jump(`/lawOrgPages/pages/peopleList?type=${item.dictDataCode}`)">
<view class="pos-a" style="left: 0;top: 0">
<u-image src="/lawOrgPages/static/ticket.png" width="220rpx" height="120rpx"/>
</view>
<view class="flex justify-center items-center flex-col pos-a text-25"
style="z-index: 1;left: 0;top: 0; width: 220rpx; padding-top: 25rpx">
<text class="text-20">{{ item.dictDataCode }}</text>
<text class="text-red mt-30">{{ orgPeopleList.filter(o => o.type === item.dictDataCode).length }}</text>
</view>
</view>
</view>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import {dictDataReq} from "@/api/common";
import {listLawOrgPeopleReq, listLawOrgReq} from "@/api/lawOrg";
import TitleItem from "@/components/TitleItem.vue";
export default {
name: "index",
components: {TitleItem, HeaderItem},
data() {
return {
orgTypeList: [],
orgPeopleTypeList: [],
orgList: [],
orgPeopleList: [],
}
},
methods: {
async getOrgTypeList() {
const {data} = await dictDataReq({dictId: '161'})
this.orgTypeList = data
},
async getPeopleTypeList() {
const {data} = await dictDataReq({dictId: '162'})
this.orgPeopleTypeList = data
},
async getOrgList() {
const {data} = await listLawOrgReq()
this.orgList = data
},
async getPeopleList() {
const {data} = await listLawOrgPeopleReq()
this.orgPeopleList = data
},
},
async onLoad() {
await this.getOrgTypeList()
await this.getOrgList()
await this.getPeopleTypeList()
await this.getPeopleList()
},
}
</script>
+141
View File
@@ -0,0 +1,141 @@
<template>
<view class="min-height bg-main-light">
<HeaderItem title="法律服务地图"/>
<view class="p-20 pos-r bg-linear">
<u-input v-model="keyword" shape="circle" :custom-style="{background: 'white', height: '65rpx'}"
placeholder="请输入您要查找的机构姓名"/>
<view class="pos-a" style="right: 30rpx; top: 25rpx">
<u-button shape="circle" type="primary" :custom-style="{width: '200rpx', zIndex: 9999}" @click="getList">
搜索
</u-button>
</view>
</view>
<view class="card m-20 flex justify-center items-center" @click="showType = true">
<u-icon name="arrow-down" :label="type" label-pos="left" label-size="25rpx"/>
</view>
<map style="width: 100%; height: calc(100vh - 410rpx);"
@markertap="onClickedMarker"
:scale="scale"
:longitude="longitude"
:latitude="latitude"
:markers="markers">
</map>
<view class="bottom pos-r" v-if="showBottom">
<view style="position:absolute; right: 20rpx; top: 20rpx" @click="showBottom = false">
<u-icon name="close"/>
</view>
<view class="p-50 flex justify-between items-center text-25">
<view class="flex flex-col justify-start items-start" v-if="showBottom && clickedItem">
<text class="text-28 font-bold">{{ clickedItem.title }}</text>
<text class="mt-15 text-25">{{ clickedItem.province }}{{ clickedItem.city }}{{ clickedItem.region }}</text>
</view>
<view>
<u-icon name="/lawOrgPages/static/map-circle.png" size="100rpx" @click="toNav" label="到这去" label-size="25rpx"
space="10rpx" label-pos="bottom"/>
</view>
</view>
</view>
<u-picker :show="showType" :columns="[typeList]" @cancel="showType = false"
:default-index="defaultIndex"
@confirm="selectType" key-name="dictDataCode"
/>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import {dictDataReq} from "@/api/common";
import {listLawOrgReq} from "@/api/lawOrg";
import {MAIN} from "@/config/color";
import coordtransform from 'coordtransform'
export default {
name: "peopleList",
components: {HeaderItem},
data() {
return {
type: '全部机构类型',
keyword: '',
list: [],
typeList: [],
defaultIndex: [0],
showType: false,
longitude: null,
latitude: null,
clickedItem: null,
showBottom: null,
scale: 13,
markers: []
}
},
methods: {
MAIN() {
return MAIN
},
async getTypeList() {
const {data} = await dictDataReq({dictId: '161'})
this.typeList = [{dictDataCode: '全部机构类型'}, ...data]
},
selectType({value}) {
this.type = value[0].dictDataCode
this.showType = false
this.getList()
},
async getList() {
const {data} = await listLawOrgReq({
keywords: this.keyword
})
this.markers = []
this.list = this.type !== '全部机构类型' ? data.filter(item => item.type === this.type) : data
if (this.list.length) {
this.markers = this.list.map(item => {
const [lng, lat] = coordtransform.wgs84togcj02(item.lng, item.lat)
return {
id: item.id,
width: 20,
height: 30,
latitude: parseFloat(lat),
longitude: parseFloat(lng)
}
})
this.latitude = parseFloat(this.list[0].lat)
this.longitude = parseFloat(this.list[0].lng)
}else this.$toast('暂无数据')
},
call(phoneNumber) {
uni.makePhoneCall({
phoneNumber: phoneNumber
})
},
onClickedMarker({markerId}) {
this.clickedItem = this.list.find(item => item.id === markerId)
this.showBottom = true
},
toNav(){
const [lng, lat] = coordtransform.wgs84togcj02(this.clickedItem.lng, this.clickedItem.lat)
uni.openLocation({
latitude: parseFloat(lat),
longitude: parseFloat(lng),
name: this.clickedItem.title,
address: `${this.clickedItem.province}${this.clickedItem.city}${this.clickedItem.region}${this.clickedItem.address}`,
})
}
},
onLoad() {
this.getTypeList()
this.getList()
}
}
</script>
<style lang="scss" scoped>
.bottom {
position: fixed;
left: 0;
bottom: 0;
border-radius: 30rpx 30rpx 0 0;
background-color: white;
width: 100%;
height: 300rpx;
}
</style>
+107
View File
@@ -0,0 +1,107 @@
<template>
<view class="min-height bg-main-light">
<HeaderItem title="机构"/>
<view class="p-20 pos-r bg-linear">
<u-input v-model="keyword" shape="circle" :custom-style="{background: 'white', height: '65rpx'}"
placeholder="请输入您要查找的机构姓名"/>
<view class="pos-a" style="right: 30rpx; top: 30rpx">
<u-button shape="circle" type="primary" :custom-style="{width: '200rpx', zIndex: 9999}" @click="getList">
搜索
</u-button>
</view>
</view>
<view class="card m-20 flex justify-center items-center" @click="showType = true">
<u-icon name="arrow-down" :label="type" label-pos="left" label-size="25rpx"/>
</view>
<template v-if="list.length">
<view class="bg-white rounded m-20 flex flex-col justify-start items-start" v-for="(item, index) in list"
:key="index" style="padding: 25rpx 0">
<text class="text-28 text-main m-15 mx-25">{{ item.title }}</text>
<view class="flex justify-start items-center text-25 text-gray-weight w-100p pb-20"
style="border-bottom: 1px dotted #6EA5D1">
<u-icon name="/lawOrgPages/static/building.png" size="100rpx"/>
<view class="flex flex-col justify-start items-start w-80p ml-15">
<view class="flex justify-between items-center mt-15 w-100p" @click="call(item.phone)">
<text>联系方式: {{ item.phone }}</text>
<u-icon name="phone" :color="MAIN()" size="40rpx"/>
</view>
<text class="mt-15">机构地址: {{ item.province }}{{ item.city }}{{ item.region }}</text>
<text class="mt-15">详细地址: {{ item.address }}</text>
</view>
</view>
<view class="py-15 flex justify-center items-center w-100p" @click="toMap(item)">
<u-icon name="/lawOrgPages/static/position.png" size="40rpx" label="到这去" :label-color="MAIN()"
label-pos="right" label-size="28rpx"/>
</view>
</view>
</template>
<u-empty v-else icon="/lawOrgPages/static/empty.png"/>
<u-picker :show="showType" :columns="[typeList]" @cancel="showType = false"
:default-index="defaultIndex"
@confirm="selectType" key-name="dictDataCode"
/>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import {dictDataReq} from "@/api/common";
import {listLawOrgPeopleReq, listLawOrgReq} from "@/api/lawOrg";
import {MAIN} from "@/config/color";
import coordtransform from 'coordtransform'
export default {
name: "peopleList",
components: {HeaderItem},
data() {
return {
type: '',
keyword: '',
list: [],
typeList: [],
defaultIndex: [0],
showType: false
}
},
methods: {
MAIN() {
return MAIN
},
async getTypeList() {
const {data} = await dictDataReq({dictId: '161'})
this.typeList = data
this.defaultIndex = [data.findIndex(item => item.dictDataCode === this.type)]
},
selectType({value}) {
this.type = value[0].dictDataCode
this.showType = false
this.getList()
},
async getList() {
const {data} = await listLawOrgReq({
keywords: this.keyword
})
this.list = data.filter(item => item.type === this.type)
},
call(phoneNumber) {
uni.makePhoneCall({
phoneNumber: phoneNumber
})
},
toMap(item){
const [lng, lat] = coordtransform.wgs84togcj02(item.lng, item.lat)
uni.openLocation({
latitude: parseFloat(lat),
longitude: parseFloat(lng),
name: item.title,
address: `${item.province}${item.city}${item.region}${item.address}`,
})
}
},
onLoad({type}) {
this.type = type
this.getTypeList()
this.getList()
}
}
</script>
+90
View File
@@ -0,0 +1,90 @@
<template>
<view class="min-height bg-main-light">
<HeaderItem title="人员"/>
<view class="p-20 pos-r bg-linear">
<u-input v-model="keyword" shape="circle" :custom-style="{background: 'white', height: '65rpx'}"
placeholder="请输入您要查找的人员姓名"/>
<view class="pos-a" style="right: 30rpx; top: 30rpx">
<u-button shape="circle" type="primary" :custom-style="{width: '200rpx', zIndex: 9999}" @click="getList">
搜索
</u-button>
</view>
</view>
<view class="card m-20 flex justify-center items-center" @click="showType = true">
<u-icon name="arrow-down" :label="type" label-pos="left" label-size="25rpx"/>
</view>
<template v-if="list.length">
<view class="card m-20 flex justify-start items-start" v-for="(item, index) in list" :key="index">
<u-icon name="/lawOrgPages/static/header.png" size="80rpx"/>
<view class="ml-15 flex flex-col justify-start text-25 text-gray-weight w-100p">
<text class="text-28">{{ item.name }}</text>
<view class="flex justify-between items-center mt-15 w-100p" @click="call(item.phone)">
<text>联系方式: {{ item.phone }}</text>
<u-icon name="phone" :color="MAIN()" size="50rpx"/>
</view>
<text class="mt-15">技术职称: {{ item.position }}</text>
<text class="mt-15">执业类别: {{ item.positionType }}</text>
<text class="mt-15">执业机构: {{ item.lawOrg ? item.lawOrg.title : '' }}</text>
</view>
</view>
</template>
<u-empty v-else icon="/lawOrgPages/static/empty.png"/>
<u-picker :show="showType" :columns="[typeList]" @cancel="showType = false"
:default-index="defaultIndex"
@confirm="selectType" key-name="dictDataCode"
/>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import {dictDataReq} from "@/api/common";
import {listLawOrgPeopleReq} from "@/api/lawOrg";
import {MAIN} from "@/config/color";
export default {
name: "peopleList",
components: {HeaderItem},
data() {
return {
type: '',
keyword: '',
list: [],
typeList: [],
defaultIndex: [0],
showType: false
}
},
methods: {
MAIN() {
return MAIN
},
async getTypeList() {
const {data} = await dictDataReq({dictId: '162'})
this.typeList = data
this.defaultIndex = [data.findIndex(item => item.dictDataCode === this.type)]
},
selectType({value}) {
this.type = value[0].dictDataCode
this.showType = false
this.getList()
},
async getList() {
const {data} = await listLawOrgPeopleReq({
keywords: this.keyword
})
this.list = data.filter(item => item.type === this.type)
},
call(phoneNumber){
uni.makePhoneCall({
phoneNumber: phoneNumber
})
}
},
onLoad({type}) {
this.type = type
this.getTypeList()
this.getList()
}
}
</script>
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

+175
View File
@@ -0,0 +1,175 @@
<template>
<view class="min-height bg-main-light">
<HeaderItem title="智能生成法律文书"/>
<view class="bg-white p-20 text-25 flex justify-center items-center">
<text class="tag selected-tag">{{ title }}</text>
</view>
<view class="pos-r" v-if="configList && configList.length">
<view class="circle-bottom-bg"></view>
<view class="tips-card-wrap">
<view class="tips-card">
<view class="text-28 font-bold text-center p-30">【{{ typeLabel }}】</view>
<u-line color="#1DBCBC" dashed></u-line>
<view class="text-25 p-20">{{ configList[activeIndex].title }}</view>
<view class="p-20 flex justify-start items-center" @click="selectItem(item, index)"
v-for="(item, index) in JSON.parse(configList[activeIndex].answer)" :key="index">
<template v-if="configList[activeIndex].type === 'single'">
<u-icon
:name="configList[activeIndex].selected.includes(item) ? '/legalLegalDoc/static/radio-selected.png' : '/legalLegalDoc/static/radio.png'"/>
<text class="text-25 ml-10">{{ item }}</text>
</template>
<template v-else-if="configList[activeIndex].type === 'multi'">
<u-icon
:name="configList[activeIndex].selected.includes(item) ? '/legalLegalDoc/static/checkbox-selected.png' : '/legalLegalDoc/static/checkbox.png'"/>
<text class="text-25 ml-10">{{ item }}</text>
</template>
</view>
<u-gap height="100rpx"/>
</view>
</view>
</view>
<view class="footer">
<view class="flex justify-center items-center text-25" style="border-top: 1px solid #ccc">
<view class="flex-1 text-blue p-30 text-center" @click="toLastItem">
返回
</view>
<view class="flex-1 bg-linear p-30 text-white text-center" @click="toNextItem">
下一步
</view>
</view>
</view>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import {legalDocConfigReq} from "@/api/legalDoc";
export default {
name: "detail",
components: {HeaderItem},
data() {
return {
id: 0,
title: '',
configList: [],
typeList: [{value: 'single', label: '单选'}, {value: 'multi', label: '多选'}, {value: 'fill', label: '填空'}],
activeIndex: 0,
typeLabel: '',
}
},
methods: {
async getList() {
const {data} = await legalDocConfigReq({
typeId: this.id
})
this.configList = data
this.typeLabel = this.typeList.find(item => item.value === data[0].type).label
this.configList.map(item => {
item.selected = []
return item
})
},
selectItem(item, index) {
// console.log(index, this.configList[index], this.configList.length - 1)
if (this.configList[this.activeIndex].type === 'single') {
this.configList[this.activeIndex].selected = [item]
if (this.activeIndex === this.configList.length - 1) {
this.toEnd()
} else {
this.activeIndex += 1
this.typeLabel = this.typeList.find(item => item.value === this.configList[this.activeIndex].type).label
}
} else if (this.configList[this.activeIndex].type === 'multi') {
const hasIndex = this.configList[this.activeIndex].selected.findIndex(i => i === item)
if (hasIndex > -1) {
this.configList[this.activeIndex].selected.splice(hasIndex, 1)
} else {
this.configList[this.activeIndex].selected.push(item)
}
}
this.$forceUpdate()
},
toNextItem() {
if (!this.configList[this.activeIndex].selected.length) {
return this.$toast('请选择选项')
}
if (this.activeIndex === this.configList.length - 1) {
this.toEnd()
} else {
this.activeIndex += 1
this.typeLabel = this.typeList.find(item => item.value === this.configList[this.activeIndex].type).label
}
},
toLastItem() {
if (this.activeIndex === 0) uni.navigateBack()
else this.activeIndex -= 1
},
toEnd() {
let content = []
this.configList.map(item => {
content.push({
quest: item.title,
answer: item.selected
})
})
uni.navigateTo({
url: `/legalLegalDoc/pages/result?title=${this.title}&typeId=${this.id}`,
success: res => {
res.eventChannel.emit('content', content)
}
})
}
},
onLoad({id, title}) {
this.id = id
this.title = title
this.getList()
}
}
</script>
<style scoped lang="scss">
.tag {
padding: 10rpx 25rpx;
margin-right: 25rpx;
flex-shrink: 0;
}
.selected-tag {
background-color: #FFCA68;
border-radius: 100rpx;
}
.circle-bottom-bg {
background-color: #1DBCBC;
width: 100vw;
height: 200rpx;
position: absolute;
left: 0;
top: 0;
border-radius: 0 0 100vw 100vw;
}
.tips-card-wrap {
position: absolute;
left: 0;
top: 70rpx;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
.tips-card {
width: 80%;
line-height: 30rpx;
border-radius: 50rpx;
background-color: rgba(255, 255, 255, 1);
color: rgba(16, 16, 16, 1);
box-shadow: 0 2px 6px 0 rgba(202, 247, 247, 1);
margin-bottom: 50rpx;
}
}
</style>
+108
View File
@@ -0,0 +1,108 @@
<template>
<view class="min-height bg-main-light">
<HeaderItem title="智能生成法律文书"/>
<view class="bg-white p-20 text-25 flex justify-start items-center overflow-x">
<text v-for="(item, index) in typeList" :key="index" class="tag"
@click="changeType(index)"
:class="[item.id === activeId ? 'selected-tag' : '']">{{ item.title }}
</text>
</view>
<view class="pos-r">
<view class="circle-bottom-bg"></view>
<view class="tips-card-wrap">
<view class="tips-card">
<view class="text-28 font-bold text-center">{{ activeTitle }}</view>
<view class="text-25 mt-20" style="padding-bottom: 50rpx">
{{ activeContent }}
</view>
</view>
<u-button shape="circle" @click="$jump(`/legalLegalDoc/pages/detail?id=${activeId}&title=${activeTitle}`)"
:customStyle="{background: 'linear-gradient(91.28deg, rgba(14,146,252,1) 27.63%,rgba(29,188,188,1) 80.08%)',
border: 0, width: '200rpx',
color: 'white'}">
开始
</u-button>
</view>
</view>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import {listLegalDocTypeReq} from "@/api/legalDoc";
export default {
name: "index",
components: {HeaderItem},
data() {
return {
typeList: [],
activeId: 0,
activeTitle: 0,
activeContent: '',
}
},
methods: {
async getTypeList() {
const {data} = await listLegalDocTypeReq()
this.typeList = data
this.activeId = data[0].id
this.activeTitle = data[0].title
this.activeContent = data[0].comment
},
changeType(index){
this.activeId = this.typeList[index].id
this.activeTitle = this.typeList[index].title
this.activeContent = this.typeList[index].comment
}
},
onLoad() {
this.getTypeList()
},
}
</script>
<style scoped lang="scss">
.tag {
padding: 10rpx 25rpx;
margin-right: 25rpx;
flex-shrink: 0;
}
.selected-tag {
background-color: #FFCA68;
border-radius: 100rpx;
}
.circle-bottom-bg {
background-color: #3A89CD;
width: 100vw;
height: 200rpx;
position: absolute;
left: 0;
top: 0;
border-radius: 0 0 100vw 100vw;
}
.tips-card-wrap {
position: absolute;
left: 0;
top: 70rpx;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
.tips-card {
width: 80%;
line-height: 30rpx;
padding: 30rpx;
border-radius: 50rpx;
background-color: rgba(255, 255, 255, 1);
color: rgba(16, 16, 16, 1);
box-shadow: 0 2px 6px 0 rgba(202, 247, 247, 1);
margin-bottom: 50rpx;
}
}
</style>
+143
View File
@@ -0,0 +1,143 @@
<template>
<view class="min-height bg-main-light p-30">
<HeaderItem :title="title"/>
<view class="text-30 font-bold text-center">{{ title }}</view>
<u-textarea v-model="contentDetail" border="none" maxlength="-1" :disabled="disabled" autoHeight
:customStyle="{background: 'transparent'}" :confirmType="null"/>
<view class="footer flex justify-center items-center text-white text-25" v-if="disabled">
<view class="bg-linear flex-1 p-20 flex justify-center items-center" @click="make('email')">
<u-icon name="email" color="white" size="40rpx"/>
<text>发送至邮箱</text>
</view>
<view class="bg-white flex-1 p-20 flex justify-center items-center text-black" @click="make('download')">
<u-icon name="/legalLegalDoc/static/mobile.png" size="40rpx"/>
<text>下载至手机</text>
</view>
<view class="bg-linear flex-1 p-20 flex justify-center items-center" @click="disabled = false">
<u-icon name="edit-pen" color="white" size="40rpx"/>
<text>我要编辑</text>
</view>
</view>
<view class="footer flex justify-center items-center text-white text-25 bg-linear" v-else>
<view class="flex-1 p-20 text-center" @click="disabled = true">我要带走</view>
</view>
<u-popup :show="showEmail" close-on-click-overlay @close="showEmail = false" round="10"
:closeable="false" mode="center" :customStyle="{width: '80%'}"
:safe-area-inset-bottom="false">
<view class="p-50 pos-r" v-if="showEmail">
<u-input v-model="email" placeholder="请填写邮箱地址"/>
</view>
<view class="flex justify-center items-center text-25">
<view class="flex-1 p-20 text-center" @click="showEmail = false">取消发送</view>
<view class="flex-1 p-20 bg-linear text-white text-center" style="border-radius: 0 0 10px 0" @click="doSend">
确认发送
</view>
</view>
</u-popup>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import {listArticleReq} from "@/api/common";
import {listLegalOrgCheckTypeInfoReq} from "@/api/legalOrgCheck";
import piaoyiProgressBar
from '@/uni_modules/piaoyi-progress-bar/components/piaoyi-progress-bar/piaoyi-progress-bar.vue';
import {legalDocMakeReq, legalDocSendEmailReq, legalDocTypeInfoReq} from "@/api/legalDoc";
import {API, MAIN_API} from "@/config";
export default {
name: "result",
components: {HeaderItem, piaoyiProgressBar},
data() {
return {
title: '',
typeId: null,
content: [],
config: null,
articleList: [],
point: 0,
levelStyle: {
color: 'white',
background: 'linear-gradient(97.98deg, rgba(255,201,35,1) 30.49%,rgba(255,144,10,1) 78.96%)',
border: 0,
width: '300rpx'
},
disabled: false,
showEmail: false,
contentDetail: '',
email: '',
file: '',
}
},
methods: {
back() {
uni.navigateBack()
},
async getConfig() {
const {data} = await legalDocTypeInfoReq(this.typeId)
this.config = data
this.contentDetail = `${this.config.topContent}\n`
this.content.map(item => {
this.contentDetail += `${item.quest}\n`
item.answer.map(answer => {
this.contentDetail += `${answer}\n`
})
this.contentDetail += `\n`
})
this.contentDetail += ` 此致\n`
this.contentDetail += ` 人民法院\n`
this.contentDetail += ` 申请人(签字):\n`
this.contentDetail += ` 年 月 日\n`
this.contentDetail += `${this.config.extraContent}\n`
},
async make(method) {
const {data} = await legalDocMakeReq({
title: this.title,
userContent: this.contentDetail
})
this.file = data
if (method === 'download') {
uni.showLoading({
title: '下载中'
})
uni.downloadFile({
url: `${API}${data}`,
success: function (res) {
uni.hideLoading()
uni.openDocument({
showMenu: true,
filePath: res.tempFilePath
})
}
})
} else {
this.email = ''
this.showEmail = true
}
},
async doSend() {
if (!this.email) return this.$toast('请输入邮箱地址')
await legalDocSendEmailReq({
email: this.email,
title: this.title,
file: this.file
})
this.showEmail = false
this.$toast('已发送,请注意查收')
}
},
onLoad({title, typeId, point}) {
this.title = title
this.typeId = typeId
this.point = point
const eventChannel = this.getOpenerEventChannel();
eventChannel.on('content', async data => {
this.content = data
console.log(this.content)
await this.getConfig()
})
}
}
</script>
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

+195
View File
@@ -0,0 +1,195 @@
<template>
<view class="min-height bg-main-light">
<HeaderItem title="企业法治体检"/>
<view class="bg-white p-20 text-25 flex justify-center items-center">
<text class="tag selected-tag">{{ title }}</text>
</view>
<view class="pos-r" v-if="configList && configList.length">
<view class="circle-bottom-bg"></view>
<view class="tips-card-wrap">
<view class="tips-card">
<view class="text-28 font-bold text-center p-30">【{{ typeLabel }}】</view>
<u-line color="#1DBCBC" dashed></u-line>
<view class="text-25 p-20">{{ configList[activeIndex].title }}</view>
<view class="p-20 flex justify-start items-center" @click="selectItem(item, index)"
v-for="(item, index) in JSON.parse(configList[activeIndex].answer)" :key="index">
<template v-if="configList[activeIndex].type === 'single'">
<u-icon
:name="configList[activeIndex].selected.includes(item.content) ? '/legalOrgCheck/static/radio-selected.png' : '/legalOrgCheck/static/radio.png'"/>
<text class="text-25 ml-10">{{ item.content }}</text>
</template>
<template v-else-if="configList[activeIndex].type === 'multi'">
<u-icon
:name="configList[activeIndex].selected.includes(item.content) ? '/legalOrgCheck/static/checkbox-selected.png' : '/legalOrgCheck/static/checkbox.png'"/>
<text class="text-25 ml-10">{{ item.content }}</text>
</template>
</view>
<u-gap height="100rpx"/>
</view>
<view class="flex justify-center items-center">
<view class="mx-15">
<u-button shape="circle" @click="toLastItem" v-if="activeIndex > 0"
:customStyle="{background: 'linear-gradient(91.28deg, rgba(14,146,252,1) 27.63%,rgba(29,188,188,1) 80.08%)',
border: 0, width: '200rpx',
color: 'white'}">
查看上一题
</u-button>
</view>
<view class="mx-15">
<u-button shape="circle" @click="toNextItem"
v-if="activeIndex > 0 && configList[activeIndex].type === 'multi'"
:customStyle="{background: 'linear-gradient(91.28deg, rgba(14,146,252,1) 27.63%,rgba(29,188,188,1) 80.08%)',
border: 0, width: '200rpx',
color: 'white'}">
确认
</u-button>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import {listLegalOrgCheckConfigReq} from "@/api/legalOrgCheck";
export default {
name: "detail",
components: {HeaderItem},
data() {
return {
id: 0,
title: '',
configList: [],
typeList: [{value: 'single', label: '单选'}, {value: 'multi', label: '多选'}, {value: 'fill', label: '填空'}],
activeIndex: 0,
typeLabel: '',
point: 0
}
},
methods: {
async getList() {
const {data} = await listLegalOrgCheckConfigReq({
typeId: this.id
})
this.configList = data
this.typeLabel = this.typeList.find(item => item.value === data[0].type).label
this.configList.map(item => {
item.selected = []
return item
})
},
selectItem(item, index) {
// console.log(index, this.configList[index], this.configList.length - 1)
if (this.configList[this.activeIndex].type === 'single') {
this.configList[this.activeIndex].selected = [item.content]
if (this.activeIndex === this.configList.length - 1) {
this.toEnd()
} else {
this.activeIndex += 1
this.typeLabel = this.typeList.find(item => item.value === this.configList[this.activeIndex].type).label
}
} else if (this.configList[this.activeIndex].type === 'multi') {
const hasIndex = this.configList[this.activeIndex].selected.findIndex(i => i === item.content)
if (hasIndex > -1) {
this.configList[this.activeIndex].selected.splice(hasIndex, 1)
} else {
this.configList[this.activeIndex].selected.push(item.content)
}
}
this.calPoint()
this.$forceUpdate()
},
calPoint() {
this.point = 0
this.configList.forEach(item => {
JSON.parse(item.answer).map(answer => {
if (item.selected.includes(answer.content)) {
this.point += parseFloat(answer.point)
}
})
})
},
toNextItem() {
if (!this.configList[this.activeIndex].selected.length) {
return this.$toast('请选择选项')
}
if (this.activeIndex === this.configList.length - 1) {
this.toEnd()
} else {
this.activeIndex += 1
this.typeLabel = this.typeList.find(item => item.value === this.configList[this.activeIndex].type).label
}
},
toLastItem() {
this.activeIndex -= 1
},
toEnd() {
let content = []
this.configList.map(item => {
content.push({
quest: item.title,
answer: item.selected.join('、')
})
})
uni.navigateTo({
url: `/legalOrgCheck/pages/result?title=${this.title}&typeId=${this.id}&point=${this.point}`,
success: res => {
res.eventChannel.emit('content', content)
}
})
}
},
onLoad({id, title}) {
this.id = id
this.title = title
this.getList()
}
}
</script>
<style scoped lang="scss">
.tag {
padding: 10rpx 25rpx;
margin-right: 25rpx;
flex-shrink: 0;
}
.selected-tag {
background-color: #FFCA68;
border-radius: 100rpx;
}
.circle-bottom-bg {
background-color: #1DBCBC;
width: 100vw;
height: 200rpx;
position: absolute;
left: 0;
top: 0;
border-radius: 0 0 100vw 100vw;
}
.tips-card-wrap {
position: absolute;
left: 0;
top: 70rpx;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
.tips-card {
width: 80%;
line-height: 30rpx;
border-radius: 50rpx;
background-color: rgba(255, 255, 255, 1);
color: rgba(16, 16, 16, 1);
box-shadow: 0 2px 6px 0 rgba(202, 247, 247, 1);
margin-bottom: 50rpx;
}
}
</style>
+109
View File
@@ -0,0 +1,109 @@
<template>
<view class="min-height bg-main-light">
<HeaderItem title="企业法治体检"/>
<u-image src="/legalOrgCheck/static/v2_suc04p.png" width="100%" height="160rpx" mode="widthFix"></u-image>
<view class="bg-white p-20 text-25 flex justify-start items-center overflow-x">
<text v-for="(item, index) in typeList" :key="index" class="tag"
@click="changeType(index)"
:class="[item.id === activeId ? 'selected-tag' : '']">{{ item.title }}
</text>
</view>
<view class="pos-r">
<view class="circle-bottom-bg"></view>
<view class="tips-card-wrap">
<view class="tips-card">
<view class="text-28 font-bold text-center">{{ activeTitle }}</view>
<view class="text-25 mt-20" style="padding-bottom: 50rpx">
{{ activeContent }}
</view>
</view>
<u-button shape="circle" @click="$jump(`/legalOrgCheck/pages/detail?id=${activeId}&title=${activeTitle}`)"
:customStyle="{background: 'linear-gradient(91.28deg, rgba(14,146,252,1) 27.63%,rgba(29,188,188,1) 80.08%)',
border: 0, width: '200rpx',
color: 'white'}">
开始
</u-button>
</view>
</view>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import {listLegalOrgCheckTypeReq} from "@/api/legalOrgCheck";
export default {
name: "index",
components: {HeaderItem},
data() {
return {
typeList: [],
activeId: 0,
activeTitle: 0,
activeContent: '',
}
},
methods: {
async getTypeList() {
const {data} = await listLegalOrgCheckTypeReq()
this.typeList = data
this.activeId = data[0].id
this.activeTitle = data[0].title
this.activeContent = data[0].content
},
changeType(index){
this.activeId = this.typeList[index].id
this.activeTitle = this.typeList[index].title
this.activeContent = this.typeList[index].content
}
},
onLoad() {
this.getTypeList()
},
}
</script>
<style scoped lang="scss">
.tag {
padding: 10rpx 25rpx;
margin-right: 25rpx;
flex-shrink: 0;
}
.selected-tag {
background-color: #FFCA68;
border-radius: 100rpx;
}
.circle-bottom-bg {
background-color: #3A89CD;
width: 100vw;
height: 200rpx;
position: absolute;
left: 0;
top: 0;
border-radius: 0 0 100vw 100vw;
}
.tips-card-wrap {
position: absolute;
left: 0;
top: 70rpx;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
.tips-card {
width: 80%;
line-height: 30rpx;
padding: 30rpx;
border-radius: 50rpx;
background-color: rgba(255, 255, 255, 1);
color: rgba(16, 16, 16, 1);
box-shadow: 0 2px 6px 0 rgba(202, 247, 247, 1);
margin-bottom: 50rpx;
}
}
</style>
+27
View File
@@ -0,0 +1,27 @@
<template>
<web-view :src="`https://sifa-h5.wsdns.cn/#/legalOrgCheck/pages/result?id=${id}&typeId=${typeId}`"
@message="onMessage" @onPostMessage="onMessage"/>
<!-- <web-view :src="`http://localhost:8080/#/legalOrgCheck/pages/result?id=${id}&typeId=${typeId}`"-->
<!-- @message="onMessage" @onPostMessage="onMessage"/>-->
</template>
<script>
export default {
name: "pdfResult",
data() {
return {
id: null,
typeId: null,
}
},
methods: {
onMessage(e) {
console.log(e)
}
},
onLoad({id, typeId}) {
this.id = id
this.typeId = typeId
},
}
</script>
+222
View File
@@ -0,0 +1,222 @@
<template>
<view class="min-height bg-main-light">
<HeaderItem :title="title"/>
<view class="p-30 bg-linear text-25 text-white pos-r" style="border-radius: 0 0 1000rpx 1000rpx" id="tag0">
<view class="flex justify-center items-center">
<view>贵公司(单位)存在的</view>
<view class="text-orange">{{ title }}</view>
<view>为</view>
</view>
<view class="flex justify-center items-center pos-r mt-25">
<piaoyiProgressBar canvasId="progressCanvas4" :progress="25" backgroundColor="#EFEFF4"
progressBackgroundColor="#FFC923" :showText="false" textColor="#000000" :textSize="24"
:height="10"
:isCircular="true" :diameter="100"></piaoyiProgressBar>
<view class="flex justify-center items-center text-20 pos-a w-100p" style="left: 0; top: 0; height: 100rpx">
{{ point }}分
</view>
</view>
<view class="mt-25 text-25 text-white text-center">(数值越高风险越大)</view>
<view class="pos-a w-100p flex justify-center items-center" style="bottom: -50rpx; left: 0">
<u-button :customStyle="levelStyle" shape="circle">
{{ comment }}
</u-button>
</view>
</view>
<u-gap height="40rpx"></u-gap>
<view class="card m-30 text-25" style="text-indent: 50rpx">
您好! 感谢您使用“企业法治体检”对贵企业进行法律风险评估,根据您描述,结合人工智能技术,为你生成企业法治体检风险指数报告,以供参考,经评测,贵企业企业合同风险分析如下:
</view>
<view class="card m-30" id="tag1">
<view v-if="loading" class="p-15 flex justify-center items-center">
<u-loading-icon mode="semicircle" :color="MAIN()"></u-loading-icon>
</view>
<zero-markdown-view :markdown="returnContent" v-else></zero-markdown-view>
</view>
<view class="card m-30 text-25" id="tag2">
<view class="font-bold text-center">---温馨提示---</view>
<view style="text-indent: 50rpx" class="my-15">
平台提醒:您的企业有着较高的企业合同风险防范意识,基本可以很好的避免企业合同风险,但此次测评仅从单一的法律领域内进行的评估,此后您的企业可在专业人士的指导下从多方法律领域进行评估,就其他可能存在风险的问题进行完善,进一步提高防控水平,以更好地规范公司各项制度。
</view>
<view style="color: #77A5CD">请注意:此次测评仅以公司经营过程中常见法律风险为参数进行评估,测评结果仅供参考。</view>
</view>
<u-gap height="200rpx"></u-gap>
<view class="footer flex justify-center items-center text-white text-25">
<view class="bg-main flex-1 p-20 text-center" @click="showGuide = true">报告导航</view>
<view class="bg-orange flex-1 p-20 text-center" @click="download">下载报告</view>
<view class="bg-main flex-1 p-20 text-center" @click="back">重做</view>
</view>
<u-popup :show="showGuide" close-on-click-overlay @close="showGuide = false" round="10"
:closeable="false" mode="bottom"
:safe-area-inset-bottom="false">
<view class="pos-r">
<view class="p-25 border-bottom" @click="jumpTo(0)">风险等级</view>
<view class="p-25 border-bottom" @click="jumpTo(1)">AI分析</view>
<view class="p-25 border-bottom" @click="jumpTo(2)">温馨提示</view>
</view>
</u-popup>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import {listArticleReq} from "@/api/common";
import {
addLegalOrgCheckContentReq,
listLegalOrgCheckTypeInfoReq,
updateLegalOrgCheckContentReq
} from "@/api/legalOrgCheck";
import piaoyiProgressBar
from '@/uni_modules/piaoyi-progress-bar/components/piaoyi-progress-bar/piaoyi-progress-bar.vue';
import {WS_API} from "@/config";
import {getUserInfo} from "@/util/user";
import {sendChatReq} from "@/api/lawOrg";
import {MAIN} from "@/config/color";
export default {
name: "result",
components: {HeaderItem, piaoyiProgressBar},
data() {
return {
title: '',
typeId: null,
content: [],
config: null,
articleList: [],
point: 0,
levelStyle: {
color: 'white',
background: 'linear-gradient(97.98deg, rgba(255,201,35,1) 30.49%,rgba(255,144,10,1) 78.96%)',
border: 0,
width: '300rpx'
},
comment: '',
returnContent: '',
loading: false,
aiDone: false,
id: null,
showGuide: false,
}
},
methods: {
MAIN() {
return MAIN
},
back() {
uni.navigateBack()
},
async getConfig() {
const {data} = await listLegalOrgCheckTypeInfoReq(this.typeId)
this.config = data
if (this.config.scoreConfig) {
JSON.parse(this.config.scoreConfig).map(item => {
if (item.minPoint < this.point && this.point <= item.maxPoint) {
this.comment = item.title
}
})
}
await this.getArticleList()
},
async getArticleList() {
const {data} = await listArticleReq({
categoryId: this.config.articleCateId
})
this.articleList = data
},
downloadFile(file) {
uni.showLoading({title: '加载中'})
uni.downloadFile({
url: file,
success: function (res) {
uni.hideLoading()
uni.openDocument({
showMenu: true,
filePath: res.tempFilePath
})
}
})
},
copy(url) {
uni.setClipboardData({
data: url,
success: function () {
uni.showToast({
title: '复制成功',
icon: 'none'
})
}
})
},
async addLog(title, content, point) {
const {data} = await addLegalOrgCheckContentReq({
title,
content,
point: parseFloat(point)
})
this.id = data
},
jumpTo(id) {
uni.pageScrollTo({
selector: `#tag${id}`,
duration: 300
})
this.showGuide = false
},
download(){
if (!this.aiDone) return this.$toast('请先等待AI回答完毕')
this.$jump(`/legalOrgCheck/pages/pdfResult?id=${this.id}&typeId=${this.typeId}`)
}
},
onLoad({title, typeId, point}) {
this.title = title
this.typeId = typeId
this.point = point
this.getConfig()
const eventChannel = this.getOpenerEventChannel();
this.returnContent = ''
eventChannel.on('content', data => {
this.content = data
this.addLog(title, JSON.stringify(data), point)
let query = `帮我分析${this.title}`
for (let i = 0; i < data.length; i++) {
const item = data[i]
query += `${item.quest}: ${item.answer};`
}
uni.connectSocket({
url: `${WS_API}/${getUserInfo().uid}`,
success: () => {
this.loading = true
this.aiDone = false
sendChatReq({
query,
user: getUserInfo().uid
}).finally(() => {
uni.closeSocket()
})
}
})
const _this = this
uni.onSocketMessage(res => {
if (res.data === '连接成功') return
this.loading = false
const aiData = JSON.parse(res.data)
if (aiData.answer !== '__END__') this.returnContent += aiData.answer
else {
updateLegalOrgCheckContentReq({
id: _this.id,
aiContent: _this.returnContent
}).then(() => {
_this.aiDone = true
})
}
})
})
},
onHide() {
uni.closeSocket()
},
onUnload() {
uni.closeSocket()
},
}
</script>
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

+184
View File
@@ -0,0 +1,184 @@
<template>
<view class="min-height bg-main-light">
<HeaderItem title="常见问题解答"/>
<view class="bg-white p-20 text-25 flex justify-center items-center">
<text class="tag selected-tag">{{ title }}</text>
</view>
<view class="pos-r" v-if="configList && configList.length">
<view class="circle-bottom-bg"></view>
<view class="tips-card-wrap">
<view class="tips-card">
<view class="text-28 font-bold text-center p-30">【{{ typeLabel }}】</view>
<u-line color="#1DBCBC" dashed></u-line>
<view class="text-25 p-20">{{ configList[activeIndex].title }}</view>
<view class="p-20 flex justify-start items-center" @click="selectItem(item, index)"
v-for="(item, index) in JSON.parse(configList[activeIndex].answer)" :key="index">
<template v-if="configList[activeIndex].type === 'single'">
<u-icon
:name="configList[activeIndex].selected.includes(item) ? '/legalOrgCheckSuggest/static/radio-selected.png' : '/legalOrgCheckSuggest/static/radio.png'"/>
<text class="text-25 ml-10">{{ item }}</text>
</template>
<template v-else-if="configList[activeIndex].type === 'multi'">
<u-icon
:name="configList[activeIndex].selected.includes(item) ? '/legalOrgCheckSuggest/static/checkbox-selected.png' : '/legalOrgCheckSuggest/static/checkbox.png'"/>
<text class="text-25 ml-10">{{ item }}</text>
</template>
</view>
<u-gap height="100rpx"/>
</view>
<view class="flex justify-center items-center">
<view class="mx-15">
<u-button shape="circle" @click="toLastItem" v-if="activeIndex > 0"
:customStyle="{background: 'linear-gradient(91.28deg, rgba(14,146,252,1) 27.63%,rgba(29,188,188,1) 80.08%)',
border: 0, width: '200rpx',
color: 'white'}">
查看上一题
</u-button>
</view>
<view class="mx-15">
<u-button shape="circle" @click="toNextItem"
v-if="activeIndex > 0 && configList[activeIndex].type === 'multi'"
:customStyle="{background: 'linear-gradient(91.28deg, rgba(14,146,252,1) 27.63%,rgba(29,188,188,1) 80.08%)',
border: 0, width: '200rpx',
color: 'white'}">
确认
</u-button>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import {listLegalOrgCheckSuggestConfigReq} from "@/api/legalOrgCheckSuggest";
export default {
name: "detail",
components: {HeaderItem},
data() {
return {
id: 0,
title: '',
configList: [],
typeList: [{value: 'single', label: '单选'}, {value: 'multi', label: '多选'}, {value: 'fill', label: '填空'}],
activeIndex: 0,
typeLabel: ''
}
},
methods: {
async getList() {
const {data} = await listLegalOrgCheckSuggestConfigReq({
typeId: this.id
})
this.configList = data
this.typeLabel = this.typeList.find(item => item.value === data[0].type).label
this.configList.map(item => {
item.selected = []
return item
})
},
selectItem(item, index) {
// console.log(index, this.configList[index], this.configList.length - 1)
if (this.configList[this.activeIndex].type === 'single') {
this.configList[this.activeIndex].selected = [item]
if (this.activeIndex === this.configList.length - 1) {
this.toEnd()
} else {
this.activeIndex += 1
this.typeLabel = this.typeList.find(item => item.value === this.configList[this.activeIndex].type).label
}
} else if (this.configList[this.activeIndex].type === 'multi') {
const hasCheckIndex = this.configList[this.activeIndex].selected.findIndex(i => i === item)
console.log(hasCheckIndex)
if (hasCheckIndex > -1) {
this.configList[this.activeIndex].selected.splice(hasCheckIndex, 1)
} else {
this.configList[this.activeIndex].selected.push(item)
}
}
this.$forceUpdate()
},
toNextItem() {
if (!this.configList[this.activeIndex].selected.length) {
return this.$toast('请选择选项')
}
if (this.activeIndex === this.configList.length - 1) {
this.toEnd()
} else {
this.activeIndex += 1
this.typeLabel = this.typeList.find(item => item.value === this.configList[this.activeIndex].type).label
}
},
toLastItem() {
this.activeIndex -= 1
},
toEnd() {
let content = []
this.configList.map(item => {
content.push({
quest: item.title,
answer: item.selected.join('、')
})
})
uni.navigateTo({
url: `/legalOrgCheckSuggest/pages/result?title=${this.title}&typeId=${this.id}`,
success: res => {
res.eventChannel.emit('content', content)
}
})
}
},
onLoad({id, title}) {
this.id = id
this.title = title
this.getList()
}
}
</script>
<style scoped lang="scss">
.tag {
padding: 10rpx 25rpx;
margin-right: 25rpx;
flex-shrink: 0;
}
.selected-tag {
background-color: #FFCA68;
border-radius: 100rpx;
}
.circle-bottom-bg {
background-color: #1DBCBC;
width: 100vw;
height: 200rpx;
position: absolute;
left: 0;
top: 0;
border-radius: 0 0 100vw 100vw;
}
.tips-card-wrap {
position: absolute;
left: 0;
top: 70rpx;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
.tips-card {
width: 80%;
line-height: 30rpx;
border-radius: 50rpx;
background-color: rgba(255, 255, 255, 1);
color: rgba(16, 16, 16, 1);
box-shadow: 0 2px 6px 0 rgba(202, 247, 247, 1);
margin-bottom: 50rpx;
}
}
</style>
+105
View File
@@ -0,0 +1,105 @@
<template>
<view class="min-height bg-main-light">
<HeaderItem title="常见问题解答"/>
<view class="bg-white p-20 text-25 flex justify-start items-center overflow-x">
<text v-for="(item, index) in typeList" :key="index" class="tag"
@click="changeType(index)"
:class="[item.id === activeId ? 'selected-tag' : '']">{{ item.title }}
</text>
</view>
<view class="pos-r">
<view class="circle-bottom-bg"></view>
<view class="tips-card-wrap">
<view class="tips-card">
<view class="text-28 font-bold text-center">{{ activeTitle }}</view>
<view class="text-25 mt-20" style="padding-bottom: 50rpx">
请你根据实际情况对以下问题进行勾选,人工智能小律将根据你勾选的信息提供相关的法律服务,出具针对性的法律意见书。本项咨询将回答有关林地纠纷中常见纠纷的相关问题。
</view>
</view>
<u-button shape="circle" @click="$jump(`/legalOrgCheckSuggest/pages/detail?id=${activeId}&title=${activeTitle}`)"
:customStyle="{background: 'linear-gradient(91.28deg, rgba(14,146,252,1) 27.63%,rgba(29,188,188,1) 80.08%)',
border: 0, width: '200rpx',
color: 'white'}">
开始咨询
</u-button>
</view>
</view>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import {listLegalOrgCheckTypeSuggestReq} from "@/api/legalOrgCheckSuggest";
export default {
name: "index",
components: {HeaderItem},
data() {
return {
typeList: [],
activeId: 0,
activeTitle: 0,
}
},
methods: {
async getTypeList() {
const {data} = await listLegalOrgCheckTypeSuggestReq()
this.typeList = data
this.activeId = data[0].id
this.activeTitle = data[0].title
},
changeType(index){
this.activeId = this.typeList[index].id
this.activeTitle = this.typeList[index].title
}
},
onLoad() {
this.getTypeList()
},
}
</script>
<style scoped lang="scss">
.tag {
padding: 10rpx 25rpx;
margin-right: 25rpx;
flex-shrink: 0;
}
.selected-tag {
background-color: #FFCA68;
border-radius: 100rpx;
}
.circle-bottom-bg {
background-color: #1DBCBC;
width: 100vw;
height: 200rpx;
position: absolute;
left: 0;
top: 0;
border-radius: 0 0 100vw 100vw;
}
.tips-card-wrap {
position: absolute;
left: 0;
top: 70rpx;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
.tips-card {
width: 80%;
line-height: 30rpx;
padding: 30rpx;
border-radius: 50rpx;
background-color: rgba(255, 255, 255, 1);
color: rgba(16, 16, 16, 1);
box-shadow: 0 2px 6px 0 rgba(202, 247, 247, 1);
margin-bottom: 50rpx;
}
}
</style>
+27
View File
@@ -0,0 +1,27 @@
<template>
<web-view :src="`https://sifa-h5.wsdns.cn/#/legalOrgCheckSuggest/pages/result?id=${id}&typeId=${typeId}`"
@message="onMessage" @onPostMessage="onMessage"/>
<!-- <web-view :src="`http://localhost:8080/#/legalOrgCheck/pages/result?id=${id}&typeId=${typeId}`"-->
<!-- @message="onMessage" @onPostMessage="onMessage"/>-->
</template>
<script>
export default {
name: "pdfResult",
data() {
return {
id: null,
typeId: null,
}
},
methods: {
onMessage(e) {
console.log(e)
}
},
onLoad({id, typeId}) {
this.id = id
this.typeId = typeId
},
}
</script>
+239
View File
@@ -0,0 +1,239 @@
<template>
<view class="min-height bg-white p-30">
<HeaderItem :title="title"/>
<view class="text-25">
<view>您好!</view>
<view style="text-indent: 50rpx">
非常感谢你的信任和支持,根据你所填写的相关信息,大体了解了目前你的相关状况,利用人工智能深度学习百万相关判例,综合法律专家、资深律师,为你出具以下法律意见,因各地方性法规、规章乃至政策有所不同,小律出具的意见书仅根据全国性法律法规以及最高法院的典型案例作出,与当地法律实务可能有所出入,仅供你参考!
</view>
<view class="flex flex-col justify-start items-start" v-if="content">
<view class="text-25 my-20" v-for="(item, index) in content" :key="index">
{{ item.quest }}: {{ item.answer }}
</view>
</view>
<view class="text-main text-28 font-bold my-25" id="tag0">一、平台分析&法律依据</view>
<!-- <view style="text-indent: 50rpx">-->
<!-- 根据你填写的信息显示:根据《中华人民共和国农村土地承包法》第三十三条的规定,你不可以与不属于同一集体经济组织的成员互换林地承包经营权。-->
<!-- </view>-->
<!-- <view class="text-main text-28 font-bold my-25">二、林地纠纷的法律依据</view>-->
<!-- <view style="text-indent: 50rpx">-->
<!-- 单位之间发生的林木、林地所有权和使用权争议,由县级以上人民政府依法处理。个人之间、个人与单位之间发生的林木所有权和林地使用权争议,由乡镇人民政府或者县级以上人民政府依法处理。当事人对有关人民政府的处理决定不服的可以自接到处理决定通知之日起三十日内,向人民法院起诉,在林木、林地权属争议解决前,除因森林防火、林业有害生物防治、国家重大基础设施建设等需要外,当事人任何一方不得砍伐有争议的林木或者改变林地现状。若是双方协商解决纠纷或者调解纠纷,可以参考下面的法律依据(仅部分参考):1、《中华人民共和国民法典》第一百八十八条-->
<!-- 向人民法院请求保护民事权利的诉讼时效期间为三年。法律另有规定的,依照其规定。诉讼时效期间自权利人知道或者应当知道权利受到损害以及义务人之日起计算。法律另有规定的,依照其规定。但是,自权利受到损害之日起超过二十年的,人民法院不予保护,有特殊情况的,人民法院可以根据权利人的申请决定延长。-->
<!-- </view>-->
<view v-if="loading" class="p-15 flex justify-center items-center">
<u-loading-icon mode="semicircle" :color="MAIN()"></u-loading-icon>
</view>
<zero-markdown-view v-else :markdown="returnContent"></zero-markdown-view>
<!-- <view class="text-main text-28 font-bold my-25">三、林地纠纷维权途径</view>-->
<!-- <view style="text-indent: 50rpx">{{ config ? config.methods : '' }}</view>-->
<!-- <view class="text-main text-28 font-bold my-25">四、林地纠纷诉讼提示</view>-->
<!-- <view style="text-indent: 50rpx">{{ config ? config.tips : '' }}</view>-->
<view class="text-main text-28 font-bold my-25" id="tag1">二、文书范本</view>
<view class="flex flex-col justify-start items-start">
<template v-if="config && config.fileList">
<view class="rounded border border-main p-10 flex justify-between items-center w-90p mb-20"
v-for="(item, index) in JSON.parse(config.fileList)" :key="index" @click="downloadFile(item.file)">
<u-icon name="/legalOrgCheckSuggest/static/file.png" :label="item.title" label-pos="right"
label-color="#116AEF"/>
<u-icon name="arrow-right" color="#116AEF"/>
</view>
</template>
</view>
<view class="text-main text-28 font-bold my-25" id="tag2">三、相关案例</view>
<view class="flex flex-col justify-start items-start">
<template v-if="articleList.length">
<view class="rounded border border-main p-10 flex justify-start items-start w-90p mb-20"
v-for="(item, index) in articleList" :key="index"
@click="$jump(`/articlePages/pages/info?id=${item.articleId}`)">
<u-icon name="/legalOrgCheckSuggest/static/star.png"/>
<text class="text-main text-25 ml-10">{{ item.title }}</text>
</view>
</template>
</view>
<view class="text-main text-28 font-bold my-25" id="tag3">四、法条链接</view>
<view style="text-indent: 50rpx">
<template v-if="config && config.urls">
<view v-for="(item, index) in JSON.parse(config.urls)" :key="index"
class="text-25 mb-15 flex justify-start items-center"
@click="copy(item.url)">
<text class="mr-15">{{ item.title }}</text>
<u-icon name="/legalOrgCheckSuggest/static/copy.png"/>
</view>
</template>
</view>
<view class="text-main text-28 font-bold my-25">特别声明</view>
<view style="text-indent: 50rpx">
(1)本法律意见书是根据您填写的信息,参考相关判例、法律法规,给出的法律建议分析。若您填写的信息不真实,将会导致给出的法律意见有偏差。
</view>
<view style="text-indent: 50rpx">
(2)司法实践中,重调查重证据,且影响判决的因素很多,因此本法律意见书仅供参考,不能替代判决文书或作关证据。
</view>
</view>
<u-gap height="200rpx"></u-gap>
<view class="footer flex justify-center items-center text-white text-25">
<view class="bg-main flex-1 p-20 text-center" @click="showGuide = true">报告导航</view>
<view class="bg-orange flex-1 p-20 text-center" @click="download">下载报告</view>
<view class="bg-main flex-1 p-20 text-center" @click="back">重做</view>
</view>
<u-popup :show="showGuide" close-on-click-overlay @close="showGuide = false" round="10"
:closeable="false" mode="bottom"
:safe-area-inset-bottom="false">
<view class="pos-r">
<view class="p-25 border-bottom" @click="jumpTo(0)">一、平台分析&法律依据</view>
<view class="p-25 border-bottom" @click="jumpTo(1)">二、文书范本</view>
<view class="p-25 border-bottom" @click="jumpTo(2)">三、相关案例</view>
<view class="p-25" @click="jumpTo(3)">四、法条链接</view>
</view>
</u-popup>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import {
addLegalOrgCheckContentSuggestReq,
listLegalOrgCheckTypeSuggestInfoReq,
updateLegalOrgCheckContentSuggestReq
} from "@/api/legalOrgCheckSuggest";
import {listArticleReq} from "@/api/common";
import {WS_API} from "@/config";
import {getUserInfo} from "@/util/user";
import {sendChatReq, stopChatReq} from "@/api/lawOrg";
import {MAIN} from "@/config/color";
import {addLegalOrgCheckContentReq, updateLegalOrgCheckContentReq} from "@/api/legalOrgCheck";
export default {
name: "result",
components: {HeaderItem},
data() {
return {
title: '',
typeId: null,
content: [],
config: null,
articleList: [],
returnContent: '',
showGuide: false,
loading: false,
taskId: null,
id: null,
}
},
methods: {
MAIN() {
return MAIN
},
back() {
uni.navigateBack()
},
async getConfig() {
const {data} = await listLegalOrgCheckTypeSuggestInfoReq(this.typeId)
this.config = data
await this.getArticleList()
},
async getArticleList() {
if (!this.config.articleCateId) return
const {data} = await listArticleReq({
categoryId: this.config.articleCateId
})
this.articleList = data
},
downloadFile(file) {
uni.showLoading({title: '加载中'})
uni.downloadFile({
url: file,
success: function (res) {
uni.hideLoading()
uni.openDocument({
showMenu: true,
filePath: res.tempFilePath
})
}
})
},
copy(url) {
uni.setClipboardData({
data: url,
success: function () {
uni.showToast({
title: '复制成功',
icon: 'none'
})
}
})
},
jumpTo(id) {
uni.pageScrollTo({
selector: `#tag${id}`,
duration: 300
})
this.showGuide = false
},
async stopAI(){
await stopChatReq({
taskId: this.taskId,
type: 1
})
uni.closeSocket()
},
async addLog(title, content) {
const {data} = await addLegalOrgCheckContentSuggestReq({
title,
content
})
this.id = data
},
download(){
if (!this.aiDone) return this.$toast('请先等待AI回答完毕')
this.$jump(`/legalOrgCheckSuggest/pages/pdfResult?id=${this.id}&typeId=${this.typeId}`)
}
},
onLoad({title, typeId}) {
this.title = title
this.typeId = typeId
this.getConfig()
const eventChannel = this.getOpenerEventChannel();
eventChannel.on('content', data => {
this.content = data
this.addLog(title, JSON.stringify(data))
uni.connectSocket({
url: `${WS_API}/${getUserInfo().uid}`,
success: () => {
this.loading = true
sendChatReq({
query: `我想咨询${title}`,
user: getUserInfo().uid,
type: title,
requestType: 1,
inputs: JSON.stringify(data)
}).finally(() => {
uni.closeSocket()
})
}
})
const _this = this
uni.onSocketMessage(res => {
if (res.data === '连接成功') return
this.loading = false
const aiData = JSON.parse(res.data)
this.taskId = aiData.taskId
if (aiData.answer !== '__END__') this.returnContent += aiData.answer
else {
updateLegalOrgCheckContentSuggestReq({
id: _this.id,
aiContent: _this.returnContent
}).then(() => {
_this.aiDone = true
})
}
})
})
},
onHide() {
this.stopAI()
},
onUnload() {
this.stopAI()
},
}
</script>
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

+38
View File
@@ -0,0 +1,38 @@
import App from './App'
import uView from '@/uni_modules/uview-ui'
Vue.use(uView)
// #ifndef VUE3
import Vue from 'vue'
import './uni.promisify.adaptor'
Vue.config.productionTip = false
Vue.prototype.$toast = (title, back = false) => {
uni.showToast({
icon: 'none',
title
})
if (back) {
setTimeout(() => {
uni.navigateBack()
}, 1500)
}
}
Vue.prototype.$jump = (url) => {
uni.navigateTo({url})
}
App.mpType = 'app'
const app = new Vue({
...App
})
app.$mount()
// #endif
// #ifdef VUE3
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp(App)
return {
app
}
}
// #endif
+77
View File
@@ -0,0 +1,77 @@
{
"name" : "规范涉企行政执法检查",
"appid" : "__UNI__75A9827",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
/* 5+App特有相关 */
"app-plus" : {
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
/* 模块配置 */
"modules" : {},
/* 应用发布信息 */
"distribute" : {
/* android打包配置 */
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
/* ios打包配置 */
"ios" : {},
/* SDK配置 */
"sdkConfigs" : {}
}
},
/* 快应用特有相关 */
"quickapp" : {},
/* 小程序特有相关 */
"mp-weixin" : {
"appid" : "wx25deb2f4b5cd2b81",
"setting" : {
"urlCheck" : false,
"minified" : true,
"es6" : true
},
"usingComponents" : true,
"optimization" : {
"subPackages" : true
}
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "2"
}
+131
View File
@@ -0,0 +1,131 @@
<template>
<view class="min-height bg p-30">
<HeaderItem title="民事商事仲裁"/>
<view class="rounded text-white flex justify-center items-center"
style="background: linear-gradient(91.28deg, rgba(14,146,252,1) 27.63%,rgba(29,188,188,1) 80.08%); height: 160rpx" @click="$jump('/onlineSheetPages/pages/newCivilRequest')">
民事商事仲裁线上申请入口
</view>
<view class="flex justify-around items-center flex-wrap my-25">
<view class="card flex flex-col justify-center items-center" @click="openPopup('condition')"
style="flex: 0 0 40%; border-radius: 20rpx">
<u-icon name="/onlineSheetPages/static/v2_sua83h.png" size="120rpx"/>
<text class="text-25 mt-10">申请条件</text>
</view>
<view class="card flex flex-col justify-center items-center" @click="openPopup('stuff')"
style="flex: 0 0 40%; border-radius: 20rpx">
<u-icon name="/onlineSheetPages/static/v2_sua840.png" size="120rpx"/>
<text class="text-25 mt-10">申请材料</text>
</view>
</view>
<view class="flex justify-around items-center flex-wrap my-25">
<view class="card flex flex-col justify-center items-center" @click="openPopup('flow')"
style="flex: 0 0 40%; border-radius: 20rpx">
<u-icon name="/onlineSheetPages/static/v2_sua84m.png" size="120rpx"/>
<text class="text-25 mt-10">办理流程</text>
</view>
<view class="card flex flex-col justify-center items-center"
@click="$jump(`/articlePages/pages/list?title=政策法规&cateId=73`)"
style="flex: 0 0 40%; border-radius: 20rpx">
<u-icon name="/onlineSheetPages/static/v2_sua84z.png" size="120rpx"/>
<text class="text-25 mt-10">政策法规</text>
</view>
</view>
<view class="flex justify-around items-center flex-wrap my-25">
<view class="card flex flex-col justify-center items-center"
@click="$jump(`/articlePages/pages/list?title=典型案例&cateId=76`)"
style="flex: 0 0 40%; border-radius: 20rpx">
<u-icon name="/onlineSheetPages/static/v2_sue29e.png" size="120rpx"/>
<text class="text-25 mt-10">典型案例</text>
</view>
<view class="card flex flex-col justify-center items-center" @click="openPopup('fee')"
style="flex: 0 0 40%; border-radius: 20rpx">
<u-icon name="/onlineSheetPages/static/v2_suhlrq.png" size="120rpx"/>
<text class="text-25 mt-10">收费标准</text>
</view>
</view>
<u-popup :show="showContent" close-on-click-overlay @close="showContent = false" round="10"
:closeable="false"
:safe-area-inset-bottom="false">
<view class="p-50 pos-r" v-if="showContent">
<view class="pos-a" style="right: 10rpx; top: 10rpx;z-index: 999" @click="showContent = false">
<u-icon name="close-circle" :color="MAIN()" size="40rpx"/>
</view>
<view class="pos-a w-100p" style="left: 0; top: 10rpx">
<view class="text-center text-main">{{ title }}</view>
</view>
<view style="height: 50vh" class="overflow-y mt-25">
<u-parse :content="content"/>
</view>
</view>
</u-popup>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import {listArticleReq} from "@/api/common";
import {MAIN} from "@/config/color";
export default {
name: "legalAid",
components: {HeaderItem},
data() {
return {
articleList: [],
showContent: false,
title: '',
content: '',
}
},
methods: {
MAIN() {
return MAIN
},
async getArticleList() {
const {data} = await listArticleReq({
categoryId: 59
})
console.log(data)
this.articleList = data
},
openPopup(type) {
switch (type) {
case 'condition' : {
this.title = '申请条件'
const article = this.articleList.find(item => item.articleId === 93)
this.content = article.content
}
break;
case 'stuff' : {
this.title = '申请材料'
const article = this.articleList.find(item => item.articleId === 94)
this.content = article.content
}
break;
case 'flow' : {
this.title = '办理流程'
const article = this.articleList.find(item => item.articleId === 95)
this.content = article.content
}
break;
case 'fee' : {
this.title = '收费标准'
const article = this.articleList.find(item => item.articleId === 96)
this.content = article.content
}
break;
}
this.showContent = true
}
},
onLoad() {
this.getArticleList()
},
}
</script>
<style lang="scss" scoped>
.bg {
background: url("https://sifa-api.wsdns.cn/api/file/20250420/bg1.jpg") no-repeat;
background-size: cover;
}
</style>
+132
View File
@@ -0,0 +1,132 @@
<template>
<view class="min-height bg p-30">
<HeaderItem title="司法鉴定"/>
<view class="rounded text-white flex justify-center items-center"
style="background: linear-gradient(91.28deg, rgba(14,146,252,1) 27.63%,rgba(29,188,188,1) 80.08%); height: 160rpx" @click="$jump('/onlineSheetPages/pages/newForensicRequest')">
司法鉴定线上申请入口
</view>
<view class="flex justify-around items-center flex-wrap my-25">
<view class="card flex flex-col justify-center items-center" @click="openPopup('condition')"
style="flex: 0 0 40%; border-radius: 20rpx">
<u-icon name="/onlineSheetPages/static/v2_sua83h.png" size="120rpx"/>
<text class="text-25 mt-10">申请条件</text>
</view>
<view class="card flex flex-col justify-center items-center" @click="openPopup('stuff')"
style="flex: 0 0 40%; border-radius: 20rpx">
<u-icon name="/onlineSheetPages/static/v2_sua840.png" size="120rpx"/>
<text class="text-25 mt-10">申请材料</text>
</view>
</view>
<view class="flex justify-around items-center flex-wrap my-25">
<view class="card flex flex-col justify-center items-center" @click="openPopup('flow')"
style="flex: 0 0 40%; border-radius: 20rpx">
<u-icon name="/onlineSheetPages/static/v2_sua84m.png" size="120rpx"/>
<text class="text-25 mt-10">办理流程</text>
</view>
<view class="card flex flex-col justify-center items-center"
@click="$jump(`/articlePages/pages/list?title=政策法规&cateId=72`)"
style="flex: 0 0 40%; border-radius: 20rpx">
<u-icon name="/onlineSheetPages/static/v2_sua84z.png" size="120rpx"/>
<text class="text-25 mt-10">政策法规</text>
</view>
</view>
<view class="flex justify-around items-center flex-wrap my-25">
<view class="card flex flex-col justify-center items-center"
@click="$jump(`/articlePages/pages/list?title=典型案例&cateId=75`)"
style="flex: 0 0 40%; border-radius: 20rpx">
<u-icon name="/onlineSheetPages/static/v2_sue29e.png" size="120rpx"/>
<text class="text-25 mt-10">典型案例</text>
</view>
<view class="card flex flex-col justify-center items-center" @click="openPopup('fee')"
style="flex: 0 0 40%; border-radius: 20rpx">
<u-icon name="/onlineSheetPages/static/v2_suhlrq.png" size="120rpx"/>
<text class="text-25 mt-10">收费标准</text>
</view>
</view>
<u-popup :show="showContent" close-on-click-overlay @close="showContent = false" round="10"
:closeable="false"
:safe-area-inset-bottom="false">
<view class="p-50 pos-r" v-if="showContent">
<view class="pos-a" style="right: 10rpx; top: 10rpx;z-index: 999" @click="showContent = false">
<u-icon name="close-circle" :color="MAIN()" size="40rpx"/>
</view>
<view class="pos-a w-100p" style="left: 0; top: 10rpx">
<view class="text-center text-main">{{ title }}</view>
</view>
<view style="height: 50vh" class="overflow-y mt-25">
<u-parse :content="content"/>
</view>
</view>
</u-popup>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import {listArticleReq} from "@/api/common";
import {MAIN} from "@/config/color";
export default {
name: "legalAid",
components: {HeaderItem},
data() {
return {
articleList: [],
showContent: false,
title: '',
content: '',
}
},
methods: {
MAIN() {
return MAIN
},
async getArticleList() {
const {data} = await listArticleReq({
categoryId: 58
})
console.log(data)
this.articleList = data
},
openPopup(type) {
switch (type) {
case 'condition' : {
this.title = '申请条件'
const article = this.articleList.find(item => item.articleId === 89)
this.content = article.content
}
break;
case 'stuff' : {
this.title = '申请材料'
const article = this.articleList.find(item => item.articleId === 90)
this.content = article.content
}
break;
case 'flow' : {
this.title = '办理流程'
const article = this.articleList.find(item => item.articleId === 91)
this.content = article.content
}
break;
case 'fee' : {
this.title = '收费标准'
const article = this.articleList.find(item => item.articleId === 92)
this.content = article.content
}
break;
}
this.showContent = true
}
},
onLoad() {
this.getArticleList()
},
}
</script>
<style lang="scss" scoped>
.bg {
background: url("https://sifa-api.wsdns.cn/api/file/20250420/bg1.jpg") no-repeat;
background-size: cover;
}
</style>
+133
View File
@@ -0,0 +1,133 @@
<template>
<view class="min-height bg p-30">
<HeaderItem title="法律援助"/>
<view class="rounded text-white flex justify-center items-center"
@click="$jump('/onlineSheetPages/pages/newRequest')"
style="background: linear-gradient(91.28deg, rgba(14,146,252,1) 27.63%,rgba(29,188,188,1) 80.08%); height: 160rpx">
法律援助线上申请入口
</view>
<view class="flex justify-around items-center flex-wrap my-25">
<view class="card flex flex-col justify-center items-center" @click="openPopup('condition')"
style="flex: 0 0 40%; border-radius: 20rpx">
<u-icon name="/onlineSheetPages/static/v2_sua83h.png" size="120rpx"/>
<text class="text-25 mt-10">申请条件</text>
</view>
<view class="card flex flex-col justify-center items-center" @click="openPopup('stuff')"
style="flex: 0 0 40%; border-radius: 20rpx">
<u-icon name="/onlineSheetPages/static/v2_sua840.png" size="120rpx"/>
<text class="text-25 mt-10">申请材料</text>
</view>
</view>
<view class="flex justify-around items-center flex-wrap my-25">
<view class="card flex flex-col justify-center items-center" @click="openPopup('flow')"
style="flex: 0 0 40%; border-radius: 20rpx">
<u-icon name="/onlineSheetPages/static/v2_sua84m.png" size="120rpx"/>
<text class="text-25 mt-10">办理流程</text>
</view>
<view class="card flex flex-col justify-center items-center"
@click="$jump(`/articlePages/pages/list?title=政策法规&cateId=69`)"
style="flex: 0 0 40%; border-radius: 20rpx">
<u-icon name="/onlineSheetPages/static/v2_sua84z.png" size="120rpx"/>
<text class="text-25 mt-10">政策法规</text>
</view>
</view>
<view class="flex justify-around items-center flex-wrap my-25">
<view class="card flex flex-col justify-center items-center"
@click="$jump(`/articlePages/pages/list?title=典型案例&cateId=70`)"
style="flex: 0 0 40%; border-radius: 20rpx">
<u-icon name="/onlineSheetPages/static/v2_sue29e.png" size="120rpx"/>
<text class="text-25 mt-10">典型案例</text>
</view>
<!-- <view class="card flex flex-col justify-center items-center" @click="openPopup('fee')"-->
<!-- style="flex: 0 0 40%; border-radius: 20rpx">-->
<!-- <u-icon name="/onlineSheetPages/static/v2_suhlrq.png" size="120rpx"/>-->
<!-- <text class="text-25 mt-10">收费标准</text>-->
<!-- </view>-->
</view>
<u-popup :show="showContent" close-on-click-overlay @close="showContent = false" round="10"
:closeable="false"
:safe-area-inset-bottom="false">
<view class="p-50 pos-r" v-if="showContent">
<view class="pos-a" style="right: 10rpx; top: 10rpx;z-index: 999" @click="showContent = false">
<u-icon name="close-circle" :color="MAIN()" size="40rpx"/>
</view>
<view class="pos-a w-100p" style="left: 0; top: 10rpx">
<view class="text-center text-main">{{ title }}</view>
</view>
<view style="height: 50vh" class="overflow-y mt-25">
<u-parse :content="content"/>
</view>
</view>
</u-popup>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import {listArticleReq} from "@/api/common";
import {MAIN} from "@/config/color";
export default {
name: "legalAid",
components: {HeaderItem},
data() {
return {
articleList: [],
showContent: false,
title: '',
content: '',
}
},
methods: {
MAIN() {
return MAIN
},
async getArticleList() {
const {data} = await listArticleReq({
categoryId: 54
})
console.log(data)
this.articleList = data
},
openPopup(type) {
switch (type) {
case 'condition' : {
this.title = '申请条件'
const article = this.articleList.find(item => item.articleId === 80)
this.content = article.content
}
break;
case 'stuff' : {
this.title = '申请材料'
const article = this.articleList.find(item => item.articleId === 81)
this.content = article.content
}
break;
case 'flow' : {
this.title = '办理流程'
const article = this.articleList.find(item => item.articleId === 82)
this.content = article.content
}
break;
case 'fee' : {
this.title = '收费标准'
const article = this.articleList.find(item => item.articleId === 83)
this.content = article.content
}
break;
}
this.showContent = true
}
},
onLoad() {
this.getArticleList()
},
}
</script>
<style lang="scss" scoped>
.bg {
background: url("https://sifa-api.wsdns.cn/api/file/20250420/bg1.jpg") no-repeat;
background-size: cover;
}
</style>
+167
View File
@@ -0,0 +1,167 @@
<template>
<view class="min-height bg-main-light p-30">
<HeaderItem title="民事商事仲裁预约"/>
<TitleItem title="基础信息"/>
<view class="card mt-25 p-30">
<u-form label-width="140rpx">
<u-form-item label="申请人姓名" border-bottom>
<u-input v-model="formData.name" border="none" placeholder="请输入申请人姓名"/>
</u-form-item>
<u-form-item label="性别" border-bottom>
<view class="flex justify-start items-center">
<view class="tag" @click="formData.gender = 0" :class="[formData.gender === 0 ? 'tag-active' : '']">男
</view>
<view class="tag ml-20" @click="formData.gender = 1" :class="[formData.gender === 1 ? 'tag-active' : '']">
女
</view>
</view>
</u-form-item>
<u-form-item label="联系电话" border-bottom>
<u-input v-model="formData.phone" border="none" placeholder="请输入联系电话"/>
</u-form-item>
<u-form-item label="民族" border-bottom>
<u-input v-model="formData.nation" border="none" placeholder="请输入民族"/>
</u-form-item>
<u-form-item label="出生日期" border-bottom @click="showDate = true">
<u-input v-model="formData.birthday" border="none" placeholder="请输入出生日期" readonly>
<u-icon
slot="right"
name="arrow-right"
></u-icon>
</u-input>
</u-form-item>
<u-form-item label="身份证号" border-bottom>
<u-input v-model="formData.idCard" border="none" placeholder="请输入身份证号"/>
</u-form-item>
<u-form-item label="住所地址" border-bottom>
<u-input v-model="formData.liveAddress" border="none" placeholder="请输入住所地址"/>
</u-form-item>
<u-form-item label="户籍地址" border-bottom>
<u-input v-model="formData.householdAddress" border="none" placeholder="请输入户籍地址"/>
</u-form-item>
<u-form-item label="被申请人" border-bottom>
<u-input v-model="formData.beenName" border="none" placeholder="请输入被申请人"/>
</u-form-item>
<u-form-item label="被申请人地址" border-bottom>
<u-input v-model="formData.beenAddress" border="none" placeholder="请输入被申请人地址"/>
</u-form-item>
<u-form-item label="被申请人统一社会信用代码" border-bottom>
<u-input v-model="formData.beenCode" border="none" placeholder="请输入被申请人统一社会信用代码"/>
</u-form-item>
<u-form-item label="被申请人联系方式" border-bottom>
<u-input v-model="formData.beenPhone" border="none" placeholder="请输入被申请人联系方式"/>
</u-form-item>
<u-form-item label="被申请人法定代表人姓名" border-bottom>
<u-input v-model="formData.beenLegalName" border="none" placeholder="请输入被申请人法定代表人姓名"/>
</u-form-item>
<u-form-item label="被申请人法定代表人职位" border-bottom>
<u-input v-model="formData.beenLegalPosition" border="none" placeholder="请输入被申请人法定代表人职位"/>
</u-form-item>
<u-form-item label="仲裁请求" border-bottom>
<u-textarea maxlength="-1" v-model="formData.requestContent" border="none" placeholder="请输入仲裁请求"/>
</u-form-item>
<u-form-item label="事实和理由" border-bottom>
<u-textarea maxlength="-1" v-model="formData.content" border="none" placeholder="请输入事实和理由"/>
</u-form-item>
</u-form>
</view>
<view class="mt-30">
<u-button type="primary" shape="circle" @click="save"
:hairline="false"
:custom-style="{border: 0, background: 'linear-gradient(91.28deg, rgba(14,146,252,1) 27.63%,rgba(29,188,188,1) 80.08%);'}">
提交
</u-button>
</view>
<u-datetime-picker
:show="showDate"
v-model="checkDate"
mode="date"
:min-date="minDate"
@confirm="selectDate"
@cancel="showDate = false"
/>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import TitleItem from "@/components/TitleItem.vue";
import dayjs from "dayjs";
import {lawLegalAidReq, lawLegalArbitrateReq, lawOrgCheckActionReq} from "@/api/lawOrg";
export default {
name: "newRequest",
components: {TitleItem, HeaderItem},
data() {
return {
formData: {
name: '',
gender: 0,
phone: '',
birthday: '',
idCard: '',
liveAddress: '',
householdAddress: '',
content: '',
requestContent: '',
beenName: '',
beenAddress: '',
beenCode: '',
beenPhone: '',
beenLegalName: '',
beenLegalPosition: '',
},
showDate: false,
checkDate: Number(new Date()),
minDate: dayjs().subtract(100, 'year').valueOf()
}
},
methods: {
selectDate({value}) {
this.showDate = false
this.formData.birthday = dayjs(value).format("YYYY-MM-DD")
},
async save() {
if (!this.formData.name) return this.$toast('请输入姓名')
if (!this.formData.phone) return this.$toast('请输入联系方式')
if (!this.formData.idCard) return this.$toast('请输入身份证号')
if (!this.formData.nation) return this.$toast('请输入民族')
if (!this.formData.requestContent) return this.$toast('请输入仲裁请求')
if (!this.formData.content) return this.$toast('请输入事实和理由')
if (!this.formData.beenName) return this.$toast('请输入被申请人')
if (!this.formData.beenAddress) return this.$toast('请输入被申请人地址')
if (!this.formData.beenCode) return this.$toast('请输入被申请人统一社会信用代码')
if (!this.formData.beenPhone) return this.$toast('请输入被申请人联系方式')
if (!this.formData.beenLegalName) return this.$toast('请输入被申请人法定代表人姓名')
if (!this.formData.beenLegalPosition) return this.$toast('请输入被申请人法定代表人职位')
const res = await lawLegalArbitrateReq(this.formData)
if (res) {
this.$toast('提交成功')
setTimeout(() => {
uni.navigateBack()
}, 500)
}
}
}
}
</script>
<style lang="scss" scoped>
.tag {
border: 1px dashed #999;
padding: 10rpx;
border-radius: 15rpx;
color: #999;
font-size: 25rpx;
width: 60rpx;
display: flex;
align-items: center;
justify-content: center;
}
.tag-active {
color: #3c9cff !important;
border-color: #3c9cff !important;
}
</style>
@@ -0,0 +1,392 @@
<template>
<view class="min-height bg-main-light p-30">
<HeaderItem title="司法鉴定预约"/>
<TitleItem title="基础信息"/>
<view class="card mt-25 p-30">
<u-form label-width="160rpx" :label-style="{fontSize: '24rpx'}">
<u-form-item label="司法鉴定机构" border-bottom @click="showOrg = true">
<u-input v-model="orgName" border="none" placeholder="请选择司法鉴定机构" readonly>
<u-icon
slot="right"
name="arrow-right"
></u-icon>
</u-input>
</u-form-item>
<template v-if="formData.orgId">
<u-form-item label="委托人姓名" border-bottom>
<u-input v-model="formData.name" border="none" placeholder="请输入委托人姓名"/>
</u-form-item>
<u-form-item label="性别" border-bottom>
<view class="flex justify-start items-center">
<view class="tag" @click="formData.gender = 0" :class="[formData.gender === 0 ? 'tag-active' : '']">男
</view>
<view class="tag ml-20" @click="formData.gender = 1" :class="[formData.gender === 1 ? 'tag-active' : '']">
女
</view>
</view>
</u-form-item>
<u-form-item label="联系电话" border-bottom>
<u-input v-model="formData.phone" border="none" placeholder="请输入联系电话"/>
</u-form-item>
<u-form-item label="出生日期" border-bottom @click="showDate = true">
<u-input v-model="formData.birthday" border="none" placeholder="请输入出生日期" readonly>
<u-icon
slot="right"
name="arrow-right"
></u-icon>
</u-input>
</u-form-item>
<u-form-item label="身份证号" border-bottom>
<u-input v-model="formData.idCard" border="none" placeholder="请输入身份证号"/>
</u-form-item>
<u-form-item label="住所地址" border-bottom>
<u-input v-model="formData.liveAddress" border="none" placeholder="请输入住所地址"/>
</u-form-item>
<u-form-item label="户籍地址" border-bottom>
<u-input v-model="formData.householdAddress" border="none" placeholder="请输入户籍地址"/>
</u-form-item>
<u-form-item label="基本案情" border-bottom>
<u-textarea maxlength="-1" v-model="formData.detail" border="none"
placeholder="请输入与鉴定又关的基本案情"/>
</u-form-item>
<template v-if="formData.orgId === 25">
<u-form-item label="委托鉴定事项" border-bottom>
<u-textarea maxlength="-1" v-model="formData.content" border="none" placeholder="请输入委托鉴定事项"/>
</u-form-item>
<u-form-item label="是否重新鉴定" border-bottom>
<view class="flex justify-start items-center">
<view class="tag" style="width: 200rpx" @click="formData.isNew = 0"
:class="[formData.isNew === 0 ? 'tag-active' : '']">不属于重新鉴定
</view>
<view class="tag ml-20" style="width: 200rpx" @click="formData.isNew = 1"
:class="[formData.isNew === 1 ? 'tag-active' : '']">
属于重新鉴定
</view>
</view>
</u-form-item>
</template>
<template v-else-if="formData.orgId === 26">
<u-form-item label="委托鉴定事项" border-bottom>
<view class="flex flex-col justify-start items-start">
<view v-for="(item, index) in contentConfigList" :key="index" class="mb-15">
<u-icon @click="changeContent(item)"
:label="item" label-pos="right"
:name="contentList.includes(item) ? '/onlineSheetPages/static/checkbox-selected.png' : '/onlineSheetPages/static/checkbox.png'"/>
</view>
</view>
</u-form-item>
<u-form-item label="鉴定用途" border-bottom>
<view class="flex flex-col justify-start items-start">
<view class="mb-15">
<u-icon label="诉讼" label-pos="right" @click="changeApplication('诉讼')"
:name="applicationList.includes('诉讼') ? '/onlineSheetPages/static/checkbox-selected.png' : '/onlineSheetPages/static/checkbox.png'"/>
</view>
<view class="mb-15">
<u-icon label="仲裁" label-pos="right" @click="changeApplication('仲裁')"
:name="applicationList.includes('仲裁') ? '/onlineSheetPages/static/checkbox-selected.png' : '/onlineSheetPages/static/checkbox.png'"/>
</view>
<view class="mb-15">
<u-icon label="调解" label-pos="right" @click="changeApplication('调解')"
:name="applicationList.includes('调解') ? '/onlineSheetPages/static/checkbox-selected.png' : '/onlineSheetPages/static/checkbox.png'"/>
</view>
<u-icon label="行政执法" label-pos="right" @click="changeApplication('行政执法')"
:name="applicationList.includes('行政执法') ? '/onlineSheetPages/static/checkbox-selected.png' : '/onlineSheetPages/static/checkbox.png'"/>
</view>
</u-form-item>
</template>
</template>
</u-form>
</view>
<template v-if="formData.orgId">
<TitleItem title="鉴定要求/标准"/>
<view class="card mt-25 p-30">
<view class="flex justify-start items-center py-20 border-bottom"
@click="changeStandard(item.title)"
v-for="(item, index) in standardList" :key="index">
<u-icon
:name="standardSelectedList.includes(item.title) ? '/onlineSheetPages/static/checkbox-selected.png' : '/onlineSheetPages/static/checkbox.png'"/>
<text class="text-25 mb-15">{{ item.title }}</text>
</view>
</view>
<TitleItem title="鉴定材料"/>
<view class="card mt-25 p-30">
<view class="flex flex-col justify-start items-start py-20 border-bottom"
v-for="(item, index) in fileList" :key="index">
<text class="text-25 mb-15">{{ item.title }}</text>
<view class="flex flex-col justify-start items-start">
<view class="flex justify-start items-start flex-wrap">
<view class="album-item pos-r" v-for="(file, fileIndex) in item.fileList" :key="fileIndex">
<u-image :src="file" width="190rpx" height="190rpx"/>
<view class="del-wrap" @click="removeFile(index, fileIndex)">
<u-icon name="trash" color="white" size="30rpx"/>
</view>
</view>
</view>
<view>
<u-button size="mini" @click="uploadFile(index)" type="primary" icon="arrow-upward">上传材料</u-button>
</view>
</view>
</view>
</view>
</template>
<view class="mt-30">
<u-button type="primary" shape="circle" @click="save"
:hairline="false"
:custom-style="{border: 0, background: 'linear-gradient(91.28deg, rgba(14,146,252,1) 27.63%,rgba(29,188,188,1) 80.08%);'}">
提交
</u-button>
</view>
<u-datetime-picker
:show="showDate"
v-model="checkDate"
mode="date"
:min-date="minDate"
@confirm="selectDate"
@cancel="showDate = false"
/>
<u-picker :show="showOrg" :columns="[orgList]" @cancel="showOrg = false"
@confirm="selectOrg" key-name="title"
/>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import TitleItem from "@/components/TitleItem.vue";
import dayjs from "dayjs";
import {
lawLegalAidReq,
lawLegalAppraisalReq,
lawLegalArbitrateReq,
lawOrgCheckActionReq,
listLawOrgReq
} from "@/api/lawOrg";
import {chooseImg} from "@/util";
export default {
name: "newRequest",
components: {TitleItem, HeaderItem},
data() {
return {
formData: {
name: '',
gender: 0,
isNew: 0,
phone: '',
birthday: '',
idCard: '',
liveAddress: '',
householdAddress: '',
content: '',
orgId: '',
detail: '',
fileList: '',
standard: '',
},
showDate: false,
showOrg: false,
orgName: '',
checkDate: Number(new Date()),
minDate: dayjs().subtract(100, 'year').valueOf(),
orgList: [],
fileList: [],
standardList: [],
standardSelectedList: [],
contentList: [],
contentConfigList: ['损伤程度鉴定', '致残程度鉴定', '劳动能力鉴定', '护理依赖评定', '听觉功能评定视觉功能评定', '误工、护理、营养时限评定',
'伤病关系鉴定', '后续治疗项目和时限评定', '医疗过错评定医疗损害后果评定', '治疗时限评定医疗费合理性评定', '致伤物和致伤方式推',],
applicationList: [],
}
},
methods: {
setFileData() {
switch (this.formData.orgId) {
case 25 : {
this.fileList = [
{
title: '道路交通事故现场图',
fileList: []
},
{
title: '现场勘查笔录',
fileList: []
},
{
title: '现场照片',
fileList: []
},
{
title: '现场复核照片',
fileList: []
},
{
title: '询问笔录',
fileList: []
},
{
title: '相关视频监控资料',
fileList: []
},
{
title: '行驶证复印件',
fileList: []
},
{
title: '行驶证复印件、机动车信息查询结果单',
fileList: []
},
{
title: '其他材料',
fileList: []
},
]
}
break;
case 26 : {
this.fileList = [
{
title: '交通事故责任认定书复印件',
fileList: []
},
{
title: '身份复印件',
fileList: []
},
{
title: '病历复印件',
fileList: []
},
{
title: '放射片',
fileList: []
},
{
title: '其他材料',
fileList: []
},
]
}
break;
}
},
setStandardList() {
switch (this.formData.orgId) {
case 25 : {
this.standardList = [
{title: '《道路交通事故现场痕迹物证勘验》(GA/T41-2019)'},
{title: '《道路交通事故痕迹鉴定》(GA/T1087-2021)'},
{title: '《道路交通事故车辆安全技术检验鉴定》(GA/T642-2020)'},
{title: '《机动车运行安全技术条件》(GB7258-2017)'},
{title: '《道路交通事故车辆速度鉴定》(GB/T33195-2016)'},
{title: '《基于视频图像的车辆行驶速度技术鉴定》(GA/T1133-2014)'},
{title: '《手印鉴定程序》(GA/T724-2007)'},
]
}
break;
case 26: {
this.standardList = [
{title: '《法医临床检验规范》(SF/T 0111-2021)'},
{title: '《人身损害护理依赖程度评定》GB/T31147-2014'},
{title: '《人身伤害致残程度评定(试行)》'},
{title: '《人体损伤程度鉴定标准》'},
{title: '《道路交通事故受伤人员治疗终结时间》GA/T 1088-2013'},
{title: '《人身损害后续诊疗项目评定指南》(试用)/《法庭科学 人身损害后续诊疗项目评定技术规程》'},
{title: '《人身损害误工期、护理期、营养期评定规范》GA/T1193-2014'},
{title: '《人身保险伤残评定标准及代码》GB/T 44893-2024'},
{title: '《劳动能力鉴定 职工工伤与职业病致残等级》GB/T16180-2014'},
{title: '《人体损伤致残程度分级》'},
{title: '《人身损害与疾病因果关系判定指南》(SF/T0095 2021)'},
]
}
}
},
changeApplication(content) {
const index = this.applicationList.findIndex(i => i === content)
if (index === -1) this.applicationList.push(content)
else this.applicationList.splice(index, 1)
},
changeContent(content) {
const index = this.contentList.findIndex(i => i === content)
if (index === -1) this.contentList.push(content)
else this.contentList.splice(index, 1)
},
changeStandard(content) {
const index = this.standardSelectedList.findIndex(i => i === content)
if (index === -1) this.standardSelectedList.push(content)
else this.standardSelectedList.splice(index, 1)
},
selectDate({value}) {
this.showDate = false
this.formData.birthday = dayjs(value).format("YYYY-MM-DD")
},
selectOrg({value}) {
this.formData.orgId = value[0].id
this.orgName = value[0].title
this.showOrg = false
this.setFileData()
this.setStandardList()
},
async save() {
if (!this.formData.name) return this.$toast('请输入姓名')
if (!this.formData.phone) return this.$toast('请输入联系方式')
if (!this.formData.idCard) return this.$toast('请输入身份证号')
if (!this.formData.orgId) return this.$toast('请选择鉴定机构')
if (this.formData.orgId === 25 && !this.formData.content) return this.$toast('请输入委托鉴定事项')
if (!this.formData.detail) return this.$toast('请输入基本案情')
if (this.standardSelectedList.length) {
this.formData.standard = this.standardSelectedList.join(',')
}
if (this.applicationList.length) {
this.formData.application = this.applicationList.join(',')
}
if (this.formData.orgId === 26){
if (!this.contentList.length) return this.$toast('请选择鉴定事项')
else this.formData.content = this.contentList.join(',')
}
this.formData.fileList = JSON.stringify(this.fileList)
const res = await lawLegalAppraisalReq(this.formData)
if (res) {
this.$toast('提交成功')
setTimeout(() => {
uni.navigateBack()
}, 500)
}
},
async uploadFile(index) {
const res = await chooseImg(9)
this.fileList[index].fileList = [...this.fileList[index].fileList, ...res.map(item => item.path)]
},
removeFile(index, fileIndex) {
this.fileList[index].fileList.splice(fileIndex, 1)
},
async getOrgList() {
const {data} = await listLawOrgReq({
type: '司法鉴定机构'
})
this.orgList = data
}
},
onLoad() {
this.getOrgList()
}
}
</script>
<style lang="scss" scoped>
.tag {
border: 1px dashed #999;
padding: 10rpx;
border-radius: 15rpx;
color: #999;
font-size: 25rpx;
width: 60rpx;
display: flex;
align-items: center;
justify-content: center;
}
.tag-active {
color: #3c9cff !important;
border-color: #3c9cff !important;
}
</style>
+266
View File
@@ -0,0 +1,266 @@
<template>
<view class="min-height bg-main-light p-30">
<HeaderItem title="公证申请"/>
<TitleItem title="人员信息"/>
<view class="card mt-25 p-30" v-for="(item, index) in peopleList" :key="index">
<u-form label-width="140rpx">
<u-form-item label="姓名" border-bottom>
<u-input v-model="peopleList[index].name" border="none" placeholder="请输入姓名"/>
</u-form-item>
<u-form-item label="性别" border-bottom>
<view class="flex justify-start items-center">
<view class="tag" @click="peopleList[index].gender = 0"
:class="[peopleList[index].gender === 0 ? 'tag-active' : '']">男
</view>
<view class="tag ml-20" @click="peopleList[index].gender = 1"
:class="[peopleList[index].gender === 1 ? 'tag-active' : '']">
女
</view>
</view>
</u-form-item>
<u-form-item label="角色" border-bottom>
<u-input v-model="peopleList[index].role" border="none" placeholder="请输入角色(如:申请人)"/>
</u-form-item>
<u-form-item label="联系电话" border-bottom>
<u-input v-model="peopleList[index].phone" border="none" placeholder="请输入联系电话"/>
</u-form-item>
<u-form-item label="民族" border-bottom>
<u-input v-model="peopleList[index].nation" border="none" placeholder="请输入民族"/>
</u-form-item>
<u-form-item label="出生日期" border-bottom @click="openDate(index)">
<u-input v-model="peopleList[index].birthday" border="none" placeholder="请输入出生日期" readonly>
<u-icon
slot="right"
name="arrow-right"
></u-icon>
</u-input>
</u-form-item>
<u-form-item label="地址">
<u-input v-model="peopleList[index].liveAddress" border="none" placeholder="请输入地址"/>
</u-form-item>
<u-button type="error" shape="circle" @click="removePeople(index)" v-if="this.peopleList.length > 1">删除
</u-button>
</u-form>
</view>
<view class="mt-30">
<u-button type="success" shape="circle" @click="addPeople"
:hairline="false"
:custom-style="{border: 0, background: 'linear-gradient(91.28deg, rgba(14,146,252,1) 27.63%,rgba(29,188,188,1) 80.08%);'}">
添加人员
</u-button>
</view>
<TitleItem title="基础信息"/>
<view class="card mt-25 p-30">
<u-form label-width="140rpx">
<u-form-item label="公证类别" required border-bottom @click="showType = true">
<u-input v-model="formData.type" border="none" placeholder="请选择公证类别" readonly>
<u-icon
slot="right"
name="arrow-right"
></u-icon>
</u-input>
</u-form-item>
<u-form-item label="公证事项" required border-bottom>
<u-textarea v-model="formData.content" border="none" placeholder="请输入公证事项" maxlength="-1"/>
</u-form-item>
<u-form-item label="用途" required border-bottom>
<u-input v-model="formData.application" border="none" placeholder="请输入用途"/>
</u-form-item>
<u-form-item label="使用地" required border-bottom>
<u-input v-model="formData.address" border="none" placeholder="请输入使用地"/>
</u-form-item>
<u-form-item label="译文" border-bottom>
<u-input v-model="formData.translate" border="none" placeholder="请输入译文"/>
</u-form-item>
</u-form>
</view>
<TitleItem title="证明材料"/>
<view class="card mt-25 p-30" v-if="selectedConfig && selectedConfig.configList">
<view class="flex flex-col justify-start items-start py-20 border-bottom"
v-for="(item, index) in JSON.parse(selectedConfig.configList)" :key="index">
<text class="text-25 mb-15">{{ item }}</text>
<view class="flex flex-col justify-start items-start">
<!-- <u-tag type="success" plain plain-fill v-for="(file, fileIndex) in fileList[index].fileList"-->
<!-- :key="fileIndex"-->
<!-- :text="`文件:${fileIndex + 1}`" closable @close="removeFile(index, fileIndex)"/>-->
<view class="flex justify-start items-start flex-wrap">
<view class="album-item pos-r" v-for="(file, fileIndex) in fileList[index].fileList" :key="fileIndex">
<u-image :src="file" width="190rpx" height="190rpx"/>
<view class="del-wrap" @click="removeFile(index, fileIndex)">
<u-icon name="trash" color="white" size="30rpx"/>
</view>
</view>
</view>
<view>
<u-button size="mini" @click="uploadFile(index)" type="primary" icon="arrow-upward">上传材料</u-button>
</view>
</view>
</view>
</view>
<view class="mt-30">
<u-button type="primary" shape="circle" @click="save"
:hairline="false"
:custom-style="{border: 0, background: 'linear-gradient(91.28deg, rgba(14,146,252,1) 27.63%,rgba(29,188,188,1) 80.08%);'}">
提交
</u-button>
</view>
<u-datetime-picker
:show="showDate"
v-model="checkDate"
mode="date"
:min-date="minDate"
@confirm="selectDate"
@cancel="showDate = false"
/>
<u-picker :show="showType" :columns="[typeList]" @cancel="showType = false"
@confirm="selectType" key-name="title"
/>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import TitleItem from "@/components/TitleItem.vue";
import dayjs from "dayjs";
import {lawLegalAidReq, lawOrgCheckActionReq} from "@/api/lawOrg";
import {listNotaryConfigReq, notaryActionReq} from "@/api/notary";
import {chooseImg} from "@/util";
export default {
name: "newRequest",
components: {TitleItem, HeaderItem},
data() {
return {
formData: {
nameList: '',
type: '',
content: '',
application: '',
address: '',
translate: '',
fileList: '',
},
showDate: false,
checkDate: Number(new Date()),
minDate: dayjs().subtract(100, 'year').valueOf(),
peopleList: [],
typeList: [],
clickedIndex: 0,
selectedConfig: null,
fileList: [],
showType: false
}
},
methods: {
async getConfigList() {
const {data} = await listNotaryConfigReq()
this.typeList = data
this.selectedConfig = this.typeList[0]
this.formData.type = this.selectedConfig.title
this.fileList = []
JSON.parse(this.selectedConfig.configList).map(item => {
this.fileList.push({
title: item,
fileList: []
})
})
},
selectType({value}) {
this.selectedConfig = value[0]
this.formData.type = this.selectedConfig.title
this.showType = false
this.fileList = []
JSON.parse(this.selectedConfig.configList).map(item => {
this.fileList.push({
title: item,
fileList: []
})
})
},
async uploadFile(index) {
const res = await chooseImg(9)
this.fileList[index].fileList = [...this.fileList[index].fileList, ...res.map(item => item.path)]
},
removeFile(index, fileIndex) {
this.fileList[index].fileList.splice(fileIndex, 1)
},
selectDate({value}) {
this.showDate = false
this.peopleList[this.clickedIndex].birthday = dayjs(value).format("YYYY-MM-DD")
this.checkDate = Number(new Date())
},
openDate(index) {
this.clickedIndex = index
if (this.peopleList[this.clickedIndex].birthday) this.checkDate = dayjs(this.peopleList[this.clickedIndex].birthday).valueOf()
this.showDate = true
},
addPeople() {
this.peopleList.push({
name: '',
gender: 0,
role: '',
phone: '',
nation: '',
birthday: '',
liveAddress: '',
})
},
removePeople(index) {
if (this.peopleList.length === 1) return
this.peopleList.splice(index, 1)
},
async save() {
if (!this.formData.type) return this.$toast('请选择公证类别')
if (!this.formData.content) return this.$toast('请输入公证事项')
if (!this.formData.application) return this.$toast('请输入用途')
if (!this.formData.address) return this.$toast('请输入使用地')
let hasRequired = false
for (let i = 0; i < this.peopleList.length; i++) {
if (!this.peopleList[i].name) return this.$toast('请输入姓名')
if (!this.peopleList[i].role) return this.$toast('请输入角色')
if (!this.peopleList[i].phone) return this.$toast('请输入手机号')
if (!this.peopleList[i].nation) return this.$toast('请输入民族')
if (!this.peopleList[i].birthday) return this.$toast('请选择出生日期')
if (!this.peopleList[i].liveAddress) return this.$toast('请输入居住地')
if (this.peopleList[i].role === '申请人') hasRequired = true
}
if (!hasRequired) return this.$toast('请至少录入申请人')
for (let i = 0; i < this.fileList.length; i++) {
if (!this.fileList[i].fileList.length) return this.$toast(`请上传${this.fileList[i].title}材料`)
}
this.formData.nameList = JSON.stringify(this.peopleList)
this.formData.fileList = JSON.stringify(this.fileList)
const res = await notaryActionReq(this.formData)
if (res) {
this.$toast('提交成功')
setTimeout(() => {
uni.navigateBack()
}, 500)
}
}
},
onLoad() {
this.getConfigList()
this.addPeople()
}
}
</script>
<style lang="scss" scoped>
.tag {
border: 1px dashed #999;
padding: 10rpx;
border-radius: 15rpx;
color: #999;
font-size: 25rpx;
width: 60rpx;
display: flex;
align-items: center;
justify-content: center;
}
.tag-active {
color: #3c9cff !important;
border-color: #3c9cff !important;
}
</style>
+162
View File
@@ -0,0 +1,162 @@
<template>
<view class="min-height bg-main-light p-30">
<HeaderItem title="法律援助预约"/>
<TitleItem title="基础信息"/>
<view class="card mt-25 p-30">
<u-form label-width="180rpx">
<u-form-item label="申请人姓名" border-bottom>
<u-input v-model="formData.name" border="none" placeholder="请输入申请人姓名"/>
</u-form-item>
<u-form-item label="性别" border-bottom>
<view class="flex justify-start items-center">
<view class="tag" @click="formData.gender = 0" :class="[formData.gender === 0 ? 'tag-active' : '']">男
</view>
<view class="tag ml-20" @click="formData.gender = 1" :class="[formData.gender === 1 ? 'tag-active' : '']">
女
</view>
</view>
</u-form-item>
<u-form-item label="民族" border-bottom>
<u-input v-model="formData.nation" border="none" placeholder="请输入民族"/>
</u-form-item>
<u-form-item label="联系电话" border-bottom>
<u-input v-model="formData.phone" border="none" placeholder="请输入联系电话"/>
</u-form-item>
<u-form-item label="出生日期" border-bottom @click="showDate = true">
<u-input v-model="formData.birthday" border="none" placeholder="请输入出生日期" readonly>
<u-icon
slot="right"
name="arrow-right"
></u-icon>
</u-input>
</u-form-item>
<u-form-item label="身份证号" border-bottom>
<u-input v-model="formData.idCard" border="none" placeholder="请输入身份证号"/>
</u-form-item>
<u-form-item label="住所地址" border-bottom>
<u-input v-model="formData.liveAddress" border="none" placeholder="请输入住所地址"/>
</u-form-item>
<u-form-item label="户籍地址" border-bottom>
<u-input v-model="formData.householdAddress" border="none" placeholder="请输入户籍地址"/>
</u-form-item>
<u-form-item label="工作单位" border-bottom>
<u-input v-model="formData.companyName" border="none" placeholder="请输入工作单位"/>
</u-form-item>
<u-form-item label="电子邮箱" border-bottom>
<u-input v-model="formData.email" border="none" placeholder="请输入电子邮箱"/>
</u-form-item>
<u-form-item label="办理事项说明" border-bottom>
<u-textarea maxlength="-1" v-model="formData.content" border="none" placeholder="请输入办理事项说明"/>
</u-form-item>
</u-form>
</view>
<TitleItem title="代理人信息"/>
<view class="card mt-25 p-30">
<u-form label-width="180rpx">
<u-form-item label="姓名" border-bottom>
<u-input v-model="formData.proxyName" border="none" placeholder="请输入代理人姓名"/>
</u-form-item>
<u-form-item label="联系电话" border-bottom>
<u-input v-model="formData.proxyPhone" border="none" placeholder="请输入代理人联系电话"/>
</u-form-item>
<u-form-item label="与申请人关系" border-bottom>
<u-input v-model="formData.proxyRelation" border="none" placeholder="请输入与申请人关系"/>
</u-form-item>
<u-form-item label="身份证号" border-bottom>
<u-input v-model="formData.proxyIdCard" border="none" placeholder="请输入身份证号"/>
</u-form-item>
</u-form>
</view>
<view class="mt-30">
<u-button type="primary" shape="circle" @click="save"
:hairline="false"
:custom-style="{border: 0, background: 'linear-gradient(91.28deg, rgba(14,146,252,1) 27.63%,rgba(29,188,188,1) 80.08%);'}">
提交
</u-button>
</view>
<u-datetime-picker
:show="showDate"
v-model="checkDate"
mode="date"
:min-date="minDate"
@confirm="selectDate"
@cancel="showDate = false"
/>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import TitleItem from "@/components/TitleItem.vue";
import dayjs from "dayjs";
import {lawLegalAidReq, lawOrgCheckActionReq} from "@/api/lawOrg";
export default {
name: "newRequest",
components: {TitleItem, HeaderItem},
data() {
return {
formData: {
name: '',
gender: 0,
phone: '',
birthday: '',
idCard: '',
liveAddress: '',
householdAddress: '',
content: '',
nation: '',
companyName: '',
email: '',
proxyName: '',
proxyPhone: '',
proxyRelation: '',
proxyIdCard: '',
},
showDate: false,
checkDate: Number(new Date()),
minDate: dayjs().subtract(100, 'year').valueOf()
}
},
methods: {
selectDate({value}) {
this.showDate = false
this.formData.birthday = dayjs(value).format("YYYY-MM-DD")
},
async save() {
if (!this.formData.name) return this.$toast('请输入姓名')
if (!this.formData.phone) return this.$toast('请输入联系方式')
if (!this.formData.idCard) return this.$toast('请输入身份证号')
if (!this.formData.content) return this.$toast('请输入办理事项')
if (!this.formData.nation) return this.$toast('请输入民族')
const res = await lawLegalAidReq(this.formData)
if (res) {
this.$toast('提交成功')
setTimeout(() => {
uni.navigateBack()
}, 500)
}
}
}
}
</script>
<style lang="scss" scoped>
.tag {
border: 1px dashed #999;
padding: 10rpx;
border-radius: 15rpx;
color: #999;
font-size: 25rpx;
width: 60rpx;
display: flex;
align-items: center;
justify-content: center;
}
.tag-active {
color: #3c9cff !important;
border-color: #3c9cff !important;
}
</style>
+143
View File
@@ -0,0 +1,143 @@
<template>
<view class="min-height bg p-30">
<HeaderItem title="公证"/>
<view class="rounded text-white flex justify-center items-center"
@click="$jump('/onlineSheetPages/pages/newNotaryRequest')"
style="background: linear-gradient(91.28deg, rgba(14,146,252,1) 27.63%,rgba(29,188,188,1) 80.08%); height: 160rpx">
公证线上申请入口
</view>
<view class="flex justify-around items-center flex-wrap my-25">
<view class="card flex flex-col justify-center items-center" @click="openPopup('condition')"
style="flex: 0 0 40%; border-radius: 20rpx">
<u-icon name="/onlineSheetPages/static/v2_sua83h.png" size="120rpx"/>
<text class="text-25 mt-10">申请条件</text>
</view>
<view class="card flex flex-col justify-center items-center" @click="openPopup('stuff')"
style="flex: 0 0 40%; border-radius: 20rpx">
<u-icon name="/onlineSheetPages/static/v2_sua840.png" size="120rpx"/>
<text class="text-25 mt-10">申请材料</text>
</view>
</view>
<view class="flex justify-around items-center flex-wrap my-25">
<view class="card flex flex-col justify-center items-center" @click="openPopup('flow')"
style="flex: 0 0 40%; border-radius: 20rpx">
<u-icon name="/onlineSheetPages/static/v2_sua84m.png" size="120rpx"/>
<text class="text-25 mt-10">办理流程</text>
</view>
<view class="card flex flex-col justify-center items-center"
@click="$jump(`/articlePages/pages/list?title=政策法规&cateId=71`)"
style="flex: 0 0 40%; border-radius: 20rpx">
<u-icon name="/onlineSheetPages/static/v2_sua84z.png" size="120rpx"/>
<text class="text-25 mt-10">政策法规</text>
</view>
</view>
<view class="flex justify-around items-center flex-wrap my-25">
<view class="card flex flex-col justify-center items-center"
@click="$jump(`/articlePages/pages/list?title=典型案例&cateId=74`)"
style="flex: 0 0 40%; border-radius: 20rpx">
<u-icon name="/onlineSheetPages/static/v2_sue29e.png" size="120rpx"/>
<text class="text-25 mt-10">典型案例</text>
</view>
<view class="card flex flex-col justify-center items-center" @click="openPopup('fee')"
style="flex: 0 0 40%; border-radius: 20rpx">
<u-icon name="/onlineSheetPages/static/v2_suhlrq.png" size="120rpx"/>
<text class="text-25 mt-10">收费标准</text>
</view>
</view>
<view class="flex justify-around items-center flex-wrap my-25">
<view class="card flex flex-col justify-center items-center"
style="flex: 0 0 90%; border-radius: 20rpx" @click="check">
<u-icon name="/onlineSheetPages/static/v2_suhluu.png" size="120rpx"/>
<text class="text-25 mt-10">查验</text>
</view>
</view>
<u-popup :show="showContent" close-on-click-overlay @close="showContent = false" round="10"
:closeable="false"
:safe-area-inset-bottom="false">
<view class="p-50 pos-r" v-if="showContent">
<view class="pos-a" style="right: 10rpx; top: 10rpx;z-index: 999" @click="showContent = false">
<u-icon name="close-circle" :color="MAIN()" size="40rpx"/>
</view>
<view class="pos-a w-100p" style="left: 0; top: 10rpx">
<view class="text-center text-main">{{ title }}</view>
</view>
<view style="height: 50vh" class="overflow-y mt-25">
<u-parse :content="content"/>
</view>
</view>
</u-popup>
</view>
</template>
<script>
import HeaderItem from "@/components/HeaderItem.vue";
import {listArticleReq} from "@/api/common";
import {MAIN} from "@/config/color";
export default {
name: "legalAid",
components: {HeaderItem},
data() {
return {
articleList: [],
showContent: false,
title: '',
content: '',
}
},
methods: {
MAIN() {
return MAIN
},
async getArticleList() {
const {data} = await listArticleReq({
categoryId: 57
})
console.log(data)
this.articleList = data
},
openPopup(type) {
switch (type) {
case 'condition' : {
this.title = '申请条件'
const article = this.articleList.find(item => item.articleId === 85)
this.content = article.content
}
break;
case 'stuff' : {
this.title = '申请材料'
const article = this.articleList.find(item => item.articleId === 86)
this.content = article.content
}
break;
case 'flow' : {
this.title = '办理流程'
const article = this.articleList.find(item => item.articleId === 87)
this.content = article.content
}
break;
case 'fee' : {
this.title = '收费标准'
const article = this.articleList.find(item => item.articleId === 88)
this.content = article.content
}
break;
}
this.showContent = true
},
check(){
this.$toast('正在完善中')
}
},
onLoad() {
this.getArticleList()
},
}
</script>
<style lang="scss" scoped>
.bg {
background: url("https://sifa-api.wsdns.cn/api/file/20250420/bg1.jpg") no-repeat;
background-size: cover;
}
</style>
Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Some files were not shown because too many files have changed in this diff Show More