Browse Source

完成东明县的物料二维码、民主选举等部分的相关逻辑与接口绑定。

feature
duanliangtao 10 months ago
parent
commit
46b45ccac4
  1. 26
      src/api/democratic.js
  2. 10
      src/api/good.js
  3. BIN
      src/assets/images/houseQR/10.png
  4. BIN
      src/assets/images/houseQR/11.png
  5. BIN
      src/assets/images/houseQR/9.png
  6. 15
      src/router/router.config.js
  7. 4
      src/views/activity/index.vue
  8. 349
      src/views/democratic/detail.vue
  9. 231
      src/views/democratic/index.vue
  10. 117
      src/views/goodsQR/index.less
  11. 187
      src/views/goodsQR/index.vue
  12. 10
      src/views/home2/index.vue

26
src/api/democratic.js

@ -0,0 +1,26 @@
// axios
import request from '@/utils/request'
//扫描二维码获取房屋信息
export function communityDemocry(data) {
return request({
url: `/governance/democracyelection/resi/list`,
method: 'post',
data
})
}
export function getDemocryDetail(data) {
return request({
url: `/governance/democracyelection/resi/info?electionId=${data.electionId}&resiId=${data.resiId}`,
method: 'get'
})
}
export function democraticVote(data) {
return request({
url: `/governance/democracyelection/resi/vote`,
method: 'post',
data
})
}

10
src/api/good.js

@ -0,0 +1,10 @@
// axios
import request from '@/utils/request'
//扫描二维码获取房屋信息
export function getGoodInfoQR(id) {
return request({
url: `/actual/base/materialcode/hfive/info/${id}`,
method: 'get',
})
}

BIN
src/assets/images/houseQR/10.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
src/assets/images/houseQR/11.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
src/assets/images/houseQR/9.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

15
src/router/router.config.js

@ -240,6 +240,21 @@ export const constantRouterMap = [
name: 'communityPublicity',
component: () => import('@/views/communityPublicity'),
meta: { title: '一次办结清单', keepAlive: false }
},{
path: '/goodsQR',
name: 'goodsQR',
component: () => import('@/views/goodsQR'),
meta: { title: '物品详情', keepAlive: false }
},{
path: '/democratic',
name: 'democratic',
component: () => import('@/views/democratic'),
meta: { title: '民主选举', keepAlive: false }
},{
path: '/democraticDetail',
name: 'democraticDetail',
component: () => import('@/views/democratic/detail'),
meta: { title: '民主选举', keepAlive: false }
}
]

4
src/views/activity/index.vue

@ -11,8 +11,8 @@
<div class="time gray font-size14">时间{{ item.strTime }} {{ item.endTime }} </div>
<div class="flex flex-end" v-if="item.online === 1">
<div>
<span>报名人数</span> <span class="font-size18 orange">{{ item.currentParticipants
}}</span>/<span class="font-size14">{{ item.participants }}</span>
<span>报名人数</span> <span class="font-size18 orange">{{ item.registered
}}</span>/<span class="font-size14">{{ item.quota }}</span>
</div>
<van-button type="info" size="small" round @click="handelClickJump('activityDetail', item)"
:disabled="disabledRecord(item)">{{ recordFlag(item) ? '已报名' : '报名' }}</van-button>

349
src/views/democratic/detail.vue

@ -0,0 +1,349 @@
<template>
<div>
<div class='container'>
<div class="flex flex-y flex1 flex-end" >
<div class="activity_content flex flex-y">
<div class="flex flex1 oh">
<div class="flex flex-y flex1 m-right10 oh">
<span class="van-multi-ellipsis--l2 text1" style="line-height: 28px;">
{{ info.title }}({{ info.multiFlag==1 ? '多选' : '单选' }})
</span>
</div>
</div>
<div class="flex flex-end flex-center gray m-top10 font-size13">
<div class="flex flex-center">
<span style="color: #FF9C00;margin-right: 10px;">{{ info.multiFlag==1 ? '进行中' : '已截止' }}</span>
<span>{{ info.resiCount || 0 }}人参与</span>
</div>
<div v-if="info.endTime">截止{{ info.endTime }}</div>
</div>
</div>
</div>
<div class="intro" v-html="info.introduce"></div>
<div class="vote-page">
<div v-for="(option, index) in voteOptions" :key="index" class="vote-option">
<input
type="radio"
:id="'option-' + index"
:value="option.electionId"
:checked="selectedOption === option.electionId"
@click="toggleSelection(option.electionId)"
:disabled="hasVoted"
class="custom-radio"
/>
<label :for="'option-' + index" class="vote-label">
<img :src="option.avatar || require('@/assets/images/user1.png')" alt="avatar" class="avatar" />
<div class="option-details">
<div class="option-header">
<h2 class="option-name">{{ option.name }}</h2>
<span class="vote-count" v-if="hasVoted">
{{ option.optionCount }}
</span>
</div>
<div class="progress-bar" v-if="hasVoted">
<div
class="progress-fill"
:style="{ width: (option.optionCount / totalVotes * 100) + '%' }"
></div>
</div>
<p class="option-description">{{ option.remark }}</p>
</div>
</label>
</div>
</div>
<div class="button-container">
<button
:class="{'voted': hasVoted}"
class="vote-button"
@click="handleVote"
:disabled="hasVoted"
>
{{ hasVoted ? '已投票' : '投票' }}
</button>
</div>
</div>
<Android></Android>
</div>
</template>
<script>
import {getDemocryDetail,democraticVote } from '@/api/democratic';
import { Toast, Dialog } from 'vant'
export default {
data() {
return {
info: {
},
selectedOption: null, //
voteOptions: [
],
hasVoted: false, //
electionId:null,
resiId:null,
};
},
created() {
this.electionId = this.$route.query.id;
this.resiId = this.$store.state.app.userInfo.id;
this.communityDemocryDetail()
},
mounted() {
},
methods: {
toggleSelection(optionId) {
this.selectedOption = this.selectedOption === optionId ? null : optionId;
},
handleVote() {
if (this.selectedOption) {
//
let params = {
electionOptionId:this.electionId,
resiId:this.resiId
}
democraticVote(params).then(res => {
if (res.code === 0) {
if (!this.hasVoted) {
this.hasVoted = true; //
}
Dialog.confirm({
title: '提示',
message: '投票成功',
})
.then(() => {})
.catch(() => {});
}
}).catch(err => {
})
}else{
Dialog.confirm({
title: '提示',
message: '您尚未选择投票人',
})
.then(() => {
})
.catch(() => {
});
}
},
//
async communityDemocryDetail() {
const handleResponse = (res) => {
if (res.code === 0) {
this.info = res.data;
//
if (res.data.option && res.data.option.length > 0) {
this.voteOptions = res.data.option;
}
//
if (res.data.isCanSelect==0) {
console.log("已投票")
this.hasVoted = true; //
}
}
}
let params = {
electionId:this.electionId,
resiId:this.resiId
}
let res = await getDemocryDetail(params);
handleResponse(res);
}
},
components: {},
computed: {
totalVotes() {
return this.voteOptions.reduce((sum, option) => sum + option.votes, 0);
},
},
watch: {},
}
</script>
<style lang='less' scoped>
.activity_content {
padding-bottom: 10px;
box-sizing: border-box;
width: 100%;
border-bottom: 1px solid #EAEAEA;
margin-top: 14px;
min-height: 50px;
.img {
width: 231px;
height: 33px;
margin: 5px 3px 0 3px;
}
&:last-child {
border-bottom: none;
}
.content {
width: 325px;
height: 40px;
font-family: PingFang SC;
font-weight: 500;
font-size: 16px;
color: #333333;
line-height: 23px;
}
.dianzan {
width: 325px;
height: 20px;
display: flex;
font-size: 13px;
color: #AAAAAA;
flex-direction: row;
justify-content: space-evenly;
align-items: center;
.img {
width: 14.5px;
height: 15px;
}
}
}
.vote-page {
width: 100%;
// max-width: 600px;
margin: auto;
// padding: 5px;
// background-color: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
background: linear-gradient(to top, #E1F7F3, #DAE6FF);
}
.vote-option {
display: flex;
align-items: center;
padding: 5px 0;
border-bottom: 1px solid #eee;
width: 100%;
}
.custom-radio {
appearance: none;
width: 20px;
height: 20px;
border-radius: 50%;
border: 2px solid white;
margin-right: 15px;
cursor: pointer;
position: relative;
}
.custom-radio:checked::before {
content: '';
display: block;
width: 10px;
height: 10px;
background-color: #007bff;
border-radius: 50%;
position: absolute;
top: 3px;
left: 2px;
}
.vote-label {
display: flex;
align-items: center;
cursor: pointer;
width: 100%;
min-height: 60px;
background-color: white;
border-radius: 5px; /* 修改为圆角 */
}
.avatar {
width: 50px;
height: 50px;
border-radius: 50%;
margin-right: 15px;
}
.option-details {
flex: 1;
}
.option-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.option-name {
font-size: 0.8em;
margin: 0;
}
.option-description {
color: #666;
font-size: 0.7em;
margin: 5px 0;
}
.vote-count {
font-size: 0.9em;
color: orange;
}
.progress-bar {
width: 100%;
height: 8px;
background-color: #eee;
border-radius: 4px;
overflow: hidden;
margin-top: 8px;
}
.progress-fill {
height: 100%;
background: linear-gradient(to right, #3887F8, #3FC7FF);
}
.button-container {
display: flex;
justify-content: center; /* 水平居中 */
width: 100%;
margin-top: 20px; /* 可选,设置按钮上方的间距 */
}
.vote-button {
width: 100px;
height: 40px;
background-color: #3887F8;
color: white;
border: none;
border-radius: 20px;
cursor: pointer;
font-size: 16px;
transition: background-color 0.3s;
}
.vote-button.voted {
background-color: #cccccc;
cursor: not-allowed;
}
.intro {
text-indent: 2em;
font-size: 16px;
color: #333333;
line-height: 25px;
}
</style>

231
src/views/democratic/index.vue

@ -0,0 +1,231 @@
<template>
<div>
<div class='container'>
<div class="flex flex-y flex1 flex-end" v-if="democraticList.length !== 0">
<van-list v-model="loading" :finished="finished" finished-text="没有更多了"
@load="democraticList" class="card" :offset="50">
<div class="activity_content flex flex-y" v-for="(item, index) in democraticList"
:key="index" @click="toDetail(item)">
<div class="flex flex1 oh">
<div class="flex flex-y flex1 m-right10 oh">
<span class="van-multi-ellipsis--l2 text1" style="line-height: 28px;">
{{ item.title }}
</span>
</div>
</div>
<div class="flex flex-end flex-center gray m-top10 font-size13">
<div class="flex flex-center">
<span style="color: #FF9C00;margin-right: 10px;">进行中</span>
<span>{{ item.resiCount || 0 }}人参与</span>
</div>
<div v-if="item.endTime">截止{{ item.endTime }}</div>
</div>
</div>
</van-list>
</div>
<div v-else class="no-data">
暂无数据~
</div>
</div>
<Android></Android>
</div>
</template>
<script>
import {communityDemocry } from '@/api/democratic';
export default {
data() {
return {
democraticList: [
],
pageSize: 5,
pageNo: 1,
agencyId: null,
finished: false,
loading: true,
showRegister: false,
searchValue: ""
};
},
created() {
this.agencyId = this.$route.query.agencyId?this.$route.query.agencyId: this.$store.state.app.agencyId;
// todo:
// this.agencyId = "1846432703164649473";
this.communityDemocryList()
},
methods: {
toDetail(item){
this.$router.push({name:'democraticDetail',query:{id:item.id}})
},
handleSearch(){
this.PublicityList = [];
this.pageNo = 1;
this.communityDemocryList()
},
async communityDemocryList() {
let parm = {
pageSize: 10,
pageNo: 1,
agencyId: this.agencyId
}
let res = await communityDemocry(parm)
console.log("***********************************")
console.log(res)
if (res.code === 0) {
this.loading = false;
if (!res.data || res.data.list.length < this.pageSize) {
this.finished = true;
}
this.democraticList = this.democraticList.concat(res.data.list);
}
},
},
components: {},
computed: {},
watch: {},
}
</script>
<style lang='less' scoped>
.text2{
font-family: PingFang SC;
font-weight: 500;
font-size: 12px;
color: #999999;
line-height: 48px;
}
.text1{
font-family: PingFang SC;
font-weight: 500;
font-size: 20px;
color: #000000;
line-height: 44px;
}
.custom-button {
width: 60px;
height: 33px;
}
.activity_content {
padding-bottom: 10px;
box-sizing: border-box;
width: 100%;
border-bottom: 1px solid #EAEAEA;
margin-top: 14px;
min-height: 50px;
.img {
width: 231px;
height: 33px;
margin: 5px 3px 0 3px;
}
&:last-child {
border-bottom: none;
}
.content {
width: 325px;
height: 40px;
font-family: PingFang SC;
font-weight: 500;
font-size: 16px;
color: #333333;
line-height: 23px;
}
.dianzan {
width: 325px;
height: 20px;
display: flex;
font-size: 13px;
color: #AAAAAA;
flex-direction: row;
justify-content: space-evenly;
align-items: center;
.img {
width: 14.5px;
height: 15px;
}
}
}
.header {}
.header .input_search {
width: 279px;
height: 33px;
background: rgba(193, 193, 193, 0.16);
border-radius: 17px;
// flex: 1;
color: #333333;
border: none;
/* 取消边框 */
margin-left: 10px;
}
.header .btn_search {
width: 60px;
height: 33px;
background: #3974F6;
border-radius: 17px;
font-family: PingFang SC;
font-weight: 500;
font-size: 14px;
color: #FFFFFF;
line-height: 23px;
border: none;
/* 取消边框 */
margin-right: 10px;
}
::v-deep .van-search__content {
background-color: white;
border: 1px solid #3974F6;
}
::v-deep .van-search__input {
color: #000;
}
::v-deep .van-field__control::placeholder {
color: #A0A0A0;
}
:deep(.van-field__control) {
font-size: 13px;
}
.van-tab__title {
padding: 5px 12px; /* 内边距调整 */
font-size: 14px; /* 字体大小 */
}
.van-tabs__nav {
justify-content: space-between; /* 平均分布 */
}
.grid-container {
display: grid;
grid-template-columns: repeat(4, 1fr); /* 每列4个 */
gap: 10px; /* 图片之间的间距 */
// padding: 16px;
align-items: start; /* 子元素顶对齐 */
}
.font-size12{
font-size: 12px;
}
</style>

117
src/views/goodsQR/index.less

@ -0,0 +1,117 @@
.header{
background:url('@/assets/images/houseQR/header_bg.png') no-repeat;
background-size: 100%;
width: 100%;
height: 210px;
z-index: 1;
}
.mask{
background:url('@/assets/images/houseQR/header_bg_mask.png');
background-size: 100%;
position: fixed;
width: 100%;
top: 0;
left: 0;
height: 210px;
z-index: 2;
}
section{
position: absolute;
top: 120px;
z-index: 3;
.house_base{
position: relative;
height: 80px;
background: url('@/assets/images/houseQR/house_bg.png') no-repeat;
background-size: 85% 100% ;
background-position: center center;
font-size: 18px;
font-weight: bold;
padding: 0 30px 0 0 ;
box-sizing: border-box;
img{
width: 115px;
height: 102px;
position: relative;
top: -20px;
}
}
}
.basi_content{
border-radius: 0 0 8px 8px;
position: relative;
&::after{
content: '';
position: absolute;
left: 0;
top: -13px;
width: 0;
height: 0;
border-left:9px solid transparent;
border-right:12px solid transparent;
border-bottom:12px solid #dfe9ef;
}
&::before{
content: '';
position: absolute;
right: 0;
top: -13px;
width: 0;
height: 0;
border-left:9px solid transparent;
border-right:12px solid transparent;
border-bottom:12px solid #dfe9ef;
}
}
a{
padding: 5px 17px;
color: #ffffff;
background: #3974f6;
border-radius: 30px;
height: 28px;
text-align: center;
line-height: 18px;
font-size: 14px;
box-sizing: border-box;
}
.my_community{
padding-top: 8px;
box-sizing: border-box;
font-family: pingfang-bold;
}
.footer{
color: #ffffff;
background-color: rgba(51,51,51,0.9) ;
border-radius: 7px;
height: 38px;
padding: 7px 16px;
position: fixed;
bottom: 10px;
left: 10px;
box-sizing: border-box;
z-index: 10;
}
.title {
display: flex;
flex-direction: column;
align-items: flex-start; /* 左对齐 */
}
.title span:first-child {
margin-bottom: 10px; /* 设置上下行间距 */
}
.img_header{
img{
width: 100%;
height: 210px;
}
}
.intro {
text-indent: 2em;
font-size: 16px;
color: #333333;
line-height: 25px;
}

187
src/views/goodsQR/index.vue

@ -0,0 +1,187 @@
<template>
<div style="position: relative;">
<div class="img_header">
<img :src="formData.picture || require('@/assets/images/houseQR/header_bg.png')" alt="" />
</div>
<section>
<div class="content card">
<div class="title">
<span>{{ formData.name || '未知' }}</span>
<span>{{ formData.agencyName || '' }} {{ formData.createdTime || '' }}</span>
</div>
<div class="intro">
{{ formData.introduce || '暂无介绍' }}
</div>
</div>
<div class="content card">
<div class="title">
<span>我的社区</span>
</div>
<div class="my_community flex flex-wrap">
<div style="width: 25%" class="flex flex-y flex-center1 flex-center2" v-for="(item, index) in myCommunity"
:key="index">
<img :src="item.imgSrc" class="img_33 m-top16" alt="" @click="handelCLickJump(item)" />
<span class="font-size14 m-top10">{{ item.title }}</span>
</div>
</div>
</div>
<div class="content card " style="margin-top: 10px;margin-bottom: 70px;">
<div class="title"><span>服务矩阵</span></div>
<div class="my_community flex flex-wrap">
<div style="width: 25%" class="flex flex-y flex-center1 flex-center2" v-for="(item, index) in serverList"
:key="index" @click="handelCLickJump(item)">
<img :src="item.imgSrc" class="img_33 m-top16" alt="" />
<span class="font-size14 m-top10">{{ item.title }}</span>
</div>
</div>
</div>
</section>
<div class="footer content flex flex-center2 flex-end">
<span>关注公众号了解更多...</span>
<van-button round color="#ffa800"
url="https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzkxNzQ5MzUzNg==&scene=110#wechat_redirect"
size="small">关注</van-button>
</div>
<van-popup v-model="showLaunch" round v-if="mpObj">
<launch-weapp :mpObj="mpObj"></launch-weapp>
</van-popup>
</div>
</template>
<script>
import { getGoodInfoQR } from '@/api/good'
import { Notify } from 'vant'
import launchWeapp from '@/components/launchWeapp/index'
export default {
name: 'goodQR',
data() {
return {
goodId: null,
myCommunity: [
{
imgSrc: require('@/assets/images/houseQR/9.png'),
title: '二维码下载',
path: '/mine'
},
{
imgSrc: require('@/assets/images/houseQR/2.png'),
title: '我有诉求',
path: '/event'
},
{
imgSrc: require('@/assets/images/houseQR/3.png'),
title: '社区讯息',
path: '/communityPublicity'
},
{
imgSrc: require('@/assets/images/houseQR/4.png'),
title: '社区活动',
path: '/activity'
},
{
imgSrc: require('@/assets/images/houseQR/5.png'),
title: '居民议事',
path: '/discussion'
},
{
imgSrc: require('@/assets/images/houseQR/6.png'),
title: '满意度测评',
path: '/mySatisfaction'
},
{
imgSrc: require('@/assets/images/houseQR/7.png'),
title: '可享服务',
path: '/Enjoyableservices'
},
{
imgSrc: require('@/assets/images/houseQR/8.png'),
title: '身边网格员'
}
],
serverList: [
{
imgSrc: require('@/assets/images/houseQR/10.png'),
title: '户政服务',
},
{
imgSrc: require('@/assets/images/houseQR/11.png'),
title: '身份证业务',
type:'security-1',
appId:'wxf419ad41949b1db6',
url:'pages/index/index.html'
}
],
formData: {},
showLaunch:false,
mpObj:null
}
},
created() {
this.goodId = this.$route.query.goodId
console.log("========================================")
console.log(this.goodId)
this.getGoodInfo()
},
mounted() {
this.share()
},
components:{
launchWeapp
},
methods: {
share() {
let than = this
if (wx.updateAppMessageShareData) {
wx.ready(function () {
wx.updateAppMessageShareData({
title: 'e智社区',
desc: '我的电子门牌',
link: `https://epmet-preview.elinkservice.cn/epmet-wx-pa/#/houseQR?houseId=${than.houesId}&appId=${than.$store.state.app.appId}`,
imgUrl: 'https://elink-esua-epdc.oss-cn-qingdao.aliyuncs.com/epmet/test/20240710/617f7fb327064d89892823b81b11cd70.png',
success: function () { }
})
});
} else {
wx.onMenuShareAppMessage({
title: 'e智社区',
desc: '我的电子门牌',
link: `http://epmet-cloud.elinkservice.cn/#/houseQR?houseId=${than.houesId}}&appId=${than.$store.state.app.appId}`,
imgUrl: 'https://elink-esua-epdc.oss-cn-qingdao.aliyuncs.com/epmet/test/20240710/617f7fb327064d89892823b81b11cd70.png',
success: function () { }
})
}
},
getGoodInfo() {
getGoodInfoQR(this.goodId).then(res => {
this.formData = res.data;
})
},
handelCLickJump(item) {
if (item.path) {
this.$router.push({ path: item.path})
}else if(item.type === 'security' || item.type === 'security-1'){
this.showLaunch = true;
this.mpObj = item;
}
else {
Notify({ type: 'primary', message: '功能持续开放中,敬请期待!' })
}
}
}
}
</script>
<style scoped lang="less">
@import './index';
:deep .van-popup{
width: 290px;
height: 244px;
padding-top: 15px;
box-sizing: border-box;
background: url('@/assets/images/houseQR/dialog_bg.png') no-repeat;
background-size: 100% 100%;
overflow: hidden;
}
</style>

10
src/views/home2/index.vue

@ -70,15 +70,15 @@
<span @click="$router.push('/activity')">更多</span>
</div>
<div class="activity_content flex" v-for="(item, index) in activityList" :key="index" @click="handelClickJump(`activityDetail`,item)">
<img :src="item.coverPic" alt="" class="mr10" style="width: 75px;height: 95px;">
<img :src="item.imgs" alt="" class="mr10" style="width: 75px;height: 95px;">
<div class="flex flex-y flex1 flex-end" style="overflow: hidden;">
<div class="van-ellipsis">{{ item.activityName }}</div>
<div class="address font-size14 van-ellipsis gray">地点{{ item.address }}</div>
<div class="time gray font-size14">时间{{ item.startTime }}</div>
<div class="time gray font-size14">时间{{ item.strTime }} {{ item.endTime }}</div>
<div class="flex flex-end">
<div>
<span>报名人数</span> <span class="font-size18 orange">{{ item.currentParticipants }}</span>/<span
class="font-size14">{{ item.participants }}</span>
<span>报名人数</span> <span class="font-size18 orange">{{ item.registered }}</span>/<span
class="font-size14">{{ item.quota }}</span>
</div>
<van-button type="info" size="small" round @click="handelClickJump(`activityDetail`,item)"
:disabled="disabledRecord(item)">{{recordFlag(item)?'已报名':'报名'}}</van-button>
@ -172,7 +172,7 @@ export default {
{
imgSrc: require('@/assets/images/squaredPaper/2.png'),
title: '民生选举',
path: 'communityPublicity'
path: 'democratic'
},
{
imgSrc: require('@/assets/images/squaredPaper/3.png'),

Loading…
Cancel
Save