This commit is contained in:
yanran200730
2022-11-11 08:36:54 +08:00
17 changed files with 2303 additions and 4 deletions

View File

@@ -72,7 +72,6 @@
<script>
import {mapActions, mapState} from 'vuex'
const navbarTitle = wx.getAccountInfoSync().miniProgram.appId == "wx41792b6cbf573dc0" ? "平昌党建" : "数字平昌"
export default {
name: 'AppHome',
appName: "首页",
@@ -103,7 +102,7 @@ export default {
}
},
onReady() {
uni.setNavigationBarTitle({title: navbarTitle})
uni.setNavigationBarTitle({title: '数字平昌'})
},
onLoad() {
this.autoLogin().then(() => {
@@ -240,7 +239,7 @@ export default {
onShareAppMessage() {
return {
title: `欢迎使用${navbarTitle}~`,
title: `欢迎使用数字平昌~`,
path: `/pages/AppHome/AppHome`
}
},

View File

@@ -0,0 +1,353 @@
<template>
<div class="page">
<div class="header-bg">
<div class="header-info">
<div class="wrap" @click="handleLogin()">
<div class="user-img-div">
<img :src="user.avatarUrl" alt="" class="user-img" v-if="user.id && user.avatarUrl"/>
<open-data type="userAvatarUrl" lang="zh_CN" class="user-img" v-else/>
</div>
<div class="user-info">
<div class="option">
<template v-if="!user.id">
<p>登录</p>
<p>点击进行登录</p>
</template>
<template v-else>
<p v-if="isApprove">{{ user.realName }}</p>
<p v-else>{{ user.nickName }}</p>
<p>{{ user.areaName || "" }}</p>
</template>
</div>
<p class="info" v-if="user.id" @click.stop="$linkTo('./userInfo')">个人信息</p>
</div>
</div>
</div>
</div>
<div class="approve">
<img class="icon" src="./authentication-img.png" alt="">
<div class="flex">
<span class="cert" v-if="isApprove" v-text="approveLabel" @click="$linkTo('/mods/AppAuth/AppAuth')"/>
<u-icon v-else name="arrow-right" color="#E7F2FF" size="28"
:label="approveLabel" label-color="#E7F2FF" label-pos="left" @click="approve"/>
</div>
</div>
<!-- <div class="list-wrap">
<div class="card" v-for="(group,index) in listGroup" :key="index">
<div class="item" v-for="(item) in group" hover-class="bg-hover" :key="item.label"
@click="linkTo(item.path, item.type)">
<div class="block">
<img class="icon" :src="item.icon" alt="">
</div>
<span class="desc" v-if="!item.share">{{ item.label }}</span>
<button open-type="share" v-else>
<span>{{ item.label }}</span>
</button>
</div>
</div>
</div> -->
<AiLogin ref="login" @success="getAuth()"/>
</div>
</template>
<script>
import {mapActions, mapState} from "vuex";
export default {
name: "AppMine",
appName: "我的",
customNavigation: true,
computed: {
...mapState(['user', 'token']),
isApprove() {
return this.user?.status == 2;
},
approveLabel() {
return this.user?.status == 2 ? "已认证" :
this.user?.status == 1 ? "审核中" :
this.user?.status == -1 ? "审核驳回" : "前往认证"
},
listGroup() {
return [
[
{
icon: "https://cdn.cunwuyun.cn/wxmp/mine/wodejiating.png",
label: "我的家庭",
path: "./myFamily",
type: 'idNumber'
},
{
icon: "https://cdn.cunwuyun.cn/wxmp/mine/wodejiaxiang.png",
label: "我的家乡",
path: "/mods/AppHometown/AppHometown",
type: 'token'
}
],
[
{
icon: "https://cdn.cunwuyun.cn/wxmp/mine/wodejifen.png",
label: "我的积分",
path: "/mods/AppCreditPoints/AppCreditPoints?type=detail",
type: 'idNumber'
},
{
icon: "https://cdn.cunwuyun.cn/wxmp/mine/chaoshidingdan.png",
label: "超市订单",
path: "/mods/AppOrderList/AppOrderList",
type: 'idNumber'
},
{
icon: "https://cdn.cunwuyun.cn/wxmp/mine/banshijindu.png",
label: "办事进度",
path: "/mods/AppMyPlan/AppMyPlan",
type: 'idNumber'
}
],
]
}
},
methods: {
...mapActions(['getUserInfo']),
approve() {
if (!this.token) {
this.$refs.login.show();
} else if (!this.isApprove) {
if (this.user.status == 0) {
this.$linkTo('/mods/AppAuth/AppAuth');
} else {
this.$linkTo('/mods/AppAuth/authSuccess')
}
}
},
linkTo(url, type) {
if (type) {
if (this.token) {
if (type == 'token') {
this.$linkTo(url)
}
if (type == 'idNumber') {
if (this.user.status == 0) {
if (!this.user.phone) {
this.$linkTo('/pages/phone/bingPhoneNumber?from=auth')
} else {
this.$linkTo('/mods/AppAuth/AppAuth')
}
} else {
this.$linkTo(url)
}
}
} else {
this.$refs.login.show()
}
} else {
this.$linkTo(url)
}
},
handleLogin() {
if (!this.token) {
this.$refs.login.show();
}
},
getAuth() {
this.$nextTick(() => {
this.token && this.getUserInfo()
})
}
},
onShow() {
this.getAuth();
},
onShareAppMessage() {
return {
title: `欢迎使用数字平昌~`,
path: `/pages/AppHome/AppHome`
}
},
}
</script>
<style scoped lang="scss">
@import "~dvcp-wui/common";
.page {
width: 100%;
min-height: 100%;
background-color: #F3F6F9;
position: relative;
.header-bg {
width: 100%;
height: 512px;
position: relative;
.header-info {
width: 100%;
height: 100%;
background: url("https://cdn.cunwuyun.cn/wxmp/sanjianxi/mineBg.png") no-repeat no-repeat;
background-size: 100% 100%;
box-sizing: border-box;
padding: 240px 0 0 48px;
.wrap {
width: 100%;
height: 96px;
display: flex;
align-items: center;
.user-img-div {
display: inline-block;
width: 96px;
height: 96px;
border-radius: 50%;
overflow: hidden;
border: 4px solid #FFFFFF;
flex-shrink: 0;
.user-img {
display: inline-block;
width: 96px;
height: 96px;
border-radius: 58px;
}
}
.user-info {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
margin-left: 26px;
box-sizing: border-box;
padding-right: 32px;
.option {
& > p:first-child {
font-size: 34px;
font-weight: 600;
color: #333333;
line-height: 54px;
}
& > p:last-child {
font-size: 26px;
font-weight: 400;
color: #7088A0;
line-height: 36px;
}
}
.info {
width: 136px;
height: 48px;
border-radius: 8px;
border: 2px solid #7088A0;
font-size: 26px;
font-weight: 400;
color: #7088A0;
display: flex;
align-items: center;
justify-content: center;
}
}
}
}
}
.approve {
position: absolute;
left: 50%;
top: 400px;
transform: translateX(-50%);
width: 686px;
height: 112px;
background: linear-gradient(90deg, #8FB4FF 0%, #4181FF 100%);
border-radius: 16px;
display: flex;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
padding: 0 20px;
.icon {
width: 296px;
height: 52px;
}
.cert {
font-family: PingFangSC-Regular, PingFang SC;
font-size: 28px;
color: #E7F2FF;
margin-right: 4px;
}
}
.list-wrap {
box-sizing: border-box;
padding: 32px;
.card {
width: 100%;
min-height: 100px;
border-radius: 16px;
background-color: #fff;
margin-bottom: 32px;
.item {
height: 100px;
display: flex;
align-items: center;
&:last-child {
.desc {
border-bottom: none !important;
}
}
.block {
width: 80px;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
.icon {
width: 44px;
height: 44px;
}
}
.desc, & > button {
height: 100%;
flex: 1;
font-size: 30px;
font-weight: 400;
color: #666666;
display: flex;
align-items: center;
border-bottom: 1px solid #EEEEEE;
& > span {
width: 100%;
height: 100%;
text-align: left;
display: flex;
align-items: center;
}
&::after {
border: none;
}
}
.no-border {
border-bottom: none;
}
}
&:first-of-type {
margin-bottom: 32px;
}
}
}
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 993 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -0,0 +1,180 @@
<template>
<div class="page">
<div class="credit-points">
<div class="bg-blue"></div>
<div class="header-content">
<div class="title">家庭地址</div>
<div class="address">
<img src="https://cdn.cunwuyun.cn/img/location-blue.svg" alt="">
<p>{{ info.resident.currentAreaName || '' }}{{ info.resident.currentAddress || '' }}</p>
</div>
</div>
<div class="list-content">
<div class="title">家庭成员</div>
<div class="item" v-for="(item, index) in info.family" :key="index">
<img src="https://cdn.cunwuyun.cn/dvcp/myFamily/1.png" alt="" class="banner-top" v-if="item.sex == 1">
<img src="https://cdn.cunwuyun.cn/dvcp/myFamily/2.png" alt="" class="banner-top" v-else>
<div class="user-img">
<img v-if="item.photo" :src="item.photo" alt=""/>
<img v-else src="https://cdn.cunwuyun.cn/dvcp/myFamily/tx.png" alt=""/>
</div>
<div class="user-info">
<p>{{ item.name }}</p>
<div v-if="item.householdName == 1" class="color-5AAD6A">户主</div>
<div v-else>{{ $dict.getLabel('householdRelation', item.householdRelation) }}</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
appName: "我的家庭",
computed: {
...mapState(['user', 'token'])
},
data() {
return {
info: {}
}
},
onLoad() {
this.$dict.load('householdRelation').then(() => {
this.$nextTick(() => {
this.getUser()
})
})
},
methods: {
getUser() {
this.$instance.post(`/app/appresident/detailForWx?id=${this.user.residentId}`).then(res => {
if (res.code === 0) {
this.info = res.data
}
})
}
}
}
</script>
<style scoped lang="scss">
@import "~dvcp-wui/common";
.page {
width: 100%;
background-color: #f3f6f9;
.credit-points {
.bg-blue {
width: 100%;
height: 112px;
background-color: #197DF0;
}
.header-content {
width: 690px;
background: #FFF;
border-radius: 16px;
margin: -80px 0 32px 30px;
padding: 0 30px 80px;
box-sizing: border-box;
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.02);
.address {
font-size: 32px;
color: #666;
overflow: hidden;
img {
width: 34px;
height: 38px;
margin-right: 14px;
vertical-align: middle;
}
p {
line-height: 44px;
width: 580px;
word-break: break-all;
float: right;
}
}
}
.title {
font-size: 32px;
font-weight: 500;
color: #333;
line-height: 120px;
}
.list-content {
width: 690px;
background: #FFF;
border-radius: 16px;
padding: 0 30px 110px;
box-sizing: border-box;
margin-left: 30px;
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.02);
.item {
width: 630px;
height: 192px;
background: #FFF;
box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.08);
border-radius: 16px;
padding-left: 30px;
box-sizing: border-box;
margin-bottom: 32px;
overflow: hidden;
.banner-top {
width: 100%;
height: 72px;
}
.user-img {
width: 104px;
height: 104px;
margin: -16px 34px 0 0;
border-radius: 50%;
float: left;
img {
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.user-info {
margin-top: -16px;
width: calc(100% - 138px);
float: right;
p {
font-size: 32px;
font-weight: 600;
color: #333;
line-height: 44px;
margin-bottom: 8px;
}
div {
font-size: 26px;
font-weight: 400;
color: #666;
line-height: 36px;
}
.color-5AAD6A {
color: #5AAD6A;
}
}
}
}
}
}
</style>

View File

@@ -0,0 +1,222 @@
<template>
<div class="page">
<div class="info-list">
<div class="item-content mar-b8">
<div class="item solid">
<p class="mar-t22">头像</p>
<button class="user-img-div" open-type="chooseAvatar" @chooseavatar="handleWeixinSync">
<img :src="user.avatarUrl" class="user-img">
</button>
</div>
<div class="item">
<p>用户昵称</p>
<div v-if="!editNickName" @click="editNickName=true">
<p class="name" v-text="nickName"/>
</div>
<input v-else type="nickname" class="editNickName" v-model="nickName" @blur="handleWeixinSync">
</div>
</div>
<div class="item-content mar-b8">
<div class="item">
<p>手机号</p>
<div>{{ user.phone || '' }}</div>
</div>
</div>
<div class="item-content" @click="onLogout">
<div class="item">
<p class="login-out">退出登录</p>
</div>
</div>
</div>
</div>
</template>
<script>
import {mapActions, mapState} from 'vuex'
export default {
name: "userInfo",
appName: "个人中心",
computed: {
...mapState(['user', 'token']),
nickName: {
set(v) {
},
get() {
const {nickName} = this.user
return nickName
}
}
},
onLoad() {
this.getUserInfo()
},
data() {
return {
editNickName: false
}
},
methods: {
...mapActions(['getUserInfo', 'autoLogin']),
upLoad(img) {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: `${this.$instance.defaults.baseURL}/admin/file/add`,
filePath: img,
name: 'file',
header: {
'Content-Type': 'multipart/form-data',
Authorization: uni.getStorageSync('token')
},
success: uploadFileRes => {
resolve(uploadFileRes)
},
fail: err => {
reject(err)
}
})
})
},
onLogout() {
uni.showModal({
title: '提示',
content: "是否要退出登录",
success: res => {
if (res.confirm) {
this.$store.commit('logout')
this.$toast('退出成功');
setTimeout(() => {
uni.switchTab({
url: '/pages/AppMine/AppMine'
})
}, 500)
}
}
})
},
handleWeixinSync({detail}) {
const {value: nickName, avatarUrl} = detail
this.autoLogin({nickName, avatarUrl})
}
}
}
</script>
<style scoped lang="scss">
@import "~dvcp-wui/common";
.page {
width: 100%;
background-color: #F5F5F5;
.info-list {
margin: 0 0 16px 0;
.item-content {
padding: 0 32px;
background-color: #fff;
}
.item {
padding: 36px 0;
line-height: 40px;
width: 100%;
box-sizing: content-box;
display: flex;
justify-content: space-between;
p {
color: #333;
font-weight: 400;
}
div {
color: #666;
font-size: 28px;
}
.user-img-div {
width: 104px;
height: 104px;
border-radius: 50%;
overflow: hidden;
}
.user-img {
width: 104px;
height: 104px;
vertical-align: middle;
border-radius: 50%;
}
.right-icon {
width: 40px;
height: 40px;
vertical-align: middle;
}
.mar-t22 {
margin-top: 44px;
}
}
.login-out {
width: 100%;
font-size: 30px;
text-align: center;
}
}
.self-knowledge-show {
position: fixed;
left: 0;
top: 0;
z-index: 100;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.3);
}
.toast-bg {
position: fixed;
z-index: 101;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.toast {
background-color: #fff;
width: 686px;
height: 316px;
font-size: 36px;
}
.toast-msg {
text-align: center;
line-height: 50px;
color: #333;
font-weight: 500;
padding: 84px 0 80px 0;
}
.toast-btn {
display: inline-block;
width: 120px;
text-align: center;
line-height: 50px;
}
.cancel {
margin-left: 394px;
margin-right: 40px;
}
.confirm {
color: #197DF0;
}
.editNickName {
text-align: right;
font-size: 28px;
}
}
</style>

View File

@@ -0,0 +1,171 @@
<template>
<div class="AppPartyAuth">
<div class="top">
<img src="https://cdn.cunwuyun.cn/AppAuth/security.png" alt="">
<span class="toast">请验证你的个人信息</span>
</div>
<div class="form">
<u-input placeholder="请输入姓名" trim placeholder-style="color:#ccc;font-size:17px"
:custom-style="{height:'72px',borderBottom:'1px solid #ddd'}" v-model="name"/>
<u-input placeholder="请输入身份证号码" trim placeholder-style="color:#ccc;font-size:17px"
:custom-style="{height:'72px'}" v-model="idNumber" maxlength="18"/>
</div>
<div class="btn" @click="confirm()">提交</div>
<!-- <div class="promise">以上信息将为你严格保密</div> -->
<div class="bottom-text">
<u-checkbox v-model="isChecked"></u-checkbox>
<span @click="isChecked=!isChecked">阅读并同意</span>
<span class="deal" @click.stop="toAgreement()">用户服务及隐私协议</span>
</div>
</div>
</template>
<script>
import {mapState} from 'vuex';
export default {
name: "AppPartyAuth",
appName: "党员认证",
computed: {
...mapState(['user']),
},
data() {
return {
name: '',
idNumber: '',
isChecked: false,
};
},
onLoad() {
// 0未认证 1认证中 2已认证 3认证失败
let {partyStatusForWX} = this.user
if (partyStatusForWX == 2) {
uni.redirectTo({url: "./partyAuthInfo"})
} else if (partyStatusForWX == 0) {
// 停留此页
} else if(partyStatusForWX == 1) {
uni.redirectTo({url: "./partyAuthSuccess"})
} else if(partyStatusForWX == 3) {
uni.redirectTo({url: "./partyAuthSuccess"})
}
},
methods: {
toAgreement() {
uni.navigateTo({url: "./partyAgreement"})
},
confirm() {
let {name, idNumber} = this
if (!name) {
return this.$u.toast('请填写姓名')
}
if (!idNumber) {
return this.$u.toast('请填写身份证号码')
}
if (!this.$idCardNoUtil.checkIdCardNo(idNumber)) {
return this.$u.toast('请输入正确的身份证号码')
}
if(!this.isChecked) {
return this.$u.toast('请勾选用户服务及隐私协议')
}
this.$instance.post(`/app/appwechatuser/idNumberAttestation`, {
idNumber, name
}).then(res => {
if (res.code == 0) {
if (res.data == 2 || res.data == 0) {
this.$store.dispatch('getUserInfo')
uni.redirectTo({
url: `./partyAuthSuccess?status=${res.data}`, success: () => {
if (res.data == 0) {
uni.setStorageSync("authForm", {idNumber, name})
}
}
})
} else {
uni.redirectTo({url: "./partyAuthSuccess"})
}
} else {
this.$u.toast(res.msg);
setTimeout(() => {
uni.navigateBack();
}, 500)
}
}).catch(err => {
this.$u.toast(err)
})
},
}
};
</script>
<style lang="scss" scope>
@import "~dvcp-wui/common";
.top {
height: 480px;
background: #4181FF;
display: flex;
flex-direction: column;
align-items: center;
padding-top: 48px;
& > img {
width: 160px;
height: 160px;
}
.toast {
margin-top: 32px;
font-size: 44px;
font-weight: 600;
color: #D9E5FF;
line-height: 60px;
}
}
.form {
width: 686px;
background: #FFFFFF;
margin: -132px auto 0;
box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.02);
border-radius: 16px;
box-sizing: border-box;
padding: 0 48px;
.input {
width: 590px;
height: 144px;
border-bottom: 2px solid #DDDDDD;
}
}
.btn {
width: 686px;
height: 88px;
margin: 80px auto 0;
background: #4181FF;
border-radius: 16px;
display: flex;
align-items: center;
justify-content: center;
font-size: 34px;
font-weight: 500;
color: #FFFFFF;
}
.bottom-text {
padding: 0 48px;
text-align: center;
margin-top: 30px;
.deal {
color: #4181ff;
}
}
.promise {
font-size: 28px;
font-weight: 400;
color: #999999;
line-height: 40px;
text-align: center;
margin-top: 48px;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@@ -0,0 +1,286 @@
<template>
<div class="partyAgreement">
<h1>村微数字乡村平台用户服务及隐私协议</h1>
<p>您的信任对我们非常重要我们深知个人信息对您的重要性我们将按法律法规要求采取相应安全保护措施尽力保护您的个人信息安全可控有鉴于此村微数字乡村平台产品和服务提供者或简称我们制定本用户服务及隐私协议下称本协议并提醒您</p>
<p>本协议适用于村微数字乡村平台产品及服务包括村微数字乡村小程序端以及将村微数字乡村平台部分功能/服务作为第三方服务集成在其他第三方智能硬件软件或服务中</p>
<p>在使用村微数字乡村平台产品或服务前请您务必仔细阅读并透彻理解本协议全部内容在确认充分理解并同意后使用相关产品或服务一旦您开始使用村微数字乡村平台产品或服务即表示您已充分理解并同意本协议</p>
<p>如您对本协议内容有任何疑问意见或建议请通过文末的联系方式与我们联系
特别提示</p>
<p>本隐私协议不适用于其他第三方通过前述网页或客户端向您提供的服务例如您通过村微数字乡村平台开放平台下载使用的第三方应用或者依托村微数字乡村平台产品向您提供服务时您向第三方提供的信息不适用本协议</p>
<p>第一部分 定义</p>
<p>村微数字乡村平台服务是指由村微数字乡村平台服务提供者开发运营旨在为基层政府及群众提供简单便利工具的多端平台包括村微数字乡村小程序端及村微数字乡村移动端PC端以及将村微数字乡村平台部分功能/服务作为第三方服务集成在其他第三方软件和/或智能硬件而提供的服务 村微数字乡村平台服务提供者是指研发并提供村微数字乡村平台产品和服务的中卫慧通科技有限公司以下简称我们</p>
<p>
<p>个人信息指以电子或者其他方式记录的能够单独或者与其他信息结合识别特定自然人身份或者反映特定自然人活动情况的各种信息</p>
<p>
<p>个人敏感信息包括身份证件号码手机号码个人生物识别信息银行账号财产信息行踪轨迹交易信息14岁以下儿童的个人信息等</p>
<p>
<p>个人信息删除指在实现日常业务功能所涉及的系统中去除个人信息的行为使其保持不可被检索访问的状态</p>
<p>第二部分 法律声明</p>
<p>权利归属</p>
<p>村微数字乡村平台的Logo村微数字乡村平台等文字图形及其组合以及村微数字乡村平台其他标识徽记村微数字乡村平台服务的名称等为村微数字乡村平台在中国和其他国家的注册商标未经村微数字乡村平台书面授权任何人不得以任何方式展示使用或做其他处理包括但不限于复制传播展示镜像上传下载也不得向他人表明您有权展示使用或做其他处理</p>
<p>
<p>村微数字乡村平台所有的产品服务技术与所有应用程序或其组件/功能以下或简称技术服务的知识产权均归属于村微数字乡村平台所有或归其权利人所有 除非另行声明村微数字乡村平台拥有村微数字乡村平台在网站内发布文档等信息包括但不限于文字图形图片照片音频视频图标色彩版面设计电子文档的所有权利包括但不限于版权商标权专利权商业秘密和其他所有相关权利未经村微数字乡村平台许可任何人不得擅自使用如上内容包括但不限于通过程序或设备监视复制转播展示镜像上传下载村微数字乡村平台网站内的任何内容被授权浏览复制打印和传播属于村微数字乡村平台产品和服务内信息内容的都不得用于商业目的且所有信息内容及其任何部分的使用都必须包括此权利声明</p>
<p>责任限制</p>
<p>村微数字乡村平台用户在村微数字乡村平台小程序端以及开放平台上自行上传提供发布相关信息包括但不限于用户名称公司名称 联系人及联络信息相关图片资讯等该等信息均由用户自行提供村微数字乡村平台用户须对其提供的任何信息依法承担全部责任</p>
<p>村微数字乡村平台转载作品出于传递更多信息之目的并不意味村微数字乡村平台赞同其观点或证实其内容的真实性</p>
<p>村微数字乡村平台在此提示您在使用村微数字乡村平台产品及服务期间应当遵守中华人民共和国的法律不得危害网络安全不得利用村微数字乡村平台产品及服务从事侵犯他人名誉隐私知识产权和其他合法权益的活动尽管有前述提示村微数字乡村平台不对您使用村微数字乡村平台产品及服务的用途和目的承担任何责任</p>
<p>知识产权保护</p>
<p>我们尊重知识产权反对并打击侵犯知识产权的行为任何组织或个人认为村微数字乡村平台提供的产品及服务如转载文章发布的信息村微数字乡村平台开放平台入驻的第三方应用及其发布的信息等可能侵犯其合法权益的可以通过以下形式向村微数字乡村平台提出书面权利通知村微数字乡村平台将在收到知识产权权利人合格通知后依法尽快处理</p>
<p>1. 通过邮寄的方式将通知书及证明材料原件邮寄至</p>
<p>收件人武汉中卫慧通科技有限公司</p>
<p>地址湖北省武汉市武昌区和平大道840号绿地蓝海A座22楼</p>
<p>邮编430070</p>
<p>第三部分隐私协议</p>
<p>本隐私协议部分将帮助您了解以下内容</p>
<p>1. 我们如何收集和使用您的个人信息</p>
<p>2. 我们如何使用Cookie和同类技术</p>
<p>3. 我们如何共享转让公开披露您的个人信息</p>
<p>4. 我们如何保护您的个人信息</p>
<p>5. 我们如何处理未成年人的个人信息</p>
<p>6. 您的个人信息如何在全球范围转移</p>
<p>7. 本隐私协议如何更新</p>
<p>8. 如何联系我们</p>
<p>我们如何收集和使用您的个人信息</p>
<p>() 我们如何收集您的信息</p>
<p>我们会出于本协议所述的以下目的收集和使用您的个人信息</p>
<p>1.帮助您成为村微数字乡村平台用户</p>
<p>注册成为村微数字乡村用户以便我们为您提供服务包括小程序的所有服务功能您需要通过微信授权我们获取您的手机号昵称实名认证性别生日等基本信息如您需实现多方通话功能则您需要您授权我们访问您的手机通讯录如果您仅需使用浏览搜索村微数字乡村基本服务及介绍您不需要注册成为我们的会员及提供上述信息</p>
<p>当您所在组织机构注销村微数字乡村平台时我们将会匿名或删除您在该组织的相关个人信息但你作为村微数字乡村平台用户的信息仍将保留除非您主动注销村微数字乡村平台账号在您主动注销账户之后我们将停止为您提供产品或服务根据适用法律的要求删除您的个人信息或使其匿名化处理</p>
<p>2.向您提供产品或服务</p>
<p>1)您向我们提供的信息</p>
<p>在服务使用过程中您可以对村微数字乡村平台产品及服务的体验问题反馈帮助我们更好地了解您使用我们产品或服务的体验和需求改善我们产品或服务</p>
<p>您可以通过村微数字乡村平台为其他人订购产品或服务您需要提供该实际订购人的前述个人信息向我们提供该实际订购人的前述个人信息之前您需确保您已经取得其授权同意若前述个人不同意我们将不对该个人可能造成的侵权承当相应法律责任</p>
<p>2)我们在您使用服务过程中收集的信息</p>
<p>为向您提供更契合您需求的智能硬件和/或软件页面展示和搜索结果了解产品适配性识别账号异常状态我们会收集关于您使用产品服务以及使用方式的信息并将这些信息进行关联这些信息包括</p>
<p>设备信息我们会根据您在软件安装及使用中授予的具体权限接收并记录您所使用的设备相关信息例如设备型号操作系统版本设备设置唯一设备标识符等软硬件特征信息设备所在位置相关信息例如IP地址GPS/北斗位置信息以及能够提供相关信息的Wi-Fi接入点蓝牙和基站等传感器信息</p>
<p>日志信息当您使用我们的网站或客户端提供的产品或服务时我们会自动收集您对我们服务的详细使用情况作为有关网络日志保存例如您的搜索查询内容IP地址浏览器的类型电信运营商使用的语言访问日期和时间您访问的网页记录通话状态信息等</p>
<p>请注意单独的设备信息日志信息等是无法识别特定自然人身份的信息如果我们将这类非个人信息与其他信息结合用于识别特定自然人身份或者将其与个人信息结合使用则在结合使用期间这类非个人信息将被视为个人信息除取得您授权或法律法规另有规定外我们会将该类个人信息做匿名化去标识化处理</p>
<p>当您与我们联系时我们可能会保存您的通信/通话记录和内容或您留下的联系方式等信息以便与您联系或帮助您解决问题或记录相关问题的处理方案及结果</p>
<p>3)我们在您使用个性推荐服务过程中收集的信息</p>
<p>为向您提供更好更个性化的服务例如在不同的服务端或设备上提供更个性化但体验一致的服务更契合您需求的输入推荐客服接待或信息推送了解产品适配性识别账号异常状态我们会收集您使用服务的相关信息这些信息包括设备信息日志服务使用信息</p>
<p>日志当您使用我们的网页或客户端时我们会自动收集您对我们服务的详细使用情况作为有关网络日志保存例如您的IP地址浏览器的类型电信运营商使用的语言访问日期和时间以及访问时长软硬件特征信息您需求的网页记录及村微数字乡村平台服务Cookies信息</p>
<p>服务使用信息我们会记录您在使用村微数字乡村平台产品及服务时提交或产生的信息创建的好友列表设置信息例如记住密码自动登录通用设置隐私设置消息提示
<p>当您在使用村微数字乡村平台服务执行某些操作时例如向您的分组添加好友我们可能会向您或其他人发送通知</p>
<p>对于您在村微数字乡村平台开放平台开通使用的第三方应用服务我们将在您启动该应用时收集相关信息并按照本隐私权协议进行处理第三方应用服务提供者可能会获取您使用村微数字乡村平台服务的相关个人信息该第三方应用服务对您的个人信息的收集如有则受该第三方隐私权协议约束</p>
<p>4) 第三方向我们提供的信息</p>
<p>村微数字乡村平台将对其他用户进行与您相关的操作时收集关于您的信息亦可能从村微数字乡村平台合作第三方或通过其他合法途径获取的您的个人数据信息</p>
<p>3.为您提供安全保障</p>
<p>为预防发现调查欺诈侵权危害安全非法或违反与我们的协议协议或规则的行为我们可能收集或整合您的用户信息服务使用信息设备信息日志信息以及我们合作伙伴取得您授权或依据法律共享的信息</p>
<p>4.其他用途</p>
<p>我们将基于本协议未载明的其他特定目的收集您的信息时会事先征求您的同意</p>
<p>村微数字乡村平台收集及使用上述信息的目的是为了更好地经营村微数字乡村平台产品和服务包括但不限于向您提供个性化的服务并且会通过包括但不限于通过网站通知电子邮件电话或短信息等方式通知村微数字乡村平台不会查看或者使用您通过村微数字乡村平台存储的任何业务数据</p>
<p>如我们停止运营村微数字乡村平台产品或服务我们将及时停止继续收集您个人信息的活动将停止运营的通知以逐一送达或公告的形式通知您对所持有的个人信息进行删除或匿名化处理</p>
<p>() 我们如何使用您的信息</p>
<p>收集您的信息是为了向您提供服务及提升服务质量为了实现这一目的我们会把您的信息用于下列用途</p>
<p>1. 向您提供您使用的村微数字乡村平台产品或服务并维护改进优化这些服务及服务体验</p>
<p>2. 为预防发现调查欺诈侵权危害安全非法或违反与我们的协议协议或规则的行为保护您其他用户或公众我们的合法权益我们可能使用或整合您的用户信息服务使用信息设备信息日志信息以及我们合作伙伴取得您授权或依据法律共享的信息来综合判断您账户及交易风险进行身份验证检测及防范安全事件并依法采取必要的记录审计分析处置措施</p>
<p>3. 我们可能会将您的信息进行处理或者与来自其他服务的信息结合起来用于为了向您提供更加个性化的服务使用例如向您推荐可能感兴趣的内容包括但不限于向您发出产品和服务信息或通过系统向您展示个性化的第三方推广信息或者在征得您同意的情况下与村微数字乡村平台合作伙伴共享信息以便他们向您发送有关其产品和服务的信息</p>
<p>4. 经您许可的其他用途</p>
<p>我们如何使用 Cookie 和同类技术</p>
<p>为使您获得更轻松的访问体验您使用村微数字乡村平台产品或服务时我们可能会通过采用各种技术收集和存储您访问村微数字乡村平台服务的相关数据在您访问或再次访问村微数字乡村平台服务时,我们能识别您的身份并通过分析数据为您提供更好更多的服务包括使用小型数据文件识别您的身份这么做是为了解您的使用习惯帮您省去重复输入账户信息的步骤或者帮助判断您的账户安全这些数据文件可能是CookieFlash Cookie或您的浏览器或关联应用程序提供的其他本地存储统称Cookie 请您理解我们的某些服务只能通过使用Cookie才可得到实现如果您的浏览器或浏览器附加服务允许您可以修改对Cookie的接受程度或者拒绝村微数字乡村平台的Cookie但拒绝村微数字乡村平台的Cookie在某些情况下您可能无法使用依赖于Cookies的村微数字乡村平台服务的部分功能</p>
<p>网页上常会包含一些电子图像称为单像素 GIF 文件网络 beacon它可以帮助网站计算浏览网页的用户或访问某些Cookie我们会通过网络beacon收集您浏览网页活动信息例如您访问的页面地址您先前访问的援引页面的位址您停留在页面的时间您的浏览环境以及显示设定等</p>
<p>我们如何共享转让公开披露您的信息</p>
<p>() 共享</p>
<p>我们不会与村微数字乡村平台服务提供者以外的公司组织和个人共享您的个人信息但以下情况除外</p>
<p>1. 在获取明确同意的情况下共享获得您的明确同意后我们会与其他方共享您的个人信息</p>
<p>2. 在法定情形下的共享我们可能会根据法律法规规定诉讼争议解决需要或按行政司法机关依法提出的要求对外共享您的个人信息</p>
<p>3. 只有透露您的资料才能提供您所要求的产品和服务如电话会议服务您通过验证码确认的手机号码将传送至基础电信业务运营商以实现通信并作为来电显示号码向其他用户展示
<p>4. 在您被他人投诉侵犯知识产权或其他合法权利时需要向投诉人披露您的必要资料以便进行投诉处理的</p>
<p>5. 为方便你和通讯录好友之间相互找到你在开启通讯录匹配的时候系统会将通讯录中的手机号进行高强度的加密算法处理后将相应的特征码进行匹配并将有匹配关系的用户展示给你村微数字乡村平台不会保留您通讯录中的任何可识别的信息使用到的您通讯录中的手机号码数据会先经过高强度的加密算法进行处理并通过处理后的特征码实现匹配</p>
<p>6. 与授权合作伙伴共享仅为实现本隐私协议中声明的目的我们的某些服务将由我们和授权合作伙伴共同提供我们可能会与合作伙伴共享您的某些个人信息以提供更好的客户服务和用户体验我们仅会出于合法正当必要特定明确的目的共享您的个人信息并且只会共享提供服务所必要的个人信息我们的合作伙伴无权将共享的个人信息用于与产品或服务无关的其他用途</p>
<p>村微数字乡村平台服务含有到其他网站的链接除法律另有规定外村微数字乡村平台对其他网站的隐私保护措施不负任何责任我们可能在任何需要的时候增加商业伙伴或共用品牌的网站但是提供给他们的将仅是综合信息我们将不会公开您的身份</p>
<p>() 转让</p>
<p>我们不会将您的个人信息转让给任何公司组织和个人但以下情况除外</p>
<p>1. 在获取明确同意的情况下转让获得您的明确同意后我们会向其他方转让您的个人信息</p>
<p>2. 村微数字乡村平台服务提供者发生合并收购或破产清算情形或其他涉及合并收购或破产清算情形时如涉及到个人信息转让我们会要求新的持有您个人信息的公司组织继续受本协议的约束否则我们将要求该公司组织和个人重新向您征求授权同意</p>
<p>() 公开披露</p>
<p>我们仅会在以下情况下公开披露您的个人信息</p>
<p>1. 获得您明确同意或基于您的主动选择我们可能会公开披露您的个人信息</p>
<p>2. 如果我们确定您出现违反法律法规或严重违反村微数字乡村平台相关协议规则的情况或为保护村微数字乡村平台用户或公众的人身财产安全免遭侵害我们可能依据法律法规或村微数字乡村平台相关协议规则征得您同意的情况下披露关于您的个人信息包括相关违规行为以及村微数字乡村平台已对您采取的措施</p>
<p>() 共享转让公开披露个人信息时事先征得授权同意的例外</p>
<p>以下情形中共享转让公开披露您的个人信息无需事先征得您的授权同意</p>
<p>1. 与国家安全国防安全有关的</p>
<p>2. 与公共安全公共卫生重大公共利益有关的</p>
<p>3. 与犯罪侦查起诉审判和判决执行等有关的</p>
<p>4. 出于维护您或其他个人的生命财产等重大合法权益但又很难得到本人同意的</p>
<p>5. 您自行向社会公众公开的个人信息</p>
<p>6. 从合法公开披露的信息中收集个人信息的如合法的新闻报道政府信息公开等渠道</p>
<p>根据法律规定共享转让经去标识化处理的个人信息且确保数据接收方无法复原并重新识别个人信息主体的不属于个人信息的对外共享转让及公开披露行为对此类数据的保存及处理将无需另行向您通知并征得您的同意</p>
<p>我们如何保护您的信息</p>
<p>我们会采取各种预防措施来保护您的个人信息以保障您的个人信息免遭丢失盗用和误用以及被擅自取阅披露更改或销毁为确保您个人信息的安全我们有严格的信息安全规定和流程并有专门的信息安全团队在公司内部严格执行上述措施</p>
<p>村微数字乡村平台有行业先进的以数据为核心围绕数据生命周期进行的数据安全管理体系从组织建设制度设计人员管理产品技术等方面多维度提升整个系统的安全性</p>
<p>我们会采取合理可行的措施尽力避免收集无关的个人信息并在限于达成本协议所述目的所需的期限内保留您的个人信息除非需要延长保留期限或在法律的允许期限内</p>
<p>在不幸发生个人信息安全事件后我们将按照法律法规的要求并最迟不迟于30 个自然日内向您告知安全事件的基本情况和可能的影响我们已采取或将要采取的处置措施您可自主防范和降低风险的建议对您的补救措施等事件相关情况我们将以邮件信函电话推送通知等方式告知您难以逐一告知个人信息主体时我们会采取合理有效的方式发布公告同时我们还将按照监管部门要求上报个人信息安全事件的处置情况</p>
<p>互联网环境并非百分之百安全尽管我们有这些安全措施但请注意在互联网上不存在完善的安全措施我们将尽力确保您的信息的安全性</p>
<p>您的个人信息如何在全球范围转移</p>
<p>原则上我们在中华人民共和国境内运营中收集和产生的个人信息存储在中华人民共和国境内就中华人民共和国境外村微数字乡村平台用户使用村微数字乡村平台产品及服务过程中产生的个人信息您同意回传存储在中国境内的服务器上否则您无法使用现有村微数字乡村平台的产品及服务在此类情况下我们会确保您的个人信息得到在中华人民共和国境内足够同等的保护</p>
<p>本协议如何更新</p>
<p>我们的隐私协议可能变更</p>
<p>未经您明确同意我们不会限制您按照本隐私协议所应享有的权利</p>
<p>对于重大变更我们还会提供更为显著的通知包括我们会通过村微数字乡村平台公示的方式进行意见征集公告通知甚至向您提供弹窗提示</p>
<p>本协议所指的重大变更包括但不限于</p>
<p>1. 我们的服务模式发生重大变化如处理用户信息的目的用户信息的使用方式等</p>
<p>2. 我们在控制权组织架构等方面发生重大变化如业务调整破产并购等引起的所有者变更等</p>
<p>3. 用户信息共享转让或公开披露的主要对象发生变化</p>
<p>4. 我们负责处理用户信息安全的责任部门联络方式及投诉渠道发生变化时</p>
<p>5. 用户信息安全影响评估报告表明存在高风险时</p>
<p>如何联系我们</p>
<p>如果您对村微数字乡村平台的隐私保护协议或数据处理有任何疑问意见或建议 可以通过以下地址与我们联系我们邮寄联系方式如下</p>
<p> 收件人武汉中卫慧通科技有限公司</p>
<p> 地址湖北省武汉市武昌区和平大道840号绿地蓝海A座22楼</p>
<p> 邮编430070</p>
<p>一般情况下我们将在收到您相关联系信息后三十天内回复</p>
</div>
</template>
<script>
export default {
name: "partyAgreement",
appName: "用户服务及隐私协议",
data() {
return {
}
},
onShow() {
this.setNavbar()
},
methods: {
setNavbar() {
uni.setNavigationBarTitle({
title: '用户服务及隐私协议'
});
}
}
}
</script>
<style lang="scss" scoped>
.partyAgreement {
padding: 20px 30px 30px 40px;
box-sizing: border-box;
h1 {
font-size: 36px;
font-weight: 600;
margin-bottom: 20px;
}
p {
text-indent: 2em;
font-size: 30px;
}
}
</style>

View File

@@ -0,0 +1,247 @@
<template>
<section class="partyAuthApply">
<div class="card">
<div class="item">
<div class="label required" v-text="`是否户主`"/>
<div class="flex">
<div class="radioBtn" v-for="op in ownerOps" :key="op.dictValue" v-text="op.dictName"
:class="{current:op.dictValue==form.householdName}" @click="form.householdName=op.dictValue"/>
</div>
</div>
<template v-if="form.householdName==0">
<div class="flex item">
<div class="label required" required v-text="`户主身份证号`"/>
<u-input v-model="form.householdIdNumber" input-align="right" maxlength="18"/>
</div>
<div class="flex item">
<div class="label required" required v-text="`与户主关系`"/>
<AiSelect v-model="form.householdRelation" dict="householdRelation"/>
</div>
</template>
</div>
<div class="card">
<view class="item flex spb" v-for="row in baseInfo" :key="row.prop">
<span class="label" :class="{required:row.required}" v-text="row.label"/>
<AiSelect v-if="row.dict" v-model="form[row.prop]" :dict="row.dict" :disabled="row.disabled"/>
<AiDate v-else-if="row.type=='time'" @change="v=>$set(form,row.prop,v)" :value="form[row.prop]"/>
<u-input v-else-if="row.type=='idNumber'" v-model="form[row.prop]" input-align="right" maxlength="18"/>
<u-input v-else-if="row.type=='phone'" v-model="form[row.prop]" input-align="right" maxlength="11"/>
<u-input v-else v-model="form[row.prop]" input-align="right"/>
</view>
</div>
<div class="card">
<view class="item" :class="{spb:!row.topLabel,flex:!row.topLabel}" v-for="row in contract" :key="row.prop">
<span class="label" :class="{required:row.required}" v-text="row.label"/>
<AiAreaPicker v-if="row.type=='area'" @input="v=>$set(form,row.prop,v)" :fullName.sync="form.currentAreaName" :selectRoot="false">
<u-icon name="arrow-right" :label="form.currentAreaName||'请选择'" label-pos="left" color="#ddd"/>
</AiAreaPicker>
<textarea v-else v-model="form[row.prop]" input-align="right" placeholder="请输入" placeholder-style="color:#999"
maxlength="50"/>
</view>
</div>
<div class="card">
<view class="item" :class="{spb:!row.topLabel,flex:!row.topLabel}" v-for="row in household" :key="row.prop">
<span class="label" :class="{required:row.required}" v-text="row.label"/>
<AiAreaPicker v-if="row.prop=='householdAreaId'" all @input="v=>$set(form,row.prop,v)" v-model="form[row.prop]"
:fullName.sync="form.householdAreaName" valueLevel="5" isForm :selectRoot="false"/>
<textarea v-else v-model="form[row.prop]" input-align="right" placeholder="请输入" placeholder-style="color:#999"
maxlength="50"/>
</view>
</div>
<div class="card">
<view class="item flex spb" v-for="row in extra" :key="row.prop">
<span class="label" :class="{required:row.required}" v-text="row.label"/>
<AiSelect v-if="row.dict" v-model="form[row.prop]" :dict="row.dict"/>
<AiDate v-else-if="row.type=='time'" v-model="form[row.prop]"/>
<AiAreaPicker v-else-if="row.type=='area'" all v-model="form[row.prop]"
:fullName.sync="form.birthplaceAreaName">
<u-icon name="arrow-right" :label="form.birthplaceAreaName||'请选择'" label-pos="left" color="#ddd"/>
</AiAreaPicker>
<u-input v-else v-model="form[row.prop]" input-align="right"/>
</view>
</div>
<div class="fixed-bottom">
<u-button type="primary" @click="submit">
<text style="font-size: 16px" v-text="`提交`"/>
</u-button>
</div>
</section>
</template>
<script>
import {mapState} from "vuex";
export default {
name: "partyAuthApply",
appName: "居民档案申请",
computed: {
...mapState(['user'])
},
data() {
let required = true
return {
ownerOps: [],
form: {
householdName: "1",
currentAreaName: "",
householdAreaName: "",
birthplaceAreaName: ""
},
baseInfo: [
{label: "姓名", prop: "name", required},
{label: "身份证号", prop: "idNumber", required, type: "idNumber"},
{label: "性别", prop: "sex", required, dict: "sex", disabled: true},
{label: "出生日期", prop: "birthDate", required, type: "time", disabled: true},
{label: "联系方式", prop: "phone", type: "phone"},
],
contract: [
{label: "现住址", prop: "currentAreaId", type: "area", required},
{label: "详细住址", prop: "currentAddress", type: 'textarea', topLabel: true},
],
household: [
{label: "户籍地址", prop: "householdAreaId", type: "area"},
{label: "详细地址", prop: "householdAddress", type: 'textarea', topLabel: true},
],
extra: [
{label: "籍贯", prop: "birthplaceAreaId", type: "area"},
{label: "民族", prop: "nation", dict: "nation"},
{label: "文化程度", prop: "education", dict: "education"},
{label: "婚姻状况", prop: "maritalStatus", dict: "maritalStatus"},
{label: "政治面貌", prop: "politicsStatus", dict: "politicsStatus"},
{label: "兵役状况", prop: "militaryStatus", dict: "militaryStatus"},
{label: "宗教信仰", prop: "faithType", dict: "faithType"},
{label: "职业", prop: "job", dict: "job"},
]
}
},
onLoad() {
this.$dict.load("yesOrNo", "householdRelation").then(() => {
this.ownerOps = this.$dict.getDict("yesOrNo")
})
this.getResident()
},
watch: {
'form.idNumber'(v) {
let {birthday: birthDate, sex} = this.$idCardNoUtil.getIdCardInfo(v),
age = this.$calcAge(v)
this.form = {...this.form, birthDate, sex, age}
}
},
methods: {
getResident() {
let {residentId: id} = this.user
if (id) {
this.$instance.post("/app/appresident/detailForWx", null, {
params: {id}
}).then(res => {
if (res?.data) {
this.form = res.data.resident
}
})
} else if (uni.getStorageSync("authForm")) {
let info = uni.getStorageSync("authForm"),
{birthday: birthDate, sex} = this.$idCardNoUtil.getIdCardInfo(info.idNumber)
uni.removeStorageSync("authForm")
this.form = {...this.form, ...info, birthDate, sex}
}
},
submit() {
let {baseInfo, contract, household, extra, form: {householdName, householdIdNumber, householdRelation}} = this
if (householdName == 0) {
if (!householdIdNumber) return this.$u.toast("请输入户主身份证号")
else if (!this.$idCardNoUtil.checkIdCardNo(householdIdNumber)) return this.$u.toast("请输入正确的身份证号")
if (!householdRelation) return this.$u.toast("请输入与户主关系")
}
let flag = [baseInfo, contract, household, extra].flat().reverse().some(e => {
if (e.required && !this.form[e.prop]) {
if (!e.dict && (['textarea', 'idNumber'].includes(e.type) || !e.type)) return this.$u.toast("请输入" + e.label) || true
else return this.$u.toast("请选择" + e.label) || true
} else if (e.type == 'idNumber' && !this.$idCardNoUtil.checkIdCardNo(this.form[e.prop])) {
return this.$u.toast("请输入正确的身份证号") || true
}
})
if (!flag) {
this.$instance.post("/app/appresident/addOrUpdate", this.form).then(res => {
if (res?.code == 0) {
this.$u.toast("提交成功!")
setTimeout(() => uni.switchTab({url: "/pages/AppMine/AppMine"}), 1000)
// uni.redirectTo({url: "./authSuccess"})
}
})
}
}
}
}
</script>
<style lang="scss" scoped>
.partyAuthApply {
background: #F3F6F9;
min-height: 100vh;
padding-bottom: 280px;
.card {
background: #fff;
padding-left: 32px;
margin-bottom: 24px;
.label {
font-size: 34px;
font-family: PingFangSC-Medium, PingFang SC;
color: #666;
font-weight: bold;
line-height: 112px;
position: relative;
&.required:before {
content: "*";
color: #FF4466;
position: absolute;
left: 0;
transform: translateX(-100%);
}
}
.item {
width: 100%;
min-height: 128px;
color: #333;
box-shadow: inset 0px -1px 0px 0px #DDDDDD;
padding-right: 32px;
box-sizing: border-box;
justify-content: space-between;
}
}
.radioBtn {
width: 218px;
height: 80px;
background: #FFFFFF;
border-radius: 16px;
border: 1px solid #CCC;
margin-right: 16px;
text-align: center;
line-height: 80px;
margin-bottom: 48px;
&.current {
background: #4181FF;
color: #fff;
border-color: #4181ff;
}
}
.fixed-bottom {
width: 100vw;
height: 120px;
padding: 16px 32px;
box-sizing: border-box;
background: inherit;
}
textarea {
width: 100%;
}
}
</style>

View File

@@ -0,0 +1,155 @@
<template>
<section class="partyAuthInfo">
<div class="headerCard flex card">
<div class="avatar">
<open-data type="userAvatarUrl" lang="zh_CN" class="user-img"/>
</div>
<div class="flex fill">
<div class="fill">
<b v-text="user.realName"/>
<div class="color-999" v-text="sexAge"/>
</div>
<div class="blue" v-if="isOwner">户主</div>
</div>
</div>
<div class="card">
<b class="title" v-text="`基本信息`"/>
<view class="item flex spb" v-for="row in baseInfo" :key="row.prop">
<span class="color-999" v-text="row.label"/>
<div v-if="row.dict" v-text="$dict.getLabel(row.dict,detail[row.prop])||'-'"/>
<div v-else v-text="detail[row.prop]||'-'"/>
</view>
</div>
<div class="card">
<b class="title" v-text="`联络方式`"/>
<view class="item" :class="{spb:!row.topLabel,flex:!row.topLabel}" v-for="row in contract" :key="row.prop">
<span class="color-999" v-text="row.label"/>
<div v-text="detail[row.prop]||'-'"/>
</view>
</div>
<div class="fixed-bottom">
<u-button type="primary" @click="apply">
<text style="font-size: 16px" v-text="`申请修改`"/>
</u-button>
</div>
</section>
</template>
<script>
import {mapState} from "vuex";
export default {
name: "partyAuthInfo",
appName: "我的档案",
data() {
return {
detail: {},
baseInfo: [
{label: "身份证号", prop: "idNumber"},
{label: "籍贯", prop: "birthplaceAreaName"},
{label: "民族", prop: "nation", dict: "nation"},
{label: "文化程度", prop: "education", dict: "education"},
{label: "政治面貌", prop: "politicsStatus", dict: "politicsStatus"},
{label: "兵役状况", prop: "militaryStatus", dict: "militaryStatus"},
{label: "宗教信仰", prop: "faithType", dict: "faithType"},
{label: "职业", prop: "job", dict: "job"},
],
contract: [
{label: "联系方式", prop: "phone"},
{label: "现住址", prop: "currentAreaName"},
{label: "详细住址", prop: "currentAddress", topLabel: true},
{label: "户籍地址", prop: "householdAreaName"},
{label: "详细地址", prop: "householdAddress", topLabel: true},
]
}
},
computed: {
...mapState(['user']),
sexAge() {
let {idNumber, gender} = this.$idCardNoUtil.getIdCardInfo(this.user.idNumber), age = this.$calcAge(idNumber)
return `${this.$dict.getLabel("sex", gender) || ""} ${age ? age + "岁" : ""}`
},
isOwner() {
return this.detail.householdName == 1
}
},
onLoad() {
this.$dict.load("sex", "nation", "education", "politicsStatus", "militaryStatus", "faithType", "job")
this.getResident()
},
methods: {
getResident() {
this.$instance.post("/app/appresident/detailForWx", null, {
params: {id: this.user.residentId}
}).then(res => {
if (res?.data) {
this.detail = res.data.resident
}
})
},
apply() {
uni.navigateTo({url: "./partyAuthApply"})
}
}
}
</script>
<style lang="scss" scoped>
.partyAuthInfo {
background: #F3F6F9;
min-height: 100vh;
padding-bottom: 280px;
.avatar {
display: inline-block;
width: 96px;
height: 96px;
border-radius: 50%;
overflow: hidden;
border: 4px solid #FFFFFF;
flex-shrink: 0;
margin-right: 16px;
}
.card {
background: #fff;
padding-left: 32px;
margin-bottom: 24px;
.title {
width: 100%;
height: 116px;
line-height: 116px;
font-weight: bold;
}
.item {
width: 100%;
min-height: 112px;
color: #333;
box-shadow: inset 0px -1px 0px 0px #DDDDDD;
padding: 32px 32px 32px 0;
box-sizing: border-box;
white-space: normal;
}
}
.headerCard {
height: 160px;
padding-right: 32px;
}
.blue {
color: #4181FF;
}
.fixed-bottom {
width: 100vw;
height: 120px;
padding: 16px 32px;
box-sizing: border-box;
background: inherit;
}
}
</style>

View File

@@ -0,0 +1,195 @@
<template>
<div class="partyAuthSuccess">
<template v-if="isSuccess">
<!-- <image src="https://cdn.cunwuyun.cn/img/authSuccess.png"/> -->
<image src="./img/success.png"/>
<h2 v-text="`认证成功!`"/>
<div class="btn" @click="gotoInfo" v-text="`前往查看`"/>
</template>
<template v-else-if="isFail">
<image src="https://cdn.cunwuyun.cn/img/authFail.png"/>
<h2 v-text="`认证失败!`"/>
<span class="flex">请先填写<div class="blue" v-text="`居民档案`"/> 进行申请</span>
<div class="btn" @click="apply">居民档案申请</div>
<div class="btn plain" @click="backToHome">返回</div>
</template>
<div class="authing" v-else>
<div class="result" v-text="`你发起的申请/修改`"/>
<div class="result" v-text="authingResult"/>
<div class="failReason" v-if="authFail">
<div class="title flex spb">
<b v-text="`审核结果`"/>
<b class="red" v-text="`未通过`"/>
</div>
<b v-text="`原因`"/>
<div v-html="info.resident.auditOpinion"/>
</div>
<div class="fixed-bottom">
<u-button type="primary" @click="$linkTo('./authInfo')">
<text style="font-size: 16px" v-text="`查看填报内容`"/>
</u-button>
</div>
</div>
</div>
</template>
<script>
import {mapState} from "vuex";
export default {
appName: "实名身份认证",
data() {
return {
info: {}
}
},
computed: {
...mapState(['user']),
isSuccess() {
return this.user.partyStatusForWX == 0
},
// isFail() {
// return this.user.partyStatusForWX == 0
// },
authFail() {
return this.user.status == -1
},
authingResult() {
return this.authFail ? "审核未通过" : "正在审核中"
}
},
onLoad() {
if (!this.isSuccess && !this.isFail) this.getAuthResult()
},
methods: {
backToHome() {
uni.navigateBack({})
},
apply() {
uni.redirectTo({url: "./authApply"})
},
gotoInfo() {
uni.redirectTo({url: "./authInfo"})
},
getAuthResult() {
this.$instance.post(`/app/appresident/detailForWx`, null, {
params: {id: this.user.residentId}
}).then(res => {
if (res?.data) {
this.info = res.data
}
})
}
}
}
</script>
<style lang="scss">
@import "~dvcp-wui/common";
.partyAuthSuccess {
height: 100vh;
padding-top: 96px;
box-sizing: border-box;
text-align: center;
background-color: #fff;
overflow: hidden;
image {
width: 240px;
height: 240px;
margin-bottom: 16px;
}
h2 {
margin-bottom: 16px;
color: #333333;
font-size: 40px;
font-weight: 700;
}
span {
font-size: 28px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: bold;
color: #333;
margin-bottom: 40px;
justify-content: center;
.blue {
color: #4181FF;
}
}
.btn {
width: 320px;
height: 88px;
line-height: 88px;
margin: 48px auto 0;
color: #fff;
font-size: 34px;
background: #4181FF;
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.02);
border-radius: 16px;
&.plain {
background: #fff;
color: #4181FF;
border: 2px solid #4181FF;
}
}
.authing {
margin-top: -272px;
padding: 224px 32px 0;
box-sizing: border-box;
height: calc(100vh + 272px);
background-image: url("https://cdn.cunwuyun.cn/shandong10086/authInfoHbg.png");
background-size: 100vw;
background-repeat: no-repeat;
background-color: #f3f6f9;
.result {
font-size: 56px;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: bold;
color: #000;
line-height: 88px;
text-align: left;
}
.failReason {
margin-top: 160px;
background: #FFFFFF;
box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.02);
border-radius: 16px;
padding: 0 32px 34px;
font-size: 32px;
text-align: left;
.title {
height: 112px;
box-shadow: inset 0px -1px 0px 0px #DDDDDD;
}
b {
font-size: inherit;
color: #999;
line-height: 112px;
&.red {
color: #f46;
}
}
}
.fixed-bottom {
position: fixed;
bottom: 16px;
width: 100vw;
height: 120px;
padding: 16px 32px;
box-sizing: border-box;
background-color: inherit;
}
}
}
</style>

View File

@@ -0,0 +1,491 @@
<template>
<div class="page">
<div class="search-wrap">
<div class="search fill" @click="$linkTo('/mods/AppContent/contentManager?moduleId=' + search.moduleId)">
<u-icon name="search" color="#ffffff" size="40"></u-icon>
<span class="desc">请输入需要搜索的内容</span>
</div>
</div>
<div class="header-bg"></div>
<img class="border" :src="`${cdn}/border.png`" alt="">
<div class="swiper-content">
<u-swiper :list="swiperList" mode="none" height="240" bg-color="none" @click="handleBannerClick"/>
</div>
<div class="grid-content">
<u-grid :col="4" hover-class="text-hover" :border="false">
<u-grid-item v-for="(item, index) in grids" :key="index" :custom-style="{padding:'8px 0'}" bg-color="none"
class="grid-item" @click="handleClick(item)">
<img :src="item.pictureUrl" alt=""/>
<div class="grid-text">{{ item.name }}</div>
</u-grid-item>
</u-grid>
</div>
<div class="notice">
<img :src="`${cdn}/notice-new.png`" alt="">
<u-notice-bar mode="vertical" color="#4181FF" style="flex: 1;" :volume-icon="false" :is-circular="false"
duration="5000" speed="5000" :list="noticeList" @click="clickNotice"/>
</div>
<template v-if="activeList.length>0">
<header>推荐专题</header>
<scroll-view :scroll-x="true" style="width: 100%" class="scroll-wrap">
<div class="scroll-card"
:style="{background:'url(' + item.pictureUrl + ') no-repeat no-repeat;background-size:100% 100%;'}"
v-for="(item,index) in activeList" :key="index" @click="handleActive(item)"/>
</scroll-view>
</template>
<template v-if="categorys&&categorys.length>0">
<u-tabs :list="categorys.map(e=>({name:e.categoryName}))" font-size="40" bg-color="transparent"
inactive-color="#999999" :active-item-style="active"
:is-scroll="true" :current="index" @change="tabChange"/>
<div class="list-wrap" v-if="categoryList && categoryList.length>0">
<div class="list-card" v-for="(category,index) in categoryList" :key="index"
@click="$linkTo('/mods/AppContent/contentDetail?id='+category.id)">
<div class="header">{{ category.title }}</div>
<div class="content-wrap"
v-if="category.contentType==0 && category.files && category.files.length<3&&category.files.length>0">
<img class="img" :src="item.url" v-for="(item,index) in category.files.slice(0,1)" :key="index.id">
</div>
<div class="content-wrap" v-if="category.contentType==0 && category.files && category.files.length >= 3">
<img class="min-img" :src="item.url" v-for="(item,index) in category.files.slice(0,3)" :key="index.id">
</div>
<div class="content-wrap" v-if="category.contentType == 1">
<img class="img" :src="category.pictureUrl" alt=""/>
<img class="play-icon" :src="`${cdn}/play.png`" alt=""/>
</div>
<div class="bottom">
<div class="left">
<div class="tag">{{ category.categoryName }}</div>
{{ category.createTime }}
</div>
<div class="right">
<em>{{ category.viewCount }}</em>
人看过
</div>
</div>
</div>
</div>
<AiEmpty v-else/>
</template>
<AiLogin ref="login"/>
</div>
</template>
<script>
import {mapActions, mapState} from 'vuex'
export default {
name: 'AppPartyHome',
appName: "党建首页",
data() {
return {
cdn: "https://cdn.cunwuyun.cn/wxmp",
swiperList: [],
index: 0,
grids: [],
activeList: [],
notices: [],
categorys: [],
categoryList: [],
search: {areaId: ''},
}
},
computed: {
...mapState(['user', 'token']),
active() {
return {
fontSize: '22px',
color: '#333333',
}
},
noticeList() {
let {notices} = this
return notices?.length > 0 ? notices?.map(e => e.title) || ['暂无公告'] : ['暂无公告']
}
},
onReady() {
uni.setNavigationBarTitle({title: '平昌党建'})
},
onLoad() {
this.autoLogin().then(() => {
this.getSwiperList();
this.getName();
this.getGrids();
this.getActive();
this.getNotice();
})
},
methods: {
...mapActions(['autoLogin', 'authCheck']),
getName() {
this.$instance.post("/app/appcontentmoduleinfo/listByName", null, {
params: {names: "新闻发布"},
withoutToken: true
}).then(res => {
if (res?.data[0]?.categoryList?.length) {
this.categorys = res.data[0]["categoryList"];
this.search.moduleId = res.data[0]['id']
this.search.categoryId = res.data[0]['categoryList'][0]['id']
this.getCategoryList()
}
})
},
tabChange(idx) {
this.index = idx
this.search.categoryId = this.categorys[idx]['id']
this.getCategoryList()
},
getCategoryList() {
this.$instance.post("/app/appcontentinfo/list", null, {
params: {...this.search, size: 100}
}).then(res => {
if (res?.data) {
this.categoryList = res.data.records;
}
})
},
clickNotice(val) {
const id = this.notices[val]["id"];
if (id) {
uni.navigateTo({
url: "/mods/AppNotice/AppNotice?id=" + id
})
}
},
handleActive({type, appId, url}) {
if (type == 0) {
uni.navigateToMiniProgram({appId})
} else if (type == 1) {
this.$linkTo("/subPages/h5/webview?link=" + url);
}
},
getNotice() {
this.$instance.post("/app/appmininotice/list", null, {
params: {size: 999},
withoutToken: true
}).then(res => {
if (res?.data) {
this.notices = res.data.records;
}
})
},
getActive() {
this.$instance.post("/app/appminitopicconfig/list", null, {
params: {size: 999},
withoutToken: true
}).then(res => {
if (res?.data) {
this.activeList = res.data.records;
}
})
},
/**
* 获取顶部九宫格
*/
getGrids() {
this.$instance.post("/app/appminihomeconfig/list", null, {
params: {picked: 1},
withoutToken: true
}).then(res => {
if (res?.data) {
this.grids = res.data.records;
}
})
},
getSwiperList() {
this.$instance.post('/app/appbanner/listForWx', null, {
withoutToken: true
}).then((res) => {
if (res?.data) {
this.swiperList = res.data?.map((e) => ({...e, image: e.imgUrl})) || []
}
})
},
handleClick({type, appId, modulePath, url, checkType, corpId}) {
//先判读是不是系统应用
if (type != "0") {
if (type == "1") {
uni.navigateToMiniProgram({appId});
} else if (type == "2") {
uni.navigateTo({url: "/subPages/h5/webview?link=" + url});
} else if (type == "3") {
this.$linkTo(url);
} else if (type == "4") {
uni.openCustomerServiceChat({
extInfo: {url: url},
corpId: corpId,
fail: () => {
this.$u.toast('请使用普通微信打开小程序进行咨询');
}
});
}
} else if (type && type == "0") {
uni.showLoading({title: '正在进入应用...'})
this.authCheck({checkType, modulePath}).finally(() => uni.hideLoading())
}
},
handleBannerClick(index) {
if (!this.swiperList[index].linkUrl) return
if (this.swiperList[index].type == '0') { //0 h5链接 1 小程序链接; 2外部小程序
this.$linkTo(`/subPages/h5/webview?link=${this.swiperList?.[index]?.linkUrl}&title=${this.swiperList?.[index]?.title}`)
} else if (this.swiperList[index].type == '1') {
this.$linkTo(`${this.swiperList?.[index]?.linkUrl}`)
} else {
wx.navigateToMiniProgram({
appId: this.swiperList[index].linkUrl
})
}
},
},
onShareAppMessage() {
return {
title: `欢迎使用平昌党建~`,
path: `/pages/AppHome/AppHome`
}
},
}
</script>
<style scoped lang="scss">
@import "~dvcp-wui/common";
.page {
width: 100%;
min-height: 100%;
background-color: #F3F6F9;
position: relative;
.search-wrap {
width: 750px;
height: 112px;
box-sizing: border-box;
padding: 0 32px;
display: flex;
align-items: center;
justify-content: center;
background-color: #4181FF;
.search {
width: 100%;
height: 64px;
background: #000000;
border-radius: 32px;
opacity: 0.2;
box-sizing: border-box;
padding: 0 32px;
display: flex;
align-items: center;
.desc {
font-size: 28px;
color: #FFFFFF;
margin-left: 16px;
}
}
}
.area-content {
height: 96px;
line-height: 96px;
background-color: #2d80fb;
.area-ai {
display: block;
width: 200px;
margin-left: 34px;
text-align: left;
}
.picker-location {
text-align: left;
}
}
.header-bg {
width: 100%;
height: 160px;
background-color: #4181FF;
}
.border {
width: 100%;
height: 40px;
}
.swiper-content {
width: 686px;
height: 240px;
margin: -176px auto 24px;
}
.grid-content {
box-sizing: border-box;
.grid-item {
img {
width: 108px;
height: 108px;
object-fit: fill;
}
.grid-text {
font-size: 26px;
font-weight: 400;
color: #333333;
line-height: 36px;
}
}
}
::v-deep .notice {
width: 686px;
height: 88px;
box-sizing: border-box;
padding: 0 24px;
margin: 30px auto 48px;
background: #FFFFFF;
box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.02);
border-radius: 16px;
display: flex;
align-items: center;
justify-content: center;
& > img {
width: 128px;
height: 52px;
}
.u-news-item {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
}
.list-wrap {
box-sizing: border-box;
padding: 32px;
.list-card {
width: 100%;
min-height: 100px;
background: #FFFFFF;
box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.02);
border-radius: 16px;
box-sizing: border-box;
padding: 32px;
margin-bottom: 24px;
.header {
font-size: 36px;
font-weight: 600;
color: #333333;
line-height: 50px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
.content-wrap {
display: flex;
gap: 4px;
flex-wrap: wrap;
margin-top: 24px;
position: relative;
.img {
width: 100%;
height: 350px;
}
.min-img {
width: 204px;
height: 204px;
}
.play-icon {
width: 80px;
height: 80px;
border-radius: 50%;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
}
.bottom {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 24px;
.left {
display: flex;
align-items: center;
font-size: 28px;
font-weight: 400;
color: #999999;
.tag {
width: 144px;
height: 48px;
background: #EEEEEE;
border-radius: 24px;
display: flex;
align-items: center;
justify-content: center;
font-size: 28px;
font-weight: 400;
color: #999999;
margin-right: 16px;
}
}
.right {
font-size: 28px;
font-weight: 400;
color: #999999;
display: flex;
align-items: center;
em {
font-style: normal;
color: #4181FF;
}
}
}
}
}
header {
font-size: 44px;
font-weight: 600;
color: #333333;
padding: 0 32px;
margin-bottom: 32px;
}
.scroll-wrap {
box-sizing: border-box;
padding: 0 32px;
width: 100%;
white-space: nowrap;
margin-bottom: 24px;
.scroll-card {
display: inline-block;
width: 440px;
height: 240px;
box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.02);
border-radius: 16px;
margin-right: 32px;
&:last-child {
margin-right: 0;
}
}
}
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 965 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1000 B

View File

@@ -158,7 +158,7 @@ export default {
},
onShareAppMessage() {
return {
title: '欢迎使用数字乡村治理服务一体化平台~',
title: '欢迎使用数字平昌~',
path: `/pages/AppModules/AppModules`
}
},