630 lines
23 KiB
Vue
630 lines
23 KiB
Vue
<template>
|
|
<view class="main">
|
|
<view class="heard">
|
|
<image class="headerBg" src="https://eshangtech.com/ShopICO/ahyd-BID/plan/blueBack.png"></image>
|
|
<view class="top" :style="{height:(menu.bottom + 6)+'px'}">
|
|
<image :style="{top:(menu.top + ((menu.height - 24)/2))+'px'}" @click="handleBack" class="img" src="https://eshangtech.com/ShopICO/ahyd-BID/examine/leftArrowWhite.svg"></image>
|
|
</view>
|
|
<view class="content">
|
|
<view class="block"></view>
|
|
<p class="title">年度经营计划</p>
|
|
<!-- 选择月份 -->
|
|
<view class="monthTabs">
|
|
<scroll-view class="big" :show-scrollbar="false" scroll-with-animation scroll-x="true" enable-flex :scrollIntoView="selectMonthId" >
|
|
<div :id="'item'+item.value" :class="selectMonth===item.value?'monthItem selectItem':'monthItem'" v-for="(item,index) in monthList" :key="index" @click="handleSelectMonth(item.value)">{{item.label}}</div>
|
|
</scroll-view>
|
|
</view>
|
|
|
|
<view class="monthDetailList">
|
|
<swiper class="swiper" previous-margin="40rpx" next-margin="40rpx" @change="handleDetailScroll" :current="selectDetail">
|
|
<block v-for="(item,index) in swiperList" :key="index">
|
|
<swiper-item class="swiper-item" :item-id="index" :data-item-id="index" bindtap='clickChange'>
|
|
<view class="box">
|
|
<view :class="selectDetail===index?'detail':'detail noShow'">
|
|
<view class="item" v-if="selectDetail===index">
|
|
<view class="itemTop">
|
|
<view class="left">
|
|
<image class="logo" src="https://eshangtech.com/ShopICO/ahyd-BID/plan/monthLogo.svg"></image>
|
|
<view class="detailContent">
|
|
<view class="top">
|
|
<span class="money">{{detail.Revenue_Amount || '-'}}</span>
|
|
<image v-if="detail.Budget_Degree>100" class="icon" src="/static/images/index/yearSuccess.svg"></image>
|
|
</view>
|
|
<p class="text">本月已完成<text class="unit">/元</text></p>
|
|
</view>
|
|
</view>
|
|
<view class="right">
|
|
<p class="add" :style="{color:detail.Growth_Rate>0?'#E83944':'#049E77'}">{{detail.Growth_Rate>0?'+':'-'}}{{detail.Growth_Rate || '-'}}%</p>
|
|
<text class="compare">比计划</text>
|
|
</view>
|
|
</view>
|
|
<view class="itemBottom" :style="{marginTop: selectDetail===index?'24px':'4px'}">
|
|
<view class="progress">
|
|
<view class="have" :style="{width: detail.Budget_Degree + '%'}"></view>
|
|
</view>
|
|
<view class="text">
|
|
<span class="success">计划完成<span class="unit">/元</span></span>
|
|
<span class="target">{{ detail.Budget_Amount || '-' }}</span>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="item" v-if="selectDetail!==index">
|
|
<view class="itemTop">
|
|
<view class="left">
|
|
<image class="logo" src="https://eshangtech.com/ShopICO/ahyd-BID/plan/monthLogo.svg"></image>
|
|
<view class="detailContent">
|
|
<view class="top">
|
|
<span class="money">{{'-'}}</span>
|
|
<image v-if="detail.Budget_Degree>100" class="icon" src="/static/images/index/yearSuccess.svg"></image>
|
|
</view>
|
|
<p class="text">本月已完成<text class="unit">/元</text></p>
|
|
</view>
|
|
</view>
|
|
<view class="right">
|
|
<p class="add" :style="{color:detail.Growth_Rate>0?'#E83944':'#049E77'}">{{detail.Growth_Rate>0?'+':'-'}}{{ '-'}}%</p>
|
|
<text class="compare">比计划</text>
|
|
</view>
|
|
</view>
|
|
<view class="itemBottom" :style="{marginTop: selectDetail===index?'24px':'4px'}">
|
|
<view class="progress">
|
|
<view class="have" :style="{width: detail.Budget_Degree + '%'}"></view>
|
|
</view>
|
|
<view class="text">
|
|
<span class="success">计划完成<span class="unit">/元</span></span>
|
|
<span class="target">{{ '-' }}</span>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</swiper-item>
|
|
</block>
|
|
</swiper>
|
|
</view>
|
|
|
|
</view>
|
|
</view>
|
|
<view class="serviceList">
|
|
<scroll-view class="list" scroll-y="true">
|
|
<view class="item" v-for="(item,index) in detail.RegionBudgetList" :key="index" @click="goPage(item.Serverpart_ID)">
|
|
<view class="top">
|
|
<p class="title">{{ item.Serverpart_Name || ''}}</p>
|
|
<image class="icon" src="https://eshangtech.com/ShopICO/ahyd-BID/plan/blueArrow.svg"></image>
|
|
</view>
|
|
<view class="detail">
|
|
<view class="left">
|
|
<view class="money">
|
|
<span class="num">{{ item.Revenue_Amount }}</span>
|
|
<image v-if="item.Budget_Degree>100" class="icon" src="/static/images/index/yearSuccess.svg"></image>
|
|
</view>
|
|
<view class="text">本月已完成<span class="unit">/元</span></view>
|
|
</view>
|
|
<view class="right">
|
|
<p class="add" :style="{color:item.Growth_Rate>0?'#E83944':'#049E77'}"><span>{{item.Growth_Rate>0?'+':''}}</span>{{item.Growth_Rate || '-'}}%</p>
|
|
<p class="text">比计划</p>
|
|
</view>
|
|
</view>
|
|
<view class="progress">
|
|
<view class="box">
|
|
<view class="have" :style="{width:item.Budget_Degree + '%'}"></view>
|
|
</view>
|
|
<view class="other">
|
|
<view>
|
|
<span class="unit">计划完成</span>
|
|
<span class="type">/元</span>
|
|
</view>
|
|
<view class="money">{{item.Budget_Amount || ''}}</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</scroll-view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import request from '@/util/index.js'
|
|
export default{
|
|
name: "yearPlan",
|
|
data(){
|
|
return {
|
|
monthList:[{label:'1月',value:1},{label:'2月',value:2},{label:'3月',value:3},{label:'4月',value:4},{label:'5月',value:5},{label:'6月',value:6},{label:'7月',value:7}, {label:'8月',value:8},{label:'9月',value:9},{label:'10月',value:10},{label:'11月',value:11},{label:'12月',value:12}],
|
|
selectMonth:0,// 选中的月份
|
|
selectMonthId:'',// 选中月份的id
|
|
swiperList:[{label:1111},{label:2222},{label:3333},{label:4444},{label:5555},{label:6666},{label:7777},{label:8888},{label:9999},{label:1010}, {label:11111111},{label:1212}],
|
|
selectDetail:0,// 选中的月份详情卡片
|
|
serviceList:[{},{},{},{},{},{}],
|
|
menu:{},
|
|
detail:{},// 页面请求到的数据
|
|
searchTime:'',
|
|
}
|
|
},
|
|
onLoad(){
|
|
// 获取手机参数对页面进行适配
|
|
this.menu = uni.getMenuButtonBoundingClientRect()
|
|
// 先拿到首页的时间 作为调用接口的统一时间 存的lastDay存当前月份的具体日期切换回本月的日期判断有用
|
|
this.searchTime = uni.getStorageSync('lastDay')
|
|
this.lastDay = uni.getStorageSync('lastDay')
|
|
// 拿到当前时间
|
|
const date = new Date(this.lastDay)
|
|
let month = date.getMonth() + 1
|
|
// 滚动的月份列表
|
|
// 超过当前月份的内容不显示 下同
|
|
this.monthList = this.monthList.filter(item=>item.value<=month)
|
|
// 详情卡片的滑动列表
|
|
this.swiperList = this.swiperList.filter((item,index)=>index<month)
|
|
// 根据月份显示的详情卡片
|
|
this.selectDetail = month - 1
|
|
// // 拿到片区详情完成列表
|
|
// this.handleAreaDetailList()
|
|
},
|
|
onReady(){
|
|
// 默认把月份选择在当前相对应的月份
|
|
this.getThisMonth()
|
|
},
|
|
methods:{
|
|
// 横向月份选择器的初始值
|
|
getThisMonth(){
|
|
// 拿到当前的搜索时间 来判断默认选中第几个月份
|
|
const date = new Date(this.searchTime)
|
|
const month = date.getMonth() + 1
|
|
this.selectMonth = month
|
|
this.selectMonthId = `item${month}`
|
|
},
|
|
// 点击月份切换月份
|
|
handleSelectMonth(value){
|
|
// 切换月份的时候 改变月份的值 改变选中的id 显示的卡片详情
|
|
this.selectMonth = value
|
|
this.selectMonthId = `item${value}`
|
|
this.selectDetail = value - 1
|
|
},
|
|
// 月份信息详情的滚动
|
|
// 由于点击月份的切换会让卡片详情的滑块列表滚动 所以在这加事件就可以
|
|
handleDetailScroll(e){
|
|
// 月份详情卡片滚动改变选中的月份和选中的滑动id
|
|
const date = new Date(this.lastDay)
|
|
let year = date.getFullYear()
|
|
let month = date.getMonth() + 1
|
|
let day = date.getDate()
|
|
// 滚动 就等于改变月份 月份详情卡片的id
|
|
this.selectDetail = e.detail.current
|
|
this.selectMonth = this.selectDetail + 1
|
|
this.selectMonthId = `item${this.selectDetail<5?1:this.selectDetail}`
|
|
// 当月份和首页传入的时间的月份一致的话 时间就是首页的时间 反之就是之前月份的最后一天
|
|
if (month === this.selectMonth){
|
|
// 兼容ios 时间月份和日期小于10的必须加上0 不然ios就会报错
|
|
if (month<10){
|
|
month = '0' + month
|
|
}
|
|
this.searchTime = `${year}-${month}-${day}`
|
|
}else{
|
|
let m = this.selectMonth
|
|
if (m<10){
|
|
m = '0' + m
|
|
}
|
|
let d = this.$util.getThisMonthDay(`${year}-${m}`)
|
|
this.searchTime = `${year}-${m}-${d}`
|
|
}
|
|
// 用新的时间去请求 得到新的数据
|
|
this.handleAreaDetailList()
|
|
},
|
|
async handleAreaDetailList(){
|
|
uni.showLoading({title:'正在加载'})
|
|
// 用全局的时间 改变时间调用接口就可以拿到新数据 不用在接口里面修改时间字段
|
|
const req = {
|
|
StatisticsDate: this.searchTime,
|
|
ProvinceCode:'340000',
|
|
StatisticsType:1
|
|
}
|
|
const data = await request.$webGet('CommercialApi/Revenue/GetProvinceRevenueBudget',req)
|
|
// 对钱进行百分号的格式化
|
|
for (let key in data.Result_Data){
|
|
if (key==='Budget_Amount' || key==='Revenue_Amount'){
|
|
data.Result_Data[key] = this.$util.fmoney(data.Result_Data[key])
|
|
}
|
|
}
|
|
data.Result_Data.RegionBudgetList.forEach(item=>{
|
|
for (let key in item){
|
|
if (key==='Budget_Amount' || key==='Revenue_Amount'){
|
|
item[key] = this.$util.fmoney(item[key])
|
|
}
|
|
}
|
|
})
|
|
this.detail = data.Result_Data
|
|
uni.hideLoading()
|
|
},
|
|
// 跳转
|
|
goPage(id){
|
|
this.$util.toNextRoute('navigateTo', '/pages/plan/areaPlanMonth?id='+id+'&search='+this.searchTime)
|
|
},
|
|
handleBack(){
|
|
uni.navigateBack({
|
|
delta: 1
|
|
});
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
@import '/static/public/font/stylesheet.css';
|
|
.main{
|
|
width: 100%;
|
|
.heard{
|
|
width: 100%;
|
|
height: 366px;
|
|
position: relative;
|
|
.top{
|
|
width: 100%;
|
|
position: relative;
|
|
.img{
|
|
width: 24px;
|
|
height: 24px;
|
|
position: absolute;
|
|
left: 16px;
|
|
z-index: 3;
|
|
}
|
|
}
|
|
.content{
|
|
width: 100%;
|
|
height: 100%;
|
|
position: absolute;
|
|
box-sizing: border-box;
|
|
top: 0;left: 0;
|
|
z-index: 2;
|
|
.block{
|
|
width: 100%;
|
|
height: 83px;
|
|
}
|
|
.title{
|
|
font-size: 28px;
|
|
font-family: "Alimama ShuHeiTi";
|
|
color: #160002;
|
|
line-height: 39px;
|
|
font-weight: 600;
|
|
text-shadow: 0 4px 8px rgba(2,32,202,0.2);
|
|
background: linear-gradient(180deg, #fff 50%, #B0BBFF 100%);
|
|
-webkit-background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
margin: 14px 24px;
|
|
}
|
|
.monthTabs{
|
|
width: calc(100% - 32px);
|
|
height: 34px;
|
|
border-radius: 17px;
|
|
box-sizing: border-box;
|
|
border: 1px solid #798DFF;
|
|
background: linear-gradient(180deg, #4762FF 0%, #778EFF 100%);
|
|
overflow: hidden;
|
|
padding: 2px 0;
|
|
margin-top: 16px;
|
|
margin-left: 16px;
|
|
.big{
|
|
width: 100%;
|
|
height: 100%;
|
|
white-space: nowrap;
|
|
.monthItem{
|
|
display: inline-block;
|
|
font-size: 14px;
|
|
padding: 2px 16px;
|
|
font-family: PingFangSC-Semibold, PingFang SC;
|
|
font-weight: 600;
|
|
color: #B8C2FF;
|
|
line-height: 24px;
|
|
margin-right: 4px;
|
|
text-align: center;
|
|
border-radius: 12px;
|
|
}
|
|
.selectItem{
|
|
background: #fff;
|
|
}
|
|
.monthItem:first-child{
|
|
margin-left: 4px;
|
|
}
|
|
}
|
|
}
|
|
.monthDetailList{
|
|
width: 100%;
|
|
height: 140px;
|
|
margin-top: 12px;
|
|
.swiper{
|
|
width: 100%;
|
|
height: 100%;
|
|
.swiper-item{
|
|
.box{
|
|
width: 100%;
|
|
height: 100%;
|
|
.detail{
|
|
width: calc(100% - 20px);
|
|
height: 100%;
|
|
background: linear-gradient(314deg, #D8EAFF 0%, #F3F5FF 32%, #F5FCFF 54%, #F0F7FF 70%, #D3D9FF 100%);
|
|
margin-left: 10px;
|
|
border-radius: 8px;
|
|
box-sizing: border-box;
|
|
padding: 16px;
|
|
.item{
|
|
.itemTop{
|
|
width: 100%;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
.left{
|
|
display: flex;
|
|
.logo{
|
|
width: 44px;
|
|
height: 44px;
|
|
margin-right: 8px;
|
|
}
|
|
.detailContent{
|
|
.top{
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 2px;
|
|
.money{
|
|
font-size: 18px;
|
|
font-family: DINAlternate-Bold, DINAlternate;
|
|
font-weight: bold;
|
|
color: #160002;
|
|
line-height: 24px;
|
|
}
|
|
.icon{
|
|
width: 15px;
|
|
height: 15px;
|
|
margin-left: 6px;
|
|
}
|
|
}
|
|
.text{
|
|
font-size: 14px;
|
|
font-family: PingFangSC-Regular, PingFang SC;
|
|
font-weight: 400;
|
|
color: #786B6C;
|
|
line-height: 20px;
|
|
.unit{
|
|
font-size: 14px;
|
|
font-family: PingFangSC-Regular, PingFang SC;
|
|
font-weight: 400;
|
|
color: #A69E9F;
|
|
line-height: 20px;
|
|
margin-left: 2px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.right{
|
|
text-align: right;
|
|
.add{
|
|
font-size: 18px;
|
|
font-family: DINAlternate-Bold, DINAlternate;
|
|
font-weight: bold;
|
|
line-height: 24px;
|
|
}
|
|
.compare{
|
|
font-size: 14px;
|
|
font-family: PingFangSC-Regular, PingFang SC;
|
|
font-weight: 400;
|
|
color: #A69E9F;
|
|
line-height: 18px;
|
|
}
|
|
}
|
|
}
|
|
.itemBottom{
|
|
margin-top: 24px;
|
|
.progress{
|
|
width: 100%;
|
|
height: 10px;
|
|
background: #ccc;
|
|
border-radius: 5px;
|
|
position: relative;
|
|
overflow: hidden;
|
|
.have{
|
|
height: 100%;
|
|
position: absolute;
|
|
left: 0;
|
|
top: 0;
|
|
background: #576EFF;
|
|
border-radius: 5px;
|
|
}
|
|
}
|
|
.text{
|
|
margin-top: 4px;
|
|
width: 100%;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
.success{
|
|
font-size: 14px;
|
|
font-family: PingFangSC-Regular, PingFang SC;
|
|
font-weight: 400;
|
|
color: #786B6C;
|
|
line-height: 20px;
|
|
.unit{
|
|
font-size: 14px;
|
|
font-family: PingFangSC-Regular, PingFang SC;
|
|
font-weight: 400;
|
|
color: #A69E9F;
|
|
line-height: 20px;
|
|
margin-left: 2px;
|
|
}
|
|
}
|
|
.target{
|
|
font-size: 14px;
|
|
font-family: PingFangSC-Regular, PingFang SC;
|
|
font-weight: 400;
|
|
color: #160002;
|
|
line-height: 20px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.noShow{
|
|
height: 112px;
|
|
margin-top: 14px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
.headerBg{
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
z-index: 1;
|
|
}
|
|
.allowLeft{
|
|
position: absolute;
|
|
width: 24px;
|
|
height: 24px;
|
|
left: 16px;
|
|
}
|
|
}
|
|
|
|
.serviceList{
|
|
width: 100%;
|
|
height: calc(100vh - 366px);
|
|
transform: translateY(-16px);
|
|
border-radius: 8px;
|
|
z-index: 6;
|
|
position: relative;
|
|
background: #fff;
|
|
box-sizing: border-box;
|
|
padding:16px 16px 0;
|
|
.list{
|
|
width: 100%;
|
|
height: 100%;
|
|
::-webkit-scrollbar {width: 0;height: 0;background-color: transparent;}
|
|
.item{
|
|
width: 100%;
|
|
height: 178px;
|
|
background: linear-gradient(314deg, #EDF7FF 0%, #F3F5FF 32%, #F5FCFF 54%, #F0F7FF 70%, #D7DDFF 100%);
|
|
border-radius: 8px;
|
|
margin-bottom: 12px;
|
|
box-sizing: border-box;
|
|
padding: 16px;
|
|
.top{
|
|
display: flex;
|
|
align-items: center;
|
|
.title{
|
|
font-size: 18px;
|
|
font-family: Alimama ShuHeiTi;
|
|
color: #1A33BC;
|
|
line-height: 26px;
|
|
}
|
|
.icon{
|
|
width: 15px;
|
|
height: 15px;
|
|
opacity: 0.8;
|
|
margin-left: 7px;
|
|
}
|
|
}
|
|
.detail{
|
|
margin-top: 16px;
|
|
width: 100%;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
.left{
|
|
.money{
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 2px;
|
|
.num{
|
|
font-size: 20px;
|
|
font-family: DINAlternate-Bold, DINAlternate;
|
|
font-weight: bold;
|
|
color: #160002;
|
|
line-height: 24px;
|
|
margin-right: 4px;
|
|
}
|
|
.icon{
|
|
width: 16px;
|
|
height: 16px;
|
|
}
|
|
}
|
|
.text{
|
|
font-size: 14px;
|
|
font-family: PingFangSC-Regular, PingFang SC;
|
|
font-weight: 400;
|
|
color: #786B6C;
|
|
line-height: 20px;
|
|
.unit{
|
|
color: #A69E9F;
|
|
margin-left: 2px;
|
|
}
|
|
}
|
|
}
|
|
.right{
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: flex-end;
|
|
.add{
|
|
font-size: 24px;
|
|
font-family: DINAlternate-Bold, DINAlternate;
|
|
font-weight: bold;
|
|
line-height: 24px;
|
|
margin-bottom: 2px;
|
|
}
|
|
.text{
|
|
font-size: 12px;
|
|
font-family: PingFangSC-Regular, PingFang SC;
|
|
font-weight: 400;
|
|
color: #A69E9F;
|
|
line-height: 18px;
|
|
}
|
|
}
|
|
}
|
|
.progress{
|
|
margin-top: 16px;
|
|
.box{
|
|
width: 100%;
|
|
height: 10px;
|
|
border-radius: 5px;
|
|
background: #ccc;
|
|
overflow: hidden;
|
|
position: relative;
|
|
.have{
|
|
position: absolute;
|
|
height: 100%;
|
|
background: rgba(87, 110, 255, 1);
|
|
border-radius: 5px;
|
|
left: 0;top: 0;
|
|
}
|
|
}
|
|
.other{
|
|
width: 100%;
|
|
margin-top: 4px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
.unit{
|
|
font-size: 14px;
|
|
font-family: PingFangSC-Regular, PingFang SC;
|
|
font-weight: 400;
|
|
color: #786B6C;
|
|
line-height: 20px;
|
|
}
|
|
.type{
|
|
font-size: 14px;
|
|
font-family: PingFangSC-Regular, PingFang SC;
|
|
font-weight: 400;
|
|
color: #A69E9F;
|
|
line-height: 20px;
|
|
margin-left: 2px;
|
|
}
|
|
.money{
|
|
font-size: 14px;
|
|
font-family: PingFangSC-Regular, PingFang SC;
|
|
font-weight: 400;
|
|
color: #160002;
|
|
line-height: 20px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|