Commit 3640e33d authored by 郭铭瑶's avatar 郭铭瑶 🤘

有求必应

parent 1fcb2c87
......@@ -81,16 +81,30 @@ export default defineComponent({
left: '2%',
right: '4%',
bottom: '1%',
top: '20%',
containLabel: true,
},
xAxis: [
{
type: 'category',
axisLabel: {
interval: 0,
},
axisLine: {
lineStyle: {
color: 'rgba(47,134,238,0.3)',
},
},
},
],
yAxis: [
{
type: 'value',
splitLine: {
lineStyle: {
color: 'rgba(47,134,238,0.3)',
},
},
},
],
}
......
......@@ -95,9 +95,7 @@ export default defineComponent({
{
type: 'value',
splitLine: {
show: true,
lineStyle: {
// color: 'rgba(91,213,255,0.3)'
color: 'rgba(47,134,238,0.3)',
},
},
......
......@@ -95,7 +95,6 @@ export default defineComponent({
display flex
position absolute
left -0.05rem
z-index -1
.line
height .03rem
background rgba(0,0,0,0.8)
......@@ -107,6 +106,7 @@ export default defineComponent({
position relative
text-align center
width .1rem
z-index 1
.icon
width .1rem
height @width
......
<template>
<div class="my-sub">
<span />
<p><slot /></p>
<img src="@/assets/images/sub-dot.png" />
<div class="title">
<span />
<p><slot /></p>
<div v-if="addition" class="addition">
<m-count v-if="addition.value" class="count" :value="addition.value" />
<span v-if="addition.unit">{{ addition.unit }}</span>
</div>
<input
v-if="searchAble"
v-model="inputValue"
:class="{ open: isOpened }"
class="search-bar"
type="text"
@keypress.enter="handleSearch"
/>
<img
v-if="searchAble"
class="search-btn"
src="@/assets/images/search.png"
draggable="false"
@click.prevent="handleOpenSearchBar"
/>
</div>
<img src="@/assets/images/sub-dot.png" draggable="false" />
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { defineComponent, PropType, ref } from 'vue'
interface AdditionProp {
name?: string
value?: number
unit?: string
}
export default defineComponent({
name: 'MySub',
displayName: 'm-sub',
props: {
addition: {
type: Object as PropType<AdditionProp>,
default: null,
},
searchAble: {
type: Boolean as PropType<boolean>,
default: false,
},
},
emits: ['search'],
setup(props, ctx) {
const isOpened = ref(false)
const inputValue = ref('')
const handleSearch = () => {
ctx.emit('search', inputValue.value.trim())
}
const handleOpenSearchBar = () => {
if (!isOpened.value) {
isOpened.value = true
} else {
if (inputValue.value) {
handleSearch()
} else {
isOpened.value = false
}
}
}
return {
isOpened,
inputValue,
handleSearch,
handleOpenSearchBar,
}
},
})
</script>
......@@ -20,17 +81,58 @@ export default defineComponent({
.my-sub
display flex
align-items center
>span
display inline-block
width .02rem
height @width
background $secondary-color
margin-right .05rem
>p
>.title
display flex
align-items center
font-family $font-zcool
color $secondary-color
flex 1
font-size .12rem
>span
display inline-block
width .02rem
height @width
background $secondary-color
margin-right .05rem
.addition
display flex
align-items center
margin-left .1rem
.count
color $yellow
font-size .15rem
font-family $font-pang
padding-bottom .03rem
span
color #aaa
font-size .08rem
margin-left .05rem
.search-bar
display block
width 0
height .16rem
background rgba(0,0,0,0.1)
border-radius .02rem
outline none
margin 0 .05rem
padding 0
box-sizing border-box
font-family $font-din
font-size .1rem
transition all .3s ease-in-out
opacity 0
&.open
width 1rem
padding .02rem .05rem
border .01rem solid $blue
opacity 1
.search-btn
width .14rem
height @width
cursor pointer
transition transform .3s ease-in-out
&:hover
transform scale(1.3) rotate(360deg)
>img
width .6rem
</style>
......@@ -2,8 +2,16 @@
<div class="brief-container">
<div v-for="item in list" :key="item.name">
<img v-if="item.icon" :src="`@/assets/images/${item.icon}`" />
<div :class="{ center: !item.icon }">
<m-count class="count" :value="item.value" />
<div v-if="Array.isArray(item.value)">
<div class="count-group">
<m-count class="count yellow" :value="item.value[0]" />
/
<m-count class="count" :value="item.value[1]" />
</div>
<p>{{ item.name }}</p>
</div>
<div v-else :class="{ center: !item.icon }">
<m-count class="count yellow" :value="item.value" />
<p>{{ item.name }}</p>
</div>
</div>
......@@ -15,7 +23,7 @@ import { defineComponent, PropType } from 'vue'
export interface BriefProp {
name: string
value: number
value: number | number[]
icon?: string
}
export default defineComponent({
......@@ -35,6 +43,11 @@ export default defineComponent({
display flex
justify-content space-around
align-items center
.count
font-size .12rem
&.yellow
font-size .14rem
color $yellow
>div
display flex
align-items center
......@@ -44,9 +57,6 @@ export default defineComponent({
margin-right .05rem
>div
font-weight bold
.count
font-size .13rem
color $yellow
p
color #ccc
&.center
......
<template>
<m-card title="有求必应">
<div class="today-case">
<m-sub :addition="{ value: 157, unit: '件' }">今日案件数</m-sub>
<Brief :list="summary" />
<div class="process">
<img src="@/assets/images/arrow.png" />
<div>
<div v-for="item in process.slice(0, 3)" :key="item.name">
<m-count class="count" :value="item.value" />
<p>{{ item.name }}</p>
</div>
</div>
<div>
<div v-for="item in process.slice(3)" :key="item.name">
<m-count class="count" :value="item.value" />
<p>{{ item.name }}</p>
</div>
</div>
</div>
<div class="chart">
<m-bar :dataset="barData" :option="barOption" />
</div>
<div class="chart wrapper">
<div>
<m-pie :option="pieOption" />
</div>
<div>
<p v-for="item in pieData" :key="item.name">
<span :style="{ background: item.color }" />
{{ item.name }}{{ item.value }}% &nbsp;&nbsp;{{ item.num }}
</p>
</div>
</div>
</div>
<div class="case-follow">
<m-sub search-able @search="searchCase">事件跟踪</m-sub>
<m-scroll :limit="1" :length="caseList.length" :step="1.1" mode="2">
<div v-for="(item, i) in caseList" :key="i" class="detail">
<div class="title">
<p>{{ item.name }}</p>
<span />
<p>{{ item.type }}</p>
</div>
<div class="msg">
<p>{{ item.address }}</p>
<p>{{ item.date }}</p>
</div>
<m-step :steps="steps" :current="item.cur" />
</div>
</m-scroll>
</div>
</m-card>
</template>
<script lang="ts">
import { computed, defineComponent, ref } from 'vue'
import Brief, { BriefProp } from '../components/brief.vue'
export default defineComponent({
name: 'Demand',
components: { Brief },
setup() {
const summary = ref<BriefProp[]>([
{
name: '综合管理',
value: [36, 468],
icon: 'icon6.png',
},
{
name: '街面管理',
value: [64, 261],
icon: 'icon7.png',
},
{
name: '小区管理',
value: [57, 154],
icon: 'icon8.png',
},
])
const process = ref([
{
name: '发现',
value: 157,
},
{
name: '立案',
value: 106,
},
{
name: '派遣',
value: 95,
},
{
name: '结案',
value: 59,
},
{
name: '检查',
value: 64,
},
{
name: '处置',
value: 86,
},
])
const barData = ref({
dimensions: [
{ name: 'date', displayName: '日期' },
{ name: 'data1', displayName: '发现数' },
{ name: 'data2', displayName: '处置数' },
{ name: 'data3', displayName: '结案数' },
],
source: [
{ date: '11-11', data1: 100, data2: 100, data3: 100 },
{ date: '11-12', data1: 110, data2: 110, data3: 120 },
{ date: '11-13', data1: 120, data2: 130, data3: 140 },
{ date: '11-14', data1: 130, data2: 140, data3: 160 },
{ date: '11-15', data1: 140, data2: 150, data3: 180 },
{ date: '11-16', data1: 150, data2: 160, data3: 190 },
{ date: '11-17', data1: 150, data2: 160, data3: 190 },
{ date: '11-18', data1: 150, data2: 160, data3: 190 },
],
})
const barOption = ref({
color: ['#5BD5FF', '#FFCE34', '#826AFA'],
legend: {
right: '2%',
},
series: [
{
type: 'bar',
barWidth: '18%',
itemStyle: { borderRadius: 8 },
barGap: 0,
stack: '总量',
},
{
type: 'bar',
barWidth: '18%',
itemStyle: { borderRadius: 8 },
barGap: 0,
stack: '总量',
},
{
type: 'bar',
barWidth: '18%',
itemStyle: { borderRadius: 8 },
barGap: 0,
stack: '总量',
},
],
})
const pieData = ref([
{
name: '第一工作站',
value: 80,
num: 87,
color: '#47B3FF',
},
{
name: '第二工作站',
value: 75,
num: 72,
color: '#FF9D27',
},
{
name: '第三工作站',
value: 30,
num: 27,
color: '#6EB629',
},
])
const fontSize = computed(() => Math.floor((screen.height * 1.6) / 100))
const pieSeries = pieData.value.map((item, i) => {
const rate = Math.round((pieData.value.length - i) * fontSize.value) + 10
const borderWidth = fontSize.value * 0.6
return {
type: 'pie',
name: item.name,
clockWise: false, //顺时加载
hoverAnimation: false, //鼠标移入变大
radius: [rate, rate],
itemStyle: {
normal: {
label: {
show: false,
},
labelLine: {
show: false,
},
borderWidth,
borderColor: item.color,
},
},
data: [
item,
{
value: 100 - item.value,
name: '',
tooltip: { show: false },
itemStyle: {
normal: {
label: {
show: false,
},
labelLine: {
show: false,
},
color: 'transparent',
borderColor: item.color,
opacity: 0.1,
},
},
},
],
}
})
const pieOption = ref({
legend: {
show: false,
},
series: pieSeries,
})
const steps = ref(['发现', '立案', '派遣', '处置', '核查', '结案'])
const caseList = ref([
{
name: '均乐小区',
type: '电梯困人',
address: '上海市黄浦区延安东路1292弄6~40号',
date: '2020-02-13 13:23:08',
cur: 5,
},
{
name: '均乐小区',
type: '电梯困人',
address: '上海市黄浦区延安东路1292弄6~40号',
date: '2020-02-13 13:23:08',
cur: 4,
},
{
name: '均乐小区',
type: '电梯困人',
address: '上海市黄浦区延安东路1292弄6~40号',
date: '2020-02-13 13:23:08',
cur: 3,
},
{
name: '均乐小区',
type: '电梯困人',
address: '上海市黄浦区延安东路1292弄6~40号',
date: '2020-02-13 13:23:08',
cur: 2,
},
])
const searchCase = (key: string) => {
console.log('searck key: ', key)
}
return {
summary,
process,
barData,
barOption,
pieData,
pieOption,
fontSize,
steps,
caseList,
searchCase,
}
},
})
</script>
<style lang="stylus" scoped>
@import '../../components/MyComponent/main.styl'
$arrow-style()
display block
content ''
width .2rem
height @width
background url('@/assets/images/arrow.png') 100% / 100% 100% no-repeat
position absolute
left 0
top 0
bottom 0
margin auto
transform translate(-80%, 0)
.process
margin-top .1rem
position relative
>img
position absolute
width .2rem
height @width
right 13.3%
top 0
bottom 0
margin auto
transform rotate(90deg)
>div
display flex
align-items center
justify-content space-around
margin-bottom .15rem
&:nth-of-type(1)
div+div
&::before
$arrow-style()
&:nth-of-type(2)
div+div
&::before
$arrow-style()
transform translate(-90%, 0) rotate(180deg)
>div
background url('@/assets/images/num-card.png') 100% / 100% 100% no-repeat
width 28%
padding .05rem 0
text-align center
font-weight bold
position relative
.count
font-size .12rem
p
color #ccc
.chart
width 100%
height 1.1rem
&.wrapper
display flex
>div
width 50%
height 100%
font-weight bold
&:last-child
$center()
flex-direction column
p
display flex
align-items center
margin-bottom .05rem
span
display inline-block
width .06rem
height @width
border-radius 50%
margin-right .1rem
.case-follow
height 1.2rem
overflow hidden
.detail
display flex
flex-direction column
justify-content space-between
padding .1rem
background url('@/assets/images/border2.png') 100% / 100% 100% no-repeat
height 1rem
margin-bottom .1rem
box-sizing border-box
.title
display flex
align-items center
p
font-size .12rem
&:last-child
color $edge
font-size .1rem
span
display block
height .01rem
background $blue
flex 1
margin 0 .1rem
.msg
$center()
justify-content space-between
color $blue
font-size .08rem
</style>
......@@ -3,7 +3,9 @@
<m-card mode="border">
<Complain />
</m-card>
<m-card mode="border"></m-card>
<m-card mode="border">
<Demand />
</m-card>
<m-card mode="border"></m-card>
</div>
</template>
......@@ -11,10 +13,11 @@
<script lang="ts">
import { defineComponent } from 'vue'
import Complain from './complain.vue'
import Demand from './demand.vue'
export default defineComponent({
name: 'RightComponent',
components: { Complain },
components: { Complain, Demand },
})
</script>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment