master
xy 1 year ago
parent 9bb7eb1a58
commit 2131000b30

@ -14,6 +14,7 @@
"test:ci": "npm run lint && npm run test:unit"
},
"dependencies": {
"@jiaminghi/data-view": "^2.10.0",
"@smallwei/avue": "^2.9.15",
"axios": "0.18.1",
"core-js": "3.6.5",

@ -40,3 +40,11 @@ export function scheduleListSkus(params){
params
})
}
export function imports (data) {
return request({
method: "post",
url: "/api/admin/customer/import",
data
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

@ -107,6 +107,8 @@ Vue.prototype.$successMessage = (type,name) => {
message:`${word}${name}成功`
})
}
import dataV from "@jiaminghi/data-view";
Vue.use(dataV);
new Vue({
el: '#app',
router,

@ -41,19 +41,28 @@ export const constantRoutes = [{
component: () => import('@/views/404'),
hidden: true
},
{
path: '/bisscreen',
component: () => import('@/views/bigSreen'),
meta: {
title: '大屏展示',
icon: 'el-icon-data-board'
}
},
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [{
path: 'dashboard',
name: '系统首页',
component: () => import('@/views/dashboard/index'),
meta: {
title: '系统首页',
icon: 'dashboard'
children: [
{
path: 'dashboard',
name: '系统首页',
component: () => import('@/views/dashboard/index'),
meta: {
title: '系统首页',
icon: 'dashboard'
}
}
},
]
}
]

@ -18,5 +18,8 @@ const store = new Vuex.Store({
getters
})
store.dispatch('app/getVillageCodes')
function initVillage () {
store.dispatch('app/getVillageCodes')
}
initVillage()
export default store

@ -0,0 +1,112 @@
$word-color: #59d4fc;
$card-color: rgba(6, 34, 108, 0.55);
.color-word {
color: $word-color;
}
.color-white {
color: #fff;
}
//
.float-r {
float: right;
}
//
.float-l {
float: left;
}
//
.fw-b {
font-weight: bold;
}
//
.title-item {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
//flex
.d-flex {
display: flex;
}
.flex-column {
flex-direction: column;
}
.flex-wrap {
flex-wrap: wrap;
}
.flex-nowrap {
flex-wrap: nowrap;
}
.flex-1 {
flex: 1;
}
$flex-jc: (
start: flex-start,
end: flex-end,
center: center,
between: space-between,
around: space-around,
evenly: space-evenly,
);
$flex-ai: (
start: flex-start,
end: flex-end,
center: center,
stretch: stretch,
);
//
@each $var in (left, center, right) {
.text-#{$var} {
text-align: $var !important;
}
}
//flex
@each $key, $value in $flex-jc {
.jc-#{$key} {
justify-content: $value;
}
}
@each $key, $value in $flex-ai {
.ai-#{$key} {
align-items: $value;
}
}
.bs-card {
background: $card-color;
border-radius: 10px;
padding: 20px 25px;
&__title {
font-size: 24px;
font-weight: 500;
display: flex;
align-content: center;
&--text {
color: #59d4fc;
position: relative;
padding-left: 22px;
&::before {
content: "";
width: 12px;
height: 18px;
background: linear-gradient(to left, #499eee, #499eee);
clip-path: polygon(0 0,55% 0, 100% 50%, 55% 100%, 0 100%);
position: absolute;
left: 0;
top: calc(50% - 9px);
}
}
}
}

@ -0,0 +1,117 @@
<template>
<div class="bottom">
<div class="bs-card">
<div class="bs-card__title jc-between">
<p class="bs-card__title--text">医院</p>
<div class="color-white">
<span class="color-word">1</span>
<span>/</span>
<span>10</span>
</div>
</div>
<div class="bs-card__body">
<img src="@/assets/bigScreen/bkg.png" alt="">
<div class="img-title">常州武进中医院</div>
</div>
</div>
<div class="bs-card">
<div class="bs-card__title jc-between">
<p class="bs-card__title--text">物业</p>
<div class="color-white">
<span class="color-word">1</span>
<span>/</span>
<span>10</span>
</div>
</div>
<div class="bs-card__body">
<img src="@/assets/bigScreen/bkg.png" alt="">
<div class="img-title">常州武进中医院</div>
</div>
</div>
<div class="bs-card">
<div class="bs-card__title jc-between">
<p class="bs-card__title--text">分公司</p>
<div class="color-white">
<span class="color-word">1</span>
<span>/</span>
<span>10</span>
</div>
</div>
<div class="bs-card__body">
<img src="@/assets/bigScreen/bkg.png" alt="">
<div class="img-title">常州武进中医院</div>
</div>
</div>
<div class="bs-card">
<div class="bs-card__title jc-between">
<p class="bs-card__title--text">站点</p>
<div class="color-white">
<span class="color-word">1</span>
<span>/</span>
<span>10</span>
</div>
</div>
<div class="bs-card__body">
<img src="@/assets/bigScreen/bkg.png" alt="">
<div class="img-title">常州武进中医院</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {}
},
methods: {},
computed: {},
}
</script>
<style scoped lang="scss">
.bottom {
flex: 1;
display: flex;
justify-content: space-between;
padding: 0 30px;
margin: 25px 0;
.bs-card {
flex-basis: calc((100% - 30px * 3) / 4);
&__body {
width: 372px;
display: flex;
justify-content: center;
align-items: center;
margin-top: 10px;
position: relative;
& > img {
object-fit: cover;
width: 372px;
}
.img-title {
width: 100%;
line-height: 29px;
position: absolute;
left: 0;
bottom: 0;
font-size: 16px;
color: #ffffff;
text-align: center;
background-color: rgba(1, 16, 57, 0.8);
}
}
}
}
</style>

@ -0,0 +1,138 @@
<template>
<div class="ccenter">
<div class="top">
<div class="bs-card">
<div class="card-icon">
<img :src="require('@/assets/bigScreen/img1.png')" alt="">
</div>
<div class="card-text">
<p class="color-word">护工人数</p>
<p>
<span class="color-white fw-b" style="font-size: 42px;">10000</span>
<span class="color-word" style="padding-left: 5px">人次/</span>
</p>
</div>
</div>
<div class="bs-card">
<div class="card-icon">
<img :src="require('@/assets/bigScreen/img2.png')" alt="">
</div>
<div class="card-text">
<p class="color-word">服务驿站</p>
<p>
<span class="color-white fw-b" style="font-size: 42px;">658</span>
<span class="color-word" style="padding-left: 5px"></span>
</p>
</div>
</div>
<div class="bs-card">
<div class="card-icon">
<img :src="require('@/assets/bigScreen/img3.png')" alt="">
</div>
<div class="card-text">
<p class="color-word">总服务时长</p>
<p>
<span class="color-white fw-b" style="font-size: 42px;">10000</span>
<span class="color-word" style="padding-left: 5px">小时</span>
</p>
</div>
</div>
</div>
<div class="bottom">
<video ref="video">
<source src="https://highlight-video.cdn.bcebos.com/video/6s/fa06ca8e-536b-11ef-8efc-7cd30ab516e3.mp4">
</video>
<img class="video-btn" :src="require('@/assets/bigScreen/video-btn.png')" alt="" @click="playVideo">
</div>
</div>
</template>
<script>
export default {
data() {
return {
isPaused: true
}
},
methods: {
playVideo () {
if (this.$refs['video'].paused) {
this.isPaused = false;
this.$refs['video'].play()
} else {
this.isPaused = true;
this.$refs['video'].pause()
}
}
},
computed: {},
}
</script>
<style scoped lang="scss">
.ccenter {
display: flex;
flex-direction: column;
.top {
display: flex;
.bs-card {
flex: 1;
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px 15px;
.card-icon {
width: 62px;
height: 58px;
& > img {
object-fit: cover;
}
}
.card-text {
flex: 1;
padding-left: 10px;
font-size: 20px;
}
}
.bs-card + .bs-card {
margin-left: 20px;
}
}
.bottom {
margin-top: 30px;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
padding: 6px;
box-sizing: border-box;
background: conic-gradient(#5470ec, #506bec, #77cbf1, #3d58ca, #3b56ca, #6fbbf0, #6aa3f2);
position: relative;
video {
object-fit: cover;
position: absolute;
left: 6px;
bottom: 6px;
filter: brightness(65%);
height: calc(100% - 12px);
width: calc(100% - 12px);
}
.video-btn {
cursor: pointer;
width: 230px;
height: 230px;
position: absolute;
top: calc(50% - 115px);
left: calc(50% - 115px);
}
}
}
</style>

@ -0,0 +1,261 @@
<template>
<div class="center-left">
<div class="bs-card business-buy">
<div class="bs-card__title jc-between">
<p class="bs-card__title--text">
政府购买服务
</p>
<p>
<span class="color-word">658</span>
<span class="color-white">人次/每分钟</span>
</p>
</div>
<div class="business-buy__body">
<div class="digital">
<p class="digital-item">60%</p>
<p class="digital-item">18%</p>
<p class="digital-item">22%</p>
<img :src="require('@/assets/bigScreen/business-buy.png')" alt="">
</div>
<div class="progress">
<div class="progress-item" v-for="i in 3">
<svg viewBox="0 0 100 100" style="transform: rotate(-90deg)">
<path d="M 50 50 m 0 47a 47 47 0 1 1 0 -94a 47 47 0 1 1 0 94"
stroke="#f56c6c"
stroke-width="8"
fill="none"
style="stroke-dasharray: 5,4; stroke-dashoffset: -36.9137px;"></path>
<path d="M 50 50 m 0 47 a 47 47 0 1 1 0 -94 a 47 47 0 1 1 0 94"
stroke="#0e2168"
fill="none"
stroke-linecap="round"
stroke-width="8"
style="stroke-dasharray: 74.1482px, 295.31px; stroke-dashoffset: -36.9137px; transition: stroke-dasharray 0.6s, stroke 0.6s;"></path>
</svg>
<div class="progress-name">
长护
</div>
<div class="progress-rate">
30%
</div>
</div>
</div>
</div>
</div>
<div class="bs-card property">
<div class="bs-card__title jc-between">
<p class="bs-card__title--text">
物业
</p>
<div class="chart-legend">
<div class="chart-legend__item">
<div style="background: #00d9d5;"></div>
<p class="color-white">商业服务面积</p>
</div>
<div class="chart-legend__item">
<div style="background: linear-gradient(0deg, #e67725 0%, #ff9d62 100%);"></div>
<p class="color-white">住宅服务面积</p>
</div>
</div>
</div>
<div>
<div id="property-line-chart"></div>
</div>
</div>
</div>
</template>
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
export default {
data() {
return {}
},
methods: {
initChart() {
this.chart = echarts.init(document.querySelector('#property-line-chart'), 'macarons');
this.setOptions(this.chartData);
},
setOptions(chartdata) {
this.chart.setOption({
grid: {
top: 10,
left: '2%',
right: '3%',
bottom: '3%',
containLabel: true
},
xAxis: [{
type: 'value',
}],
yAxis: [{
type: 'category',
date: ['商业服务面积','住宅服务面积']
}],
series: [{
name: '商业服务面积',
type: 'bar',
barWidth: '30%',
data: [550],
itemStyle: {
color: "#00d9d5",
barBorderRadius: [0,4,4,0],
},
label: {
show: true,
position: 'right',
color: '#31abe3',
fontWeight: 'bold',
formatter: '{c}㎡'
},
animationDuration: 3000
},{
name: '住宅服务面积',
type: 'bar',
barWidth: '30%',
data: [550],
itemStyle: {
color: new echarts.graphic.LinearGradient(1, 0.5, 0, 0.5, [
{
offset: 0,
color: '#e67725'
},
{
offset: 1,
color: '#ff9d62'
}
]),
barBorderRadius: [0,4,4,0],
},
label: {
show: true,
position: 'right',
color: '#31abe3',
fontWeight: 'bold',
formatter: '{c}㎡'
},
animationDuration: 3000
}]
})
}
},
computed: {},
mounted() {
this.initChart()
}
}
</script>
<style scoped lang="scss">
.center-left {
display: flex;
flex-direction: column;
justify-content: space-between;
.business-buy {
height: 382px;
&__body {
.digital {
width: 205px;
height: 188px;
margin: auto;
position: relative;
& > img {
width: 205px;
height: 188px;
display: block;
}
&-item {
font-size: 20px;
color: #31abe3;
font-weight: bold;
z-index: 2;
position: absolute;
}
&-item:nth-child(1) {
top: 46%;
right: -36%;
}
&-item:nth-child(2) {
left: 50%;
bottom: 10%;
}
&-item:nth-child(3) {
left: -20%;
bottom: 0;
}
}
.progress {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 20px;
padding: 0 15px;
&-item {
width: 91px;
position: relative;
}
&-name {
color: #fff;
text-align: center;
width: 52px;
height: 20px;
border-radius: 10px;
background-color: #0052e9;
position: absolute;
bottom: 6px;
left: calc(50% - 26px);
}
&-rate {
color: #00deff;
font-size: 20px;
transform: translate(-50%, -50%);
position: absolute;
top: 50%;
left: 50%;
}
}
}
}
.property {
height: 243px;
.chart-legend {
display: flex;
&__item {
display: flex;
align-items: center;
margin-left: 18px;
& > div {
width: 18px;
height: 18px;
border-radius: 4px;
margin-right: 15px;
}
& > p {
font-size: 16px;
}
}
}
}
}
#property-line-chart {
height: 140px;
width: 388px;
}
</style>

@ -0,0 +1,799 @@
<template>
<div class="center-right">
<div class="bs-card business-serve">
<div class="bs-card__title jc-between">
<p class="bs-card__title--text">
商业化服务
</p>
</div>
<div>
<div id="business-serve-pie-chart"></div>
</div>
</div>
<div class="bs-card serve-map">
<div class="bs-card__title jc-between">
<p class="bs-card__title--text">
服务地图
</p>
</div>
<div>
<div id="serve-map-fly-line"></div>
</div>
</div>
</div>
</template>
<script>
import China from "echarts/map/json/china.json"
import echarts from 'echarts'
export default {
data() {
return {
}
},
methods: {
initFlyLine () {
this.flyLineChart = echarts.init(document.querySelector('#serve-map-fly-line'));
echarts.registerMap('china', China)
this.setFlyLineOptions(this.flyLineChartData);
},
setFlyLineOptions (chartdata) {
this.flyLineChart.setOption({
visualMap: {
show: false,
type: 'continuous',
calculable: true,
left: '0%',
bottom: '3%',
dimension: 0, // series.data series.data ,, data
seriesIndex: 1,
itemWidth: 15, //
itemHeight: 68,
min: 0,
// max: that.mapmax,
// color: ['#01fffd', '#1E74FF'],
// color: ['#0B64F3', '#1A05B8'],
color: ['#007EF9 ', '#0B275E'],
textStyle: {
color: '#ccc',
fontSize: 12
}
},
tooltip: {
//
enterable: true,
transitionDuration: 1,
textStyle: {
fontFamily: 'Microsoft YaHei',
color: '#b8c8e5',
fontSize: 13
},
backgroundColor: 'rgba(15,33,70,0.7)',
borderColor: 'rgba(54,82,132,0.7)',
borderWidth: 1,
padding: [10, 14],
extraCssText: 'z-index:4',
formatter: function (parma) {
if(parma.seriesType === 'effectScatter') {
return parma.name
} else {
return parma.name
}
}
},
legend: {
show: false,
color: ['#5bffde'],
icon: 'circle', //
top: '10.7%',
// bottom: '2.8%',
left: '2%',
itemGap: 22,
itemWidth: 8, //
textStyle: {
color: '#ffff',
fontSize: 14,
fontWeight: 'normal',
// align: "left",
padding: [0, 3],
fontFamily: 'Microsoft YaHei'
},
itemHeight: 8 //
},
geo: {
zoom: 1.22, //
top: '11%',
left: '20%',
show: true,
aspectScale: 0.85,
silent: true, //
animation: true,
map: 'china',
label: {
normal: {
show: false
},
emphasis: {
show: false
}
},
roam: false, //
// aspectScale: 1, //
//
regions: [
{
name: '南海诸岛',
itemStyle: {
//
normal: {
opacity: 0 // 0
}
},
label: {
show: false //
}
}
],
itemStyle: {
normal: {
// areaColor: '#122C69', // #415ef7
borderColor: '#122C69',
shadowColor: '#122C69',
shadowOffsetX: 1,
shadowOffsetY: 9
// borderWidth: 3,
},
emphasis: {
areaColor: '#4499d0'
}
}
},
series: [
{
name: '背景地图',
type: 'effectScatter',
coordinateSystem: 'geo',
symbolSize: function () {
return 8
},
// data: mapData,
data: [],
rippleEffect: {
period: 4,
scale: 1.5,
brushType: 'stroke'
},
label: {
normal: {
formatter: '{b}',
position: 'bottom',
show: false
},
emphasis: {
show: false
}
},
showEffectOn: 'render',
hoverAnimation: true,
itemStyle: {
normal: {
color: '#5bffde' //
},
label: {
show: false
},
//
// emphasis: {
// color: 'red'
// }
},
// select: {
// //
// itemStyle: {
// color: 'yellow'
// }
// },
zlevel: 1
},
{
//
type: 'map',
map: 'china',
zoom: 1.22, //
geoIndex: 1,
left: '20%',
top: '11%',
aspectScale: 0.85, //
showLegendSymbol: true, // legend
label: {
normal: {
show: false
},
emphasis: {
show: false,
textStyle: {
color: '#fff'
}
}
},
roam: false,
itemStyle: {
normal: {
color: 'none',
areaColor:'#dce5ee', //'#01032a',
borderColor: '#246BD2', // 4065eb
borderWidth: 1,
},
emphasis: {
areaColor: '#34d1fc'
}
},
select: {
//
label: {
color: '#fff'
},
itemStyle: {
areaColor: '#34d1fc'
}
},
animation: true,
data: []
// data: that.maparr
},
{
name: '大网点',
type: 'effectScatter',
coordinateSystem: 'geo',
symbolSize: function () {
return 14
},
data: [
{
name: '当前重点的地址名称',
value: {
visualMap: {
show: false,
type: 'continuous',
calculable: true,
left: '0%',
bottom: '3%',
dimension: 0, // series.data series.data ,, data
seriesIndex: 1,
itemWidth: 15, //
itemHeight: 68,
min: 0,
// max: that.mapmax,
// color: ['#01fffd', '#1E74FF'],
// color: ['#0B64F3', '#1A05B8'],
color: ['#007EF9 ', '#0B275E'],
textStyle: {
color: '#ccc',
fontSize: 12
}
},
tooltip: {
//
enterable: true,
transitionDuration: 1,
textStyle: {
fontFamily: 'Microsoft YaHei',
color: '#b8c8e5',
fontSize: 13
},
backgroundColor: 'rgba(15,33,70,0.7)',
borderColor: 'rgba(54,82,132,0.7)',
borderWidth: 1,
padding: [10, 14],
extraCssText: 'z-index:4',
formatter: function (parma) {
if(parma.seriesType === 'effectScatter') {
return parma.name
} else {
return parma.name
}
}
},
legend: {
show: false,
color: ['#5bffde'],
icon: 'circle', //
top: '10.7%',
// bottom: '2.8%',
left: '2%',
itemGap: 22,
itemWidth: 8, //
textStyle: {
color: '#ffff',
fontSize: 14,
fontWeight: 'normal',
// align: "left",
padding: [0, 3],
fontFamily: 'Microsoft YaHei'
},
itemHeight: 8 //
},
geo: {
zoom: 1.22, //
top: '11%',
left: '20%',
show: true,
aspectScale: 0.85,
silent: true, //
animation: true,
map: 'china',
label: {
normal: {
show: false
},
emphasis: {
show: false
}
},
roam: false, //
// aspectScale: 1, //
//
regions: [
{
name: '南海诸岛',
itemStyle: {
//
normal: {
opacity: 0 // 0
}
},
label: {
show: false //
}
}
],
itemStyle: {
normal: {
// areaColor: '#122C69', // #415ef7
borderColor: '#122C69',
shadowColor: '#122C69',
shadowOffsetX: 1,
shadowOffsetY: 9
// borderWidth: 3,
},
emphasis: {
areaColor: '#4499d0'
}
}
},
series: [
{
name: '接单网点',
type: 'effectScatter',
coordinateSystem: 'geo',
symbolSize: function () {
return 8
},
// data: mapData,
data: [],
rippleEffect: {
period: 4,
scale: 1.5,
brushType: 'stroke'
},
label: {
normal: {
formatter: '{b}',
position: 'bottom',
show: false
},
emphasis: {
show: false
}
},
showEffectOn: 'render',
hoverAnimation: true,
itemStyle: {
normal: {
color: '#5bffde' //
},
label: {
show: false
},
//
// emphasis: {
// color: 'red'
// }
},
// select: {
// //
// itemStyle: {
// color: 'yellow'
// }
// },
zlevel: 1
},
{
//
type: 'map',
map: 'china',
zoom: 1.22, //
geoIndex: 1,
left: '20%',
top: '11%',
aspectScale: 0.85, //
showLegendSymbol: true, // legend
label: {
normal: {
show: false
},
emphasis: {
show: false,
textStyle: {
color: '#fff'
}
}
},
roam: false,
itemStyle: {
normal: {
color: 'none',
areaColor:'#122C69', //'#01032a',
borderColor: '#246BD2', // 4065eb
borderWidth: 1
},
emphasis: {
areaColor: '#34d1fc'
}
},
select: {
//
label: {
color: '#fff'
},
itemStyle: {
areaColor: '#34d1fc'
}
},
animation: true,
data: []
// data: that.maparr
},
{
name: '网点',
type: 'effectScatter',
coordinateSystem: 'geo',
symbolSize: function () {
return 14
},
data: [
{
name: '终点名称-广东',
value: ['113.746262', '23.046237'] //
}
],
rippleEffect: {
period: 4,
scale: 1.5,
brushType: 'stroke'
},
label: {
normal: {
formatter: '{b}',
position: 'bottom',
show: false
},
emphasis: {
show: false
}
},
showEffectOn: 'render',
hoverAnimation: true,
itemStyle: {
normal: {
color: '#5bffde' //
},
label: {
show: false
},
//
// emphasis: {
// color: 'red'
// }
},
// select: {
// //
// itemStyle: {
// color: 'yellow'
// }
// },
zlevel: 2
},
{
type: 'lines',
zlevel: 1,
effect: {
show: true,
period: 6, //
trailLength: 0.02, //[0,1]
symbol: 'arrow', //
symbolSize: 6 //
},
label: {
emphasis: {
show: false
}
},
lineStyle: {
normal: {
width: 1, //线
color: '#27C7E9',
opacity: 1, //线
curveness: 0.3 //线
}
},
data: []
}
]
}
}
],
rippleEffect: {
period: 4,
scale: 1.5,
brushType: 'stroke'
},
label: {
normal: {
formatter: '{b}',
position: 'bottom',
show: false
},
emphasis: {
show: false
}
},
showEffectOn: 'render',
hoverAnimation: true,
itemStyle: {
normal: {
color: '#5bffde' //
},
label: {
show: false
},
//
// emphasis: {
// color: 'red'
// }
},
// select: {
// //
// itemStyle: {
// color: 'yellow'
// }
// },
zlevel: 2
},
{
type: 'lines',
zlevel: 1,
effect: {
show: true,
period: 6, //
trailLength: 0.02, //[0,1]
symbol: 'arrow', //
symbolSize: 6 //
},
label: {
emphasis: {
show: false
}
},
lineStyle: {
normal: {
width: 1, //线
color: '#27C7E9',
opacity: 1, //线
curveness: 0.3 //线
}
},
data: [
[
{ //
coord:['119.946973', '31.772752'],
value: "0000100101"
},
{
coord: ['113.746262', '23.046237'] // 广
}
],
[
{ //
coord:['119.946973', '31.772752'],
value: "0000100101"
},
{
coord: ['113.746262', '23.046237'] // 广
}
]
]
}
]
})
},
initChart() {
this.chart = echarts.init(document.querySelector('#business-serve-pie-chart'));
this.setOptions(this.chartData);
},
setOptions() {
this.chart.setOption({
title: {
show: false,
},
tooltip: {
trigger: 'item'
},
visualMap: {
show: false,
min: 60,
max: 600,
inRange: {
colorLightness: [0, 1]
}
},
series: [
{
type: 'pie',
radius: '60%',
center: ['50%', '50%'],
data: [
{
value: 550,
name: '居家照护',
itemStyle: {
color: new echarts.graphic.RadialGradient(0.5, 0.5, 1, [
{
offset: 0,
color: '#7a2cf5'
},
{
offset: 1,
color: '#b274f7'
}
])
}
},
{
value: 510,
name: '陪诊',
itemStyle: {
color: new echarts.graphic.RadialGradient(0.5, 0.5, 1, [
{
offset: 0,
color: '#53a2c1'
},
{
offset: 1,
color: '#6fe8fb'
}
])
}
},
{
value: 510,
name: '问诊',
itemStyle: {
color: new echarts.graphic.RadialGradient(0.5, 0.5, 1, [
{
offset: 0,
color: '#81bf3b'
},
{
offset: 1,
color: '#6be04a'
}
])
}
},
{
value: 620,
name: '个性化服务',
itemStyle: {
color: new echarts.graphic.RadialGradient(0.5, 0.5, 1, [
{
offset: 0,
color: '#ad862e'
},
{
offset: 1,
color: '#dfb43f'
}
])
}
},
{
value: 580,
name: '医院陪护',
itemStyle: {
color: new echarts.graphic.RadialGradient(0.5, 0.5, 1, [
{
offset: 0,
color: '#2238ed'
},
{
offset: 1,
color: '#3779f0'
}
])
}
}
].sort(function (a, b) {
return a.value - b.value;
}),
roseType: 'radius',
label: {
color: '#fff',
formatter: '{b} \n {c}个{d}%'
},
labelLine: {
lineStyle: {
color: '#71e8fc'
},
smooth: 0.2,
length: 10,
length2: 20
},
itemStyle: {
normal: {
shadowBlur: 100,
// shadowColor: 'rgba(0, 0, 0, 0.2)'
}
},
animationType: 'scale',
animationEasing: 'elasticOut',
animationDelay: function (idx) {
return Math.random() * 200;
}
}
]
})
}
},
computed: {},
mounted() {
this.initChart()
this.initFlyLine()
}
}
</script>
<style scoped lang="scss">
.center-right {
display: flex;
flex-direction: column;
justify-content: space-between;
.business-serve {
height: 382px;
#business-serve-pie-chart {
width: 100%;
height: 300px;
}
}
.serve-map {
height: 243px;
#serve-map-fly-line {
height: 170px;
}
}
}
</style>

@ -0,0 +1,62 @@
<template>
<div class="top">
<img class="title-img" :src="require('@/assets/bigScreen/title.png')" alt="">
<div class="line">
<img :src="require('@/assets/bigScreen/line.png')" alt="">
</div>
</div>
</template>
<script>
export default {
data() {
return {}
},
methods: {},
computed: {},
}
</script>
<style scoped lang="scss">
.top {
flex: 0;
height: calc(28px + 72px + 18px);
position: relative;
}
.title-img {
height: 72px;
width: 477px;
margin: 0 auto;
display: block;
}
.line {
left: 0;
right: 0;
bottom: 0;
position: absolute;
&::before {
content: "";
height: 3px;
background: linear-gradient(to right, #334067, #4f5a7c);
position: absolute;
left: 0;
top: 0;
width: 31%;
}
&::after {
content: "";
height: 3px;
background: linear-gradient(to right, #28376c, #9bbbe5);
filter: drop-shadow(0 -1px 2px #204fd6);
position: absolute;
right: 0;
top: 0;
width: 32.1%;
}
& > img {
height: 100%;
}
}
</style>

@ -0,0 +1,76 @@
<template>
<div id="big-screen">
<div ref="appRef" class="container">
<top></top>
<div class="center">
<CenterLeft style="grid-area: left"></CenterLeft>
<Center style="grid-area: center;"></Center>
<CenterRight style="grid-area: right;"></CenterRight>
</div>
<Bottom></Bottom>
</div>
</div>
</template>
<script>
import drawMixin from './mixin'
import top from './component/top.vue'
import CenterLeft from "./component/CenterLeft.vue";
import Center from "./component/Center.vue";
import CenterRight from "./component/CenterRight.vue";
import Bottom from "./component/Bottom.vue";
export default {
mixins: [drawMixin],
components: {
top,
CenterLeft,
Center,
CenterRight,
Bottom
},
data() {
return {}
},
methods: {},
computed: {},
}
</script>
<style lang="scss">
@import "~@/styles/bigscreen.scss";
</style>
<style scoped lang="scss">
#big-screen {
width: 100vw;
height: 100vh;
position: relative;
background: url("~@/assets/bigScreen/bkg.png") no-repeat;
background-size: cover;
overflow: hidden;
.container {
width: 1920px;
height: 1080px;
transform-origin: 0 0;
display: flex;
flex-direction: column;
position: relative;
top: 50%;
left: 50%;
.center {
flex: 0;
height: 648px;
display: grid;
grid-template-areas: "left center center right";
grid-template-columns: repeat(4, 1fr);
grid-column-gap: 30px;
padding: 0 30px;
margin-top: 25px;
}
}
}
</style>

@ -0,0 +1,57 @@
// 屏幕适配 mixin 函数
// * 默认缩放值
const scale = {
width: '1',
height: '1',
}
// * 设计稿尺寸px
const baseWidth = 1920
const baseHeight = 1080
// * 需保持的比例默认1.77778
const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5))
export default {
data() {
return {
// * 定时函数
drawTiming: null
}
},
mounted () {
this.calcRate()
window.addEventListener('resize', this.resize)
},
beforeDestroy () {
window.removeEventListener('resize', this.resize)
},
methods: {
calcRate () {
const appRef = this.$refs["appRef"]
if (!appRef) return
// 当前宽高比
const currentRate = parseFloat((window.innerWidth / window.innerHeight).toFixed(5))
if (appRef) {
if (currentRate > baseProportion) {
// 表示更宽
scale.width = ((window.innerHeight * baseProportion) / baseWidth).toFixed(5)
scale.height = (window.innerHeight / baseHeight).toFixed(5)
appRef.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)`
} else {
// 表示更高
scale.height = ((window.innerWidth / baseProportion) / baseHeight).toFixed(5)
scale.width = (window.innerWidth / baseWidth).toFixed(5)
appRef.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)`
}
}
},
resize () {
clearTimeout(this.drawTiming)
this.drawTiming = setTimeout(() => {
this.calcRate()
}, 200)
}
},
}

@ -107,7 +107,7 @@
<!-- </div>-->
<!-- </template>-->
<template #village_code>
<template v-slot:village_code>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>区域
@ -477,12 +477,6 @@ export default {
message: '身份证格式错误'
}
],
// contact_name: [
// {required: true, message: ''}
// ],
// contact_phone: [
// {validator: validatePhone}
// ],
idcard_address: [
{required: true, message: '请填写户籍地址'},
],
@ -496,7 +490,15 @@ export default {
{validator: validateProductType}
],
village_code: [
{required: true, message: '请选择区域'},
{
validator:(rule,value,callback) => {
if (this.form.village_code) {
callback()
} else {
callback(new Error('请选择区域'))
}
}
},
],
},
map: [],
@ -571,7 +573,6 @@ export default {
account_id:'',
status: 0,
customer_id: '',
village_code: '',
},
rules1: {
customer_id:[
@ -639,7 +640,6 @@ export default {
account_id:'',
status: 0,
customer_id: '',
village_code: '',
}
},
areaPick(e){

@ -0,0 +1,165 @@
<template>
<div>
<el-dialog :visible.sync="dialogVisible" title="数据导入" width="70%">
<div class="title">模板下载</div>
<el-button
style="margin-top: 10px"
size="small"
type="primary"
@click="exportExcel(new Date().getTime().toString())"
>模板下载
</el-button
>
<div style="color: red; margin-top: 10px">
导入的时候请勿修改模版的标题名称
</div>
<el-upload
style="margin-top: 10px"
drag
:action="action"
:headers="{
Authorization: `Bearer ${getToken()}`,
}"
:on-success="uploadSuccess"
:on-error="uploadFail"
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">只能上传xls/xlsx文件</div>
</el-upload>
<div class="title" style="margin-top: 10px;">数据预览</div>
<xy-table :is-page="false" :height="300" :list="tableList" :table-item="formInfo" style="margin-top: 10px;">
<template #btns></template>
</xy-table>
<div style="font-size: 12px;zoom: 0.8;">总共数据{{ tableList.length }}</div>
<el-button type="primary" size="small" style="margin-top: 10px;" @click="imports"></el-button>
</el-dialog>
</div>
</template>
<script>
import * as XLSX from "xlsx";
import {saveAs} from "file-saver";
import {getToken} from "@/utils/auth";
import {imports} from "@/api/customer";
export default {
props: {
formInfo: {
type: Array,
default: () => [
{
label: "名字",
width: "180",
prop: "name"
},
{
label: "性别",
prop: "sex",
width: 100,
},
{
prop: "idcard",
label: "身份证号",
width: "220",
},
{
prop: "phone",
label: "手机号",
width: "160",
},
],
},
},
data() {
return {
action: `${process.env.VUE_APP_BASE_API}api/admin/customer/excel-show`,
dialogVisible: false,
headers: [],
tableList: [],
table: [],
};
},
methods: {
getToken,
show() {
this.dialogVisible = true;
},
hidden() {
this.dialogVisible = false;
},
//
uploadFail(err) {
console.log(err);
this.$message({
message: "上传失败",
type: "error",
});
},
uploadSuccess(response) {
this.tableList = response;
this.$message({
message: `上传成功`,
type: "success",
});
},
exportExcel(sheetName) {
const data = [this.formInfo.map((header) => header.label).slice(2)];
console.log(data)
const wb = XLSX.utils.book_new();
const ws = XLSX.utils.aoa_to_sheet(data);
XLSX.utils.book_append_sheet(wb, ws, sheetName);
const wbout = XLSX.write(wb, {
bookType: "xlsx",
bookSST: true,
type: "array",
});
saveAs(
new Blob([wbout], {type: "application/octet-stream"}),
`${sheetName}.xlsx`
);
},
imports() {
imports({
data: this.tableList
}).then(res => {
console.log(res)
this.$message({
type: 'success',
message: `成功导入${res.total}`
})
})
this.hidden();
this.$emit('refresh')
}
},
computed: {},
};
</script>
<style scoped lang="scss">
.title {
font-size: 15px;
font-weight: 600;
padding: 8px 4px;
position: relative;
&::before {
content: '';
width: 4px;
background: $primaryColor;
position: absolute;
top: 8px;
bottom: 8px;
left: -8px;
}
}
</style>

@ -88,6 +88,7 @@
}">
取消选择
</Button>
<Button type="primary" style="margin-left: 10px" @click="$refs['imports'].show()"></Button>
</div>
</slot>
</lx-header>
@ -202,6 +203,7 @@
:disability-level="disabilityLevel"
@refresh="getCustomers"
></add-customer>
<imports ref="imports" @refresh="getCustomers"></imports>
</div>
</template>
@ -216,10 +218,12 @@ import { getAuthAreas, getAuthTypes } from "@/utils/auth";
import addCustomer from "@/views/customer/component/addCustomer";
import addOrder from "./component/addOrder";
import imports from "./component/imports.vue"
export default {
components: {
addCustomer,
addOrder,
imports
},
data() {
return {
@ -232,6 +236,7 @@ export default {
page_size: 10,
keyword: "",
village_name: "",
is_auth: 1
},
disabilityLevel: [],
levelTypes: [],

@ -1,242 +1,243 @@
<template>
<div class="login-container">
<vue-particles color="#ffffff" :particleOpacity="0.7" :particlesNumber="80" shapeType="circle" :particleSize="4"
linesColor="#ffffff" :linesWidth="1" :lineLinked="true" :lineOpacity="0.4" :linesDistance="150" :moveSpeed="3"
:hoverEffect="true" hoverMode="grab" :clickEffect="true" clickMode="push"> </vue-particles>
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on"
label-position="left">
<div class="title-container">
<h3 class="title">四世同堂业务管理系统</h3>
</div>
<el-form-item prop="username">
<span class="svg-container">
<svg-icon icon-class="user" />
</span>
<el-input ref="username" v-model="loginForm.username" placeholder="请输入登录名" name="username" type="text"
tabindex="1" auto-complete="on" />
</el-form-item>
<el-form-item prop="password">
<span class="svg-container">
<svg-icon icon-class="password" />
</span>
<el-input :key="passwordType" ref="password" v-model="loginForm.password" :type="passwordType"
placeholder="请输入密码" name="password" tabindex="2" auto-complete="on" @keyup.enter.native="handleLogin" />
<span class="show-pwd" @click="showPwd">
<svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
</span>
</el-form-item>
<el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;"
@click.native.prevent="handleLogin">登录</el-button>
</el-form>
</div>
</template>
<script>
import {
validUsername
} from '@/utils/validate'
export default {
name: 'Login',
data() {
const validateUsername = (rule, value, callback) => {
if (!validUsername(value)) {
callback(new Error('请正确输入登录名'))
} else {
callback()
}
}
const validatePassword = (rule, value, callback) => {
if (value.length < 6) {
callback(new Error('密码输入错误'))
} else {
callback()
}
}
return {
loginForm: {
username: '',
password: ''
},
loginRules: {
username: [{
required: true,
trigger: 'blur',
validator: validateUsername
}],
password: [{
required: true,
trigger: 'blur',
validator: validatePassword
}]
},
loading: false,
passwordType: 'password',
redirect: undefined
}
},
watch: {
$route: {
handler: function(route) {
this.redirect = route.query && route.query.redirect
},
immediate: true
}
},
methods: {
showPwd() {
if (this.passwordType === 'password') {
this.passwordType = ''
} else {
this.passwordType = 'password'
}
this.$nextTick(() => {
this.$refs.password.focus()
})
},
handleLogin() {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true
this.$store.dispatch('user/login', this.loginForm).then(() => {
this.$router.push({
path: this.redirect || '/'
})
this.loading = false
}).catch(() => {
this.loading = false
})
} else {
console.log('error submit!!')
return false
}
})
}
}
}
</script>
<style lang="scss">
#particles-js {
width: 100%;
height: 100%;
position: absolute;
}
/* 修复input 背景不协调 和光标变色 */
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
$bg:#122583;
$light_gray:#122583;
$cursor: #122583;
@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
.login-container .el-input input {
color: $cursor;
}
}
/* reset element-ui css */
.login-container {
.el-input {
display: inline-block;
height: 47px;
width: 85%;
input {
background: transparent;
border: 0px;
-webkit-appearance: none;
border-radius: 0px;
padding: 12px 5px 12px 15px;
color: $light_gray;
height: 47px;
caret-color: $cursor;
}
}
.el-form-item {
border: 1px solid rgba(255, 255, 255, 0.1);
background: rgba(0, 0, 0, 0.1);
border-radius: 5px;
color: #454545;
}
}
</style>
<style lang="scss" scoped>
$bg:#122583;
$dark_gray:#122583;
$light_gray:#122583;
.login-container {
min-height: 100%;
width: 100%;
//background-color: $bg;
background: url("../../assets/bg.jpg") no-repeat;
overflow: hidden;
.login-form {
position: relative;
width: 520px;
max-width: 100%;
padding: 20px 35px 0;
margin: 160px auto;
overflow: hidden;
background-color: #fff;
}
.tips {
font-size: 14px;
color: #fff;
margin-bottom: 10px;
span {
&:first-of-type {
margin-right: 16px;
}
}
}
.svg-container {
padding: 6px 5px 6px 15px;
color: $dark_gray;
vertical-align: middle;
width: 30px;
display: inline-block;
}
.title-container {
position: relative;
.title {
font-size: 26px;
color: $light_gray;
margin: 0px auto 40px auto;
text-align: center;
font-weight: bold;
}
}
.show-pwd {
position: absolute;
right: 10px;
top: 7px;
font-size: 16px;
color: $dark_gray;
cursor: pointer;
user-select: none;
}
<template>
<div class="login-container">
<vue-particles color="#ffffff" :particleOpacity="0.7" :particlesNumber="80" shapeType="circle" :particleSize="4"
linesColor="#ffffff" :linesWidth="1" :lineLinked="true" :lineOpacity="0.4" :linesDistance="150" :moveSpeed="3"
:hoverEffect="true" hoverMode="grab" :clickEffect="true" clickMode="push"> </vue-particles>
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on"
label-position="left">
<div class="title-container">
<h3 class="title">四世同堂业务管理系统</h3>
</div>
<el-form-item prop="username">
<span class="svg-container">
<svg-icon icon-class="user" />
</span>
<el-input ref="username" v-model="loginForm.username" placeholder="请输入登录名" name="username" type="text"
tabindex="1" auto-complete="on" />
</el-form-item>
<el-form-item prop="password">
<span class="svg-container">
<svg-icon icon-class="password" />
</span>
<el-input :key="passwordType" ref="password" v-model="loginForm.password" :type="passwordType"
placeholder="请输入密码" name="password" tabindex="2" auto-complete="on" @keyup.enter.native="handleLogin" />
<span class="show-pwd" @click="showPwd">
<svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
</span>
</el-form-item>
<el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;"
@click.native.prevent="handleLogin">登录</el-button>
</el-form>
</div>
</template>
<script>
import {
validUsername
} from '@/utils/validate'
import store from "@/store";
export default {
name: 'Login',
data() {
const validateUsername = (rule, value, callback) => {
if (!validUsername(value)) {
callback(new Error('请正确输入登录名'))
} else {
callback()
}
}
const validatePassword = (rule, value, callback) => {
if (value.length < 6) {
callback(new Error('密码输入错误'))
} else {
callback()
}
}
return {
loginForm: {
username: '',
password: ''
},
loginRules: {
username: [{
required: true,
trigger: 'blur',
validator: validateUsername
}],
password: [{
required: true,
trigger: 'blur',
validator: validatePassword
}]
},
loading: false,
passwordType: 'password',
redirect: undefined
}
},
watch: {
$route: {
handler: function(route) {
this.redirect = route.query && route.query.redirect
},
immediate: true
}
},
methods: {
showPwd() {
if (this.passwordType === 'password') {
this.passwordType = ''
} else {
this.passwordType = 'password'
}
this.$nextTick(() => {
this.$refs.password.focus()
})
},
handleLogin() {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true
this.$store.dispatch('user/login', this.loginForm).then(() => {
this.$store.dispatch('app/getVillageCodes')
this.$router.push({
path: this.redirect || '/'
})
this.loading = false
}).catch(() => {
this.loading = false
})
} else {
console.log('error submit!!')
return false
}
})
}
}
}
</script>
<style lang="scss">
#particles-js {
width: 100%;
height: 100%;
position: absolute;
}
/* 修复input 背景不协调 和光标变色 */
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
$bg:#122583;
$light_gray:#122583;
$cursor: #122583;
@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
.login-container .el-input input {
color: $cursor;
}
}
/* reset element-ui css */
.login-container {
.el-input {
display: inline-block;
height: 47px;
width: 85%;
input {
background: transparent;
border: 0px;
-webkit-appearance: none;
border-radius: 0px;
padding: 12px 5px 12px 15px;
color: $light_gray;
height: 47px;
caret-color: $cursor;
}
}
.el-form-item {
border: 1px solid rgba(255, 255, 255, 0.1);
background: rgba(0, 0, 0, 0.1);
border-radius: 5px;
color: #454545;
}
}
</style>
<style lang="scss" scoped>
$bg:#122583;
$dark_gray:#122583;
$light_gray:#122583;
.login-container {
min-height: 100%;
width: 100%;
//background-color: $bg;
background: url("../../assets/bg.jpg") no-repeat;
overflow: hidden;
.login-form {
position: relative;
width: 520px;
max-width: 100%;
padding: 20px 35px 0;
margin: 160px auto;
overflow: hidden;
background-color: #fff;
}
.tips {
font-size: 14px;
color: #fff;
margin-bottom: 10px;
span {
&:first-of-type {
margin-right: 16px;
}
}
}
.svg-container {
padding: 6px 5px 6px 15px;
color: $dark_gray;
vertical-align: middle;
width: 30px;
display: inline-block;
}
.title-container {
position: relative;
.title {
font-size: 26px;
color: $light_gray;
margin: 0px auto 40px auto;
text-align: center;
font-weight: bold;
}
}
.show-pwd {
position: absolute;
right: 10px;
top: 7px;
font-size: 16px;
color: $dark_gray;
cursor: pointer;
user-select: none;
}
}
</style>

@ -65,6 +65,7 @@
ref="newElTree"
node-key="code"
lazy
:check-strictly="true"
show-checkbox
:props="{
label: 'name',
@ -132,15 +133,15 @@ export default {
checkNewTreeNodes (level = 0) {
this.$nextTick(() => {
if (level === 0) {
this.$refs['newElTree'].setCheckedKeys([])
}
// if (level === 0) {
// this.$refs['newElTree'].setCheckedKeys([])
//
// }
let user = this.users.find(i => i.id == this.activeUser)
if (user && user.village) {
let village = new Map()
user.village.filter(i => i.level === level+1).forEach(item => {
user.village.forEach(item => {
village.set(item.village_code,item)
})
this.$refs['newElTree'].setCheckedKeys([...village.values()].map(i => Number(i.village_code)))

Loading…
Cancel
Save