This commit is contained in:
lnn19986213 2023-12-28 16:09:04 +08:00
parent cbad1a4f1c
commit 4a15baa22c
87 changed files with 25272 additions and 3410 deletions

View File

@ -14,12 +14,17 @@
"core-js": "3.15.2",
"cropperjs": "1.5.12",
"crypto-js": "4.0.0",
"dayjs": "^1.11.10",
"echarts": "5.1.2",
"echarts-liquidfill": "^3.1.0",
"echarts-wordcloud": "^2.1.0",
"element-plus": "1.0.2-beta.54",
"html2canvas": "^1.4.1",
"mapv-three": "^1.0.9",
"nprogress": "0.2.0",
"qrcodejs2": "^0.0.2",
"sortablejs": "1.13.0",
"swiper": "^8.4.5",
"tinymce": "5.8.2",
"vue": "3.1.4",
"vue-router": "4.0.10",
@ -28,11 +33,14 @@
"vuex": "4.0.2"
},
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@vue/cli-plugin-babel": "4.5.13",
"@vue/cli-plugin-eslint": "4.5.13",
"@vue/cli-service": "4.5.13",
"@vue/compiler-sfc": "3.1.4",
"babel-eslint": "10.1.0",
"cache-loader": "^4.1.0",
"eslint": "6.8.0",
"eslint-plugin-vue": "7.12.1",
"less": "3.13.1",
@ -57,7 +65,8 @@
"indent": 0,
"no-tabs": 0,
"no-mixed-spaces-and-tabs": 0,
"vue/no-unused-components": "off"
"vue/no-unused-components": "off",
"no-unused-vars": "off"
}
},
"browserslist": [

View File

@ -6,6 +6,10 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>static/img/favicon.ico">
<script
type="text/javascript"
src="//api.map.baidu.com/api?type=webgl&v=1.0&ak=k9luQNMq1GwExcPKOEusTniNUfcV49S3"
></script>
<title>
艺象心后台管理系统
</title>

1
src/assets/css/theme.css Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"version":3,"sources":["../theme/theme.less"],"names":[],"mappings":"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"}

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/assets/img/ball.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

BIN
src/assets/img/bg_ball.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
src/assets/img/bg_cb.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/assets/img/bg_cbg.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

BIN
src/assets/img/bg_ct.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/assets/img/bg_ms1.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

BIN
src/assets/img/bg_ms2.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
src/assets/img/bg_ms3.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
src/assets/img/bg_ms4.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
src/assets/img/bg_ms5.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
src/assets/img/bg_mt.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
src/assets/img/cbmb.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
src/assets/img/cbmi.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1010 B

BIN
src/assets/img/close.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 750 B

BIN
src/assets/img/elb.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
src/assets/img/eval_t1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/assets/img/eval_t2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 984 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
src/assets/img/icon/j.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/assets/img/icon/j2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/assets/img/icon/l.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
src/assets/img/icon/l2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
src/assets/img/icon/s.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/assets/img/icon/s2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/assets/img/icon/w.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
src/assets/img/icon/w2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/assets/img/icon_bg.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
src/assets/img/light.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
src/assets/img/lwt1.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
src/assets/img/lwt11.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
src/assets/img/lwt2.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
src/assets/img/lwt22.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
src/assets/img/lwt3.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
src/assets/img/lwt33.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
src/assets/img/lwt4.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
src/assets/img/lwt44.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
src/assets/img/lwt5.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
src/assets/img/lwt55.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
src/assets/img/lwt_bg.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
src/assets/img/pics/1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

BIN
src/assets/img/pics/2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

BIN
src/assets/img/pics/3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

BIN
src/assets/img/pics/4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

BIN
src/assets/img/rate_bg.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/assets/img/top1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

BIN
src/assets/img/w_ib.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

13944
src/assets/map/330225.json Normal file

File diff suppressed because it is too large Load Diff

590
src/assets/theme/theme.less Normal file
View File

@ -0,0 +1,590 @@
// ant默认样式修改
@link-color: #cff; //链接颜色
@lightColor:#cff; //浅色
@darkColor:hsla(0, 0%, 100%, 0.65); //深色
@antFontColor:#85b1bf !important; //灰色文字
@antBg:rgba(21,46,62,.9) !important; //黑色背景
@antBorder:1px solid #02739d !important; //黑色边框
//自定颜色
@listIconfontP:22px; //list-icon图标列表的p标签(数据)的文字大小
@listItemHeight:36px; //列表的高度
@pColor:#cff; //文本颜色
// foot的默认height为90px,两侧默认高度lrHeight为900px,中间cHeight为790px
@fontHeight: 90px;
@lrHeight: 900px + @fontHeight;
@cHeight: 790px + @fontHeight;
.chart{
width: 100%;
height: 100%;
}
.flex-c{
display:flex;
flex-direction:column
}
.flex-r{
display:flex;
flex-direction:row
}
.flex-1{
flex:1 !important
}
.flex-2{
flex:2 !important
}
.flex-3{
flex:3 !important
}
.flex-4{
flex:4 !important
}
.flex-5{
flex:5 !important
}
.flex-6{
flex:6 !important
}
.flex-7{
flex:7 !important
}
.flex-8{
flex:8 !important
}
.flex-9{
flex:9 !important
}
.flex-10{
flex:10 !important
}
* {
padding: 0;
margin: 0;
text-decoration: none;
list-style: none;
outline: none;
border: none;
user-select: none;
box-sizing: border-box;
@font-face {
font-family: dsFont;
src:url(../font/DS-DIGIT.TTF);
}
@font-face {
font-family: dyFont;
src: url(../font/douyuFont.otf);
}
}
body{
overflow: hidden;
&::-webkit-scrollbar{
width:0px;
height:0px;
overflow:hidden;
}
}
.scrollBar{
overflow: auto;
&::-webkit-scrollbar{
width: 3px;
height: 1px;
right: -5px;
&-thumb{
border-radius: 4px;
box-shadow: inset 0 0 5px rgb(0 0 0 / 20%);
background: #44909d;
}
&-track{
box-shadow: inset 0 0 5px rgb(0 0 0 / 20%);
border-radius: 4px;
background: rgba(36, 119, 130,.5);
}
}
}
// commonBox的css ↓
@keyframes one{
0%{
left:-100%
}
50%,
100%{
left:100%
}
}
@keyframes two{
0%{
top:-100%
}
50%,
100%{
top:100%
}
}
@keyframes three{
0%{
right:-100%
}
50%,
100%{
right:100%
}
}
@keyframes four{
0%{
bottom:-100%
}
50%,
100%{
bottom:100%
}
}
.commonBox{
display: flex;
flex-direction: column;
position: relative;
overflow: hidden;
&::before,&::after{
content: "";
position: absolute;
width: 100%;
height: 1px;
}
&::before{
top: 0;
left: -100%;
background-image: linear-gradient(90deg,transparent,#03e9f4);
animation: one 6s linear infinite;
}
&::after{
bottom: 0;
right: -100%;
background-image: linear-gradient(-90deg,transparent,#03e9f4);
animation: three 6s linear 2s infinite;
}
>i{
position: absolute;
display: inline-block;
height: 100%;
width: 1px;
&:first-child{
top: -100%;
right: 0;
background-image: linear-gradient(180deg,transparent,#03e9f4);
animation: two 6s linear 1s infinite;
}
&:nth-child(2){
bottom: -100%;
left: 0;
background-image: linear-gradient(1turn,transparent,#03e9f4);
animation: four 6s linear 3s infinite;
}
}
&-header{
@height:48px;
flex-basis: @height;
margin: 1px 1px 0;
display: flex;
align-items: center;
justify-content: center;
position: relative;
>span{
height: @height;
line-height: @height;
font-size: 18px;
font-family: dyFont;
font-weight: 400;
color: #fff;
padding: 4px 7px 0;
box-sizing: border-box;
}
>img{
width: 26px;
height: 26px;
&:nth-of-type(2){
transform: rotate(180deg);
}
}
.commonBox-more{
@height:40px;
position: absolute;
top: -7%;
right: 10px;
display: block;
height: @height;
line-height: @height+5;
background: url(../img/cbmb.webp) no-repeat 0/100% 100%;
cursor: pointer;
img{
width: 18px;
height: 18px;
margin: 0 6px;
}
span{
vertical-align: middle;
padding-right: 10px;
}
}
}
&-contain{
flex: 1;
display: flex;
flex-direction: column;
.commonBox-menu{
flex-basis: 24px;
}
.commonBox-item{
flex: 1;
display: flex;
}
}
}
//ant组件样式修改
.commonBox{
.commonBox-menu{
margin: 8px 10px;
//radio菜单面板
.ant-radio-button-wrapper{
background: rgba(0,198,255,.08);
border: none;
span{
background: rgba(0,198,255,.08);
color: hsla(0,0%,100%,.65);
display: inline-block;
padding: 0 8px;
height: 100%;
}
&-checked{
background: rgba(0,198,255,.85);
span{
color: #fff;
}
}
&:focus-within{
box-shadow:none;
}
&:not(:first-child){
&::before{
display: none;
}
}
}
//select下拉选择
.ant-select{
position: absolute;
right: 10px;
&:not(.ant-select-customize-input){
.ant-select-selector{
background: none;
border: @antBorder;
&:hover{
border-color: #ccffff;
-webkit-box-shadow: none;
box-shadow: none;
}
}
}
.ant-select-arrow{
color: @antFontColor;
}
&-selector{
span{
color: @antFontColor;
font-size: 13px;
}
}
.ant-select-focused:not(.ant-select-disabled).ant-select:not(.ant-select-customize-input){
.ant-select-selector {
border-color: #ccffff;
-webkit-box-shadow: none;
box-shadow: none;
}
}
}
//日期选项框
.ant-picker{
color:@antFontColor;
background: @antBg;
border: @antBorder;
padding: 3px 11px 3px !important;
width: 80px !important;
position: absolute !important;
right: 10px;
//右侧图标
&-suffix{
color:@antFontColor;
}
}
//日期选择框文本调整
.ant-picker-input{
>input{
color: @antFontColor;
text-indent: 0.1em;
}
}
}
}
//下拉选项框面板
.ant-select-dropdown{
color:@antFontColor;
background: @antBg;
border: 1px solid #02739d !important;
.ant-select-item-option-selected{
&:not(.ant-select-item-option-disabled){
background: none;
}
}
.ant-select-item-option-active{
&:not(.ant-select-item-option-disabled){
background: url(../img/arrowItemBg.webp) no-repeat 0/100% 100%;
}
}
//下拉框菜单
.ant-select-item-option{
&:hover{
background: url(../img/arrowItemBg.webp) no-repeat 0/100% 100%;
}
&:active{
background: url(../img/arrowItemBg.webp) no-repeat 0/100% 100%;
}
}
}
//下拉日期框面板
.ant-picker-dropdown{
//头部添加背景,并隐藏年份左右切换的按钮
.ant-picker-header{
border-bottom: 1px solid rgba(0,198,255,.5);
>button{
display: none !important;
}
&-view{
>button{
color: #ccffff !important;
pointer-events: none !important;// 取消年份切换效果
}
}
}
.ant-picker-panel-container{
color:@antFontColor;
border: 1px solid rgba(0,198,255,.5)!important;
background: url(../img/bg_ms1.webp) no-repeat 0/100% 100%;
background-color: rgba(21, 56, 76,0.8);
.ant-picker-panel{
border: 0;
}
}
//内容面板高度调整
.ant-picker-content{
height: 200px !important;
}
//内容面板颜色调整
.ant-picker-cell{
&.ant-picker-cell-disabled{
.ant-picker-cell-inner{
color: #6b909e;
}
}
&:hover{
&:not(.ant-picker-cell-in-view),
&:not(.ant-picker-cell-selected):not(.ant-picker-cell-range-start):not(.ant-picker-cell-range-end):not(.ant-picker-cell-range-hover-start):not(.ant-picker-cell-range-hover-end){
.ant-picker-cell-inner{
background: #1890ff;
}
}
}
}
}
// commonBox的css ↑
// ant弹窗样式 ↓
.ant-modal-content{
@closeWH:40px;
background-color: #3c697b;
.ant-modal-header{
padding: 12px 24px 6px;
border: none;
background: url(../img/bg_mt.webp) no-repeat 0/100% 100%;
.ant-modal-title{
font-family: dyFont;
font-size: 16px;
font-weight: 400;
color: #fff;
}
}
.ant-modal-body{
background: url('../img/bg_ms1.webp') no-repeat 0/100% 100%;
}
.ant-modal-close-x{
width: @closeWH;
height: @closeWH;
line-height: @closeWH;
text-align: center;
}
}
// ant弹窗样式 ↑
// ant步骤条 ↓
.ant-steps{
.ant-steps-icon{
color: #cff !important;
}
.ant-steps-item-icon{
background:none !important;
}
.ant-steps-item-title,.ant-steps-item-description{
color: @lightColor !important;
}
}
// ant步骤条 ↑
//列表样式 ↓ 包含图标列表list-icon滚动列表list-scroll自动滚动列表list-swiper
.list{
width: 100%;
height: 100%;
padding: 0 10px;
display: flex;
flex-direction: column;
position: relative;
.list-h{
flex-basis: @listItemHeight;
height: @listItemHeight;
line-height: @listItemHeight;
width: 100%;
text-align: center;
background: rgba(203, 244, 255, .1) 50%/contain;
box-sizing: border-box;
display: flex;
flex-flow: row nowrap;
align-items: center;
font-size: 16px;
font-weight: 400;
color: #d7efff;
p{
flex: 1;
height: 100%;
margin-bottom: 0px;
font-size: 14px;
}
&:nth-child(even){
background: rgba(0, 198, 255, .04) 50%/contain;
}
&:nth-child(odd){
background: rgba(0, 198, 255, .1) 50%/contain;
}
}
.list-b{
width: 100%;
}
//图标列表样式
&-icon{
flex-direction: row;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
height: auto;
&-item{
margin-top: 10px;
width: 170px;
height: 66px;
background: url('../img/icon_bg.webp') no-repeat;
background-size: 100% 100%;
display: flex;
align-items: center;
img{
width: 46px;
height: 48px;
margin: 0 10px 0 5px;
}
>div{
p{
font-size: @listIconfontP;
margin-bottom: 0px;
color: @pColor;
}
span{
color: @darkColor;
font-size: 14px;
}
}
}
}
//滚动列表的样式
&-scroll{
flex-direction: column;
margin-top: 10px;
.list-b{
background-color: #122a3b;
overflow-y: auto;
overflow-x: hidden;
&::-webkit-scrollbar{
width: 3px;
height: 1px;
right: -5px;
&-thumb{
border-radius: 4px;
box-shadow: inset 0 0 5px rgb(0 0 0 / 20%);
background: #44909d;
}
&-track{
box-shadow: inset 0 0 5px rgb(0 0 0 / 20%);
border-radius: 4px;
background: rgba(36, 119, 130,.5);
}
}
.list-item:extend(.list .list-h all){
}
}
}
//自动滚动列表
&-swiper{
.list-b{
.list-item:extend(.list .list-h all){
height: auto;
flex-basis: auto;
}
}
.swiper-slide {
p {
display: flex;
align-items: center;
justify-content: center;
}
}
}
//排行列表前3改为图标
.ranking{
&-first,&-second,&-third{
display: block;
width: 36px;
height: 36px;
margin: 0 auto;
background-position: center center;
background-repeat: no-repeat;
}
&-first{
background-image: url('../img/icon/icon_first.webp');
}
&-second{
background-image: url('../img/icon/icon_second.webp');
}
&-third{
background-image: url('../img/icon/icon_third.webp');
}
}
&-operation {
cursor: pointer;
}
}
//列表样式 ↑
//地图弹窗 ↓
.BMap_bubble_content{
p{
margin-bottom: 4px;
font-size: 12px;
}
}
//地图弹窗 ↑

129
src/components/Foot.vue Normal file
View File

@ -0,0 +1,129 @@
<template>
<transition :appear='true' enter-active-class='animate__animated animate__fadeInUp'>
<div class='foot'>
<div class="foot-menu">
<div class='foot-page foot-page1'>
<a href="javascript:void(0)">基础概况</a>
</div>
<div class='foot-page foot-page2'>
<a href="javascript:void(0)">瞭望台</a>
</div>
<div class='foot-page foot-page3'>
<a href="javascript:void(0)">指挥台</a>
</div>
<div class='foot-page foot-page4'>
<a href="javascript:void(0)">工作台</a>
</div>
<div class='foot-icon'>
<img src="../assets/img/light.png" alt="">
</div>
</div>
</div>
</transition>
</template>
<script setup>
</script>
<style lang="less" scoped>
@keyframes one-data{
0%{
transform:rotate(0)
}
50%{
transform: rotate(180deg);
}
100%{
transform: rotate(1turn);
}
}
.foot{
position: fixed;
bottom: 0;
width: 100%;
height: 90px;
background: url(../assets/img/bg_bottom.png) no-repeat 0/100% 100%;
&-menu{
margin-top: 20px;
display: flex;
justify-content: center;
}
}
.foot-page{
a{
display: block;
cursor: pointer;
font-size: 18px;
font-family: SourceHanSansCN;
font-weight: 500;
color: #fff;
text-align: center;
}
}
.foot-page1{
margin-top:10px;
width:155px;
height:43px;
background: url(../assets/img/bg_btn_l1.png) no-repeat 0/100% 100%;
a{
padding-left: 24px;
transform: rotate(-4deg);
line-height: 46px;
}
}
.foot-page2{
margin-right:79px;
width:146px;
height: 49px;
background: url(../assets/img/bg_btn_l2.png) no-repeat 0/100% 100%;
a{
padding-right: 20px;
transform: rotate(-4deg);
line-height: 46px;
}
}
.foot-page3{
transform:rotateY(180deg);
width:120px;
height: 49px;
margin-left: 12px;
background: url(../assets/img/bg_btn_l2.png) no-repeat 0/100% 100%;
a{
line-height: 46px;
transform: rotate(-2deg) rotateY(180deg);
}
}
.foot-page4{
margin-top: 10px;
transform:rotateY(180deg);
width:152px;
height:43px;
background: url(../assets/img/bg_btn_l1.png) no-repeat 0/100% 100%;
a{
padding-right: 10px;
line-height: 46px;
transform: rotate(-4deg) rotateY(180deg);
}
}
.foot-icon{
position: absolute;
width: 140px;
height: 140px;
top: -20px;
background: url(../assets/img/bg_bottom_logo.png) no-repeat 0/100% 100%;
img{
pointer-events: none;
position: absolute;
width: 176px;
height: 176px;
z-index: 999;
top: -30px;
left: -18px;
top: -18px;
-webkit-animation: one-data 6s linear infinite;
animation: one-data 6s linear infinite;
}
}
</style>

39
src/components/Header.vue Normal file
View File

@ -0,0 +1,39 @@
<template>
<transition
:appear="true"
enter-active-class="animate__animated animate__fadeInDown"
>
<div class="header">
<p>{{ datas.title }}</p>
</div>
</transition>
</template>
<script setup>
import { reactive } from 'vue'
let datas = reactive({ // eslint-disable-line no-unused-vars
title: '"艺象心"驾驶舱',
}) // eslint-disable-line no-unused-vars
</script>
<style lang="less" scoped>
.header {
position: fixed;
pointer-events: none;
width: 100%;
height: 90px;
background: url(../assets/img/top1.png) no-repeat;
background-size: 100% 100%;
> p {
color: #fff;
font-size: 26px;
font-family: dyFont;
letter-spacing: 8px;
margin: 16px auto 0;
text-align: center;
padding-left: 28px;
cursor: default;
}
}
</style>

146
src/components/Main.vue Normal file
View File

@ -0,0 +1,146 @@
<template>
<div class="main-nav">
<div
v-for="(item, index) in mainNav"
:key="index"
class="main-nav-item"
:style="[
item.router == defaultNav
? { backgroundImage: 'url(' + item.obg + ')' }
: { backgroundImage: 'url(' + item.bg + ')' },
]"
>
<router-link :to="item.router">{{ item.name }}</router-link>
</div>
</div>
<router-view></router-view>
</template>
<script setup>
import { reactive, ref } from '@vue/reactivity'
import { useRouter } from 'vue-router'
import { watch } from '@vue/runtime-core'
let mainNav = reactive([ // eslint-disable-line no-unused-vars
{
name: '首页',
router: '/coHome',
bg: require('../assets/img/lwt1.webp'),
obg: require('../assets/img/lwt11.webp'),
},
{
name: '用户画像',
router: '/yhhx',
bg: require('../assets/img/lwt2.webp'),
obg: require('../assets/img/lwt22.webp'),
},
{
name: '文艺作品',
router: '/wyzp',
bg: require('../assets/img/lwt3.webp'),
obg: require('../assets/img/lwt33.webp'),
},
{
name: '文艺活动',
router: '/wyhd',
bg: require('../assets/img/lwt4.webp'),
obg: require('../assets/img/lwt44.webp'),
},
{
name: '服务点',
router: '/fwd',
bg: require('../assets/img/lwt5.webp'),
obg: require('../assets/img/lwt55.webp'),
},
{
name: '点单大厅',
router: '/dddt',
bg: require('../assets/img/lwt5.webp'),
obg: require('../assets/img/lwt55.webp'),
},
]) // eslint-disable-line no-unused-vars
const defaultNav = ref('/coHome')
const router = useRouter()
watch(
() => router.currentRoute.value.path,
(newValue) => {
defaultNav.value = newValue
let dom = document.getElementById('page')
dom.style.background = ['/fwd', '/dddt'].includes(newValue)
? 'none'
: ' #061119'
}
)
</script>
<style lang="less" scoped>
.main-nav {
pointer-events: all;
width: 762px;
height: 70px;
padding: 8px 0;
box-sizing: border-box;
z-index: 1000;
position: fixed;
top: 92px;
left: 30.1%;
background: url(../assets/img/lwt_bg_center.webp) no-repeat;
background-size: 100% 100%;
display: flex;
&-item {
box-sizing: border-box;
flex: 1;
height: 100%;
font-weight: 400;
color: #fff;
padding-left: 52px;
background-size: 100% 100%;
a {
color: #fff;
font-family: dyFont;
font-size: 13px;
line-height: 54px;
}
}
}
</style>
<style lang="less">
@import "@/assets/theme/theme.less";
.main {
width: 100%;
height: 100%;
box-sizing: border-box;
position: relative;
&-l,
&-c,
&-r {
display: flex;
flex-direction: column;
.commonBox {
&:nth-child(n + 2) {
margin-top: 20px;
}
}
}
&-l {
position: absolute;
left: 15px;
top: 70px;
width: 555px;
height: @lrHeight;
}
&-c {
position: absolute;
left: 595px;
top: 180px;
width: 734px;
height: @cHeight;
}
&-r {
position: absolute;
right: 15px;
top: 70px;
width: 555px;
height: @lrHeight;
}
}
</style>

View File

@ -0,0 +1,198 @@
<template>
<div
class="commonBox"
:style="[
{ background: 'url(' + commonBoxBg + ') no-repeat 0/100% 100%' },
{ '--width': width || 'auto' },
{ '--height': height || 'auto' },
{ '--flex': flex },
]"
>
<i></i>
<i></i>
<div
class="commonBox-header"
:style="[
titleImg ? { backgroundImage: 'url(' + titleImg + ')' } : null,
]"
>
<img :src="tipImg" />
<span>{{ title }}</span>
<img :src="tipImg" />
<div
class="commonBox-more"
v-if="onMoreData.name"
@click="commonBoxMoreActive"
>
<img :src="commBoxMoreIcon" />
<span>{{ onMoreData.name }}</span>
</div>
</div>
<div class="commonBox-contain">
<div class="commonBox-menu" v-if="onMenuData && onMenuData != ''">
<el-radio-group
v-model="defaultValue"
@change="menuChange"
>
<el-radio-button
v-for="(item, index) in onMenuData"
:key="index"
:label="item.value"
>
{{ item.name }}
</el-radio-button>
</el-radio-group>
<el-select
ref="select"
v-model="chooseValue"
v-if="chooseValue != ''"
@change="menuChange"
>
<el-select-option
v-for="(item, index) in choose"
:key="index"
:value="item.value"
>{{ item.name }}</el-select-option
>
</el-select>
<el-date-picker
v-if="dateFalg"
v-model="dateValue"
:disabled-date="disabledDate"
:placeholder="store.state.lastMon"
:format="'M月'"
picker="month"
:inputReadOnly="true"
@change="menuChange"
/>
</div>
<slot></slot>
</div>
</div>
</template>
<script setup>
import { ref, reactive, toRaw, toRefs, defineEmits, defineProps } from 'vue'
import { useStore } from 'vuex'
import dayjs from 'dayjs'
// import 'dayjs/locale/zh-cn'
// import locale from 'ant-design-vue/es/date-picker/locale/zh_CN'
// dayjs.locale('lcoale')
const store = useStore()
const props = defineProps([
'title',
'width',
'height',
'flex',
'bg',
'boxData',
'lbHeight',
])
const tipImg = ref(require('@/assets/img/title-tip.webp'))
let commonBoxBg = ref(require('@/assets/img/bg_ms1.webp'))
let titleImg = ref(require('@/assets/img/bg_mt.webp'))
const commBoxMoreIcon = ref(require('@/assets/img/cbmi.webp'))
//onSelectData
const onSelectData = reactive({
itemName: '', //
defaultValue: '', // /
lastValue: '', //
chooseValue: '', //&
choose: [], //
dateFalg: false, //
dateValue: '', //
})
const { defaultValue, chooseValue, choose, dateFalg, dateValue } =
toRefs(onSelectData)
let onDefaultData = [] //default
let onMenuData = [] //menu
let onMoreData = {} //more
const emit = defineEmits(['menuActive', 'moreActive']) //
//
const bgs = reactive({
bg1: require('@/assets/img/bg_ms1.webp'),
bg2: require('@/assets/img/bg_ms2.webp'),
bg3: require('@/assets/img/bg_ms3.webp'),
bg4: require('@/assets/img/bg_ms4.webp'),
bg5: require('@/assets/img/bg_ms5.webp'),
cbg: require('@/assets/img/bg_cbg.webp'),
})
//
const changeBg = (b) => {
commonBoxBg = bgs[b] ? ref(bgs[b]) : ref(b)
titleImg = b == 'cbg' ? (titleImg = ref('')) : titleImg
}
///boxData
const setBoxData = (d) => {
let onboxData = toRaw(reactive(d))
let { more, menu, ...defData } = onboxData
//default()
onDefaultData = defData
//defDataitemNameitemNamemenuherf
//menu()
onMenuData = menu
if (defData.itemName && defData.itemName != '') {
for (let v of menu) if (v.value == defData.itemName) checkChooseData(v)
}
//+more
if (more) {
onMoreData = more
onMoreData.name = more.name || '更多'
}
}
///onSelectData
const checkChooseData = (d) => {
if (d.href) return (onSelectData.defaultValue = onSelectData.lastValue)
onSelectData.defaultValue ? null : (onSelectData.defaultValue = d.value)
onSelectData.lastValue = onSelectData.lastValue
? onSelectData.defaultValue
: d.value
onSelectData.chooseValue = d.choose ? d.choose[0].value : ''
onSelectData.choose = d.choose || []
onSelectData.dateFalg = d.date ? true : false
onSelectData.dateValue = d.date ? store.state.lastMonTime : ''
}
//,memutype
const commonBoxMoreActive = () => {
if (onMoreData.href) onMoreData.href ? window.open(onMoreData.href) : null
if (onMoreData.fn) emit('moreActive', onMoreData.fn)
}
props.bg && changeBg(props.bg)
props.boxData && setBoxData(props.boxData)
//()
const disabledDate = (current) => {
return current && current > store.state.lastMonTime
}
//
const menuChange = (e) => {
for (let v of onMenuData) {
if (v.value == e) {
checkChooseData(v)
if (v.href) window.open(v.href)
}
}
let a = onSelectData.dateValue
? dayjs(onSelectData.dateValue).format('M月')
: ''
emit(
'menuActive',
onDefaultData.name,
onSelectData.defaultValue,
onSelectData.chooseValue,
a
)
}
</script>
<style lang="less" scoped>
@import "@/assets/theme/theme.less";
.commonBox {
width: var(--width);
height: var(--height);
flex-basis: var(--height);
flex: var(--flex);
}
</style>

View File

@ -0,0 +1,210 @@
<template>
<div
:class="['list', 'list-' + ld.type, ld.ranking ? 'list-ranking' : null]"
>
<div class="list-h" v-if="!ld.hideHeader && ld.header">
<p
v-for="(item, index) in ld.header"
:key="index"
:class="[
ld.flex && ld.flex[index] ? 'flex-' + ld.flex[index] : null,
]"
>
{{ item.headerName }}
</p>
</div>
<div
class="list-b"
:style="[{ height: ld.height }]"
v-if="ld.type === 'scroll' && ld.data.length"
>
<template v-if="ld.ranking">
<div
class="list-item"
v-for="(item, index) in onList"
:key="index"
@click="itemActive(item)"
>
<p
v-for="(v, i) in ld.header"
:key="i"
:class="[
ld.flex && ld.flex[i] ? 'flex-' + ld.flex[i] : null,
]"
>
<i
v-if="index < 3 && i == 0"
:class="[
index === 0
? 'ranking-first'
: index === 1
? 'ranking-second'
: 'ranking-third',
]"
></i>
<span v-else-if="index >= 3 && i == 0">{{
item.ranking
}}</span>
<span
v-else-if="ld.header[i].key === 'operation'"
@click="operActive(item)"
class="list-operation"
>
{{ item[ld.header[i].key] }}
</span>
<span v-else>{{ item[ld.header[i].key] }}</span>
</p>
</div>
</template>
<template v-else>
<div
class="list-item"
v-for="(item, index) in onList"
:key="index"
@click="itemActive(item)"
>
<p
v-for="(v, i) in ld.header"
:key="i"
:class="[
ld.flex && ld.flex[i] ? 'flex-' + ld.flex[i] : null,
]"
>
<span
v-if="ld.header[i].key === 'operation'"
@click="operActive(item)"
class="list-operation"
>
{{ item[ld.header[i].key] }}
</span>
<span v-else>{{ item[ld.header[i].key] }}</span>
</p>
</div>
</template>
</div>
<swiper
class="swiper-container list-b"
:modules="modules"
:slidesPerView="!ld.swiperView ? 5 : ld.swiperView"
direction="vertical"
:loop="true"
:autoplay="{ delay: 5000, disableOnInteraction: false }"
:style="[{ height: ld.height }]"
v-else-if="ld.type === 'swiper' && ld.data.length"
>
<template v-if="ld.ranking">
<swiper-slide
class="list-item"
v-for="(item, index) in onList"
:key="index"
@click="itemActive(item)"
>
<p
v-for="(v, i) in ld.header"
:key="i"
:class="[
ld.flex && ld.flex[i] ? 'flex-' + ld.flex[i] : null,
]"
>
<i
v-if="index < 3 && i == 0"
:class="[
index === 0
? 'ranking-first'
: index === 1
? 'ranking-second'
: 'ranking-third',
]"
></i>
<span v-else-if="index >= 3 && i == 0">{{
item.ranking
}}</span>
<span
v-else-if="ld.header[i].key === 'operation'"
@click="operActive(item)"
class="list-operation"
>
{{ item[ld.header[i].key] }}
</span>
<span v-else>{{ item[ld.header[i].key] }}</span>
</p>
</swiper-slide>
</template>
<template v-else>
<swiper-slide
class="swiper-slide list-item"
v-for="(item, index) in onList"
:key="index"
@click="itemActive(item)"
>
<p
v-for="(v, i) in ld.header"
:key="i"
:class="[
ld.flex && ld.flex[i] ? 'flex-' + ld.flex[i] : null,
]"
>
<span
v-if="ld.header[i].key === 'operation'"
@click="operActive(item)"
class="list-operation"
>
{{ item[ld.header[i].key] }}
</span>
<span v-else>{{ item[ld.header[i].key] }}</span>
</p>
</swiper-slide>
</template>
</swiper>
<template v-if="ld.type === 'icon'">
<div
class="list-icon-item"
v-for="(item, index) in ld.data"
:key="index"
@click="itemActive(item)"
>
<img :src="item.icon" />
<div>
<p>
{{ item.value }}
<span>{{ item.unit }}</span>
</p>
<span>{{ item.name }}</span>
</div>
</div>
</template>
</div>
</template>
<script setup>
import { reactive, toRaw, ref, defineEmits, defineProps } from 'vue'
import { hook } from '@/hook/hook'
import { Autoplay } from 'swiper'
import { Swiper, SwiperSlide } from 'swiper/vue/swiper-vue.js'
const modules = [Autoplay]
const { jsonSort } = hook()
const props = defineProps(['listData'])
const ld = reactive(props.listData)
var onList = reactive(props.listData.data)
ld &&
(() => {
if (ld.ranking) {
ld.header.unshift({ headerName: '排名', key: 'ranking' })
let r = typeof ld.ranking == 'string' ? ld.ranking : 'value'
let d = jsonSort(toRaw(ld.data), r, ld.rankingOrder)
d.forEach((v, i) => (v.ranking = i + 1))
onList = reactive(d)
}
if (ld.operation) {
ld.header.push({ headerName: '操作', key: 'operation' })
let r = typeof ld.operation == 'string' ? ld.operation : '查看'
for (let v of ld.data) v.operation = r
}
})()
const emit = defineEmits(['listItem', 'listOper']) //
const itemActive = (item) => emit('listItem', item)
const operActive = (item) => emit('listOper', item)
</script>

View File

@ -0,0 +1,33 @@
<template>
<div class="common-title flex-r">
<img :src="tip1" />
<p class="common-title-info">{{ title }}</p>
</div>
</template>
<script setup>
import { ref, defineEmits, defineProps } from 'vue'
const props = defineProps(['title'])
const tip1 = ref(require('@/assets/img/bg_ct.webp'))
</script>
<style lang="less" scoped>
@import "@/assets/theme/theme.less";
.common-title {
height: 30px;
line-height: 30px;
flex-basis: 30px;
> img {
margin-right: 8px;
}
&-info {
font-size: 18px;
font-weight: 500;
min-width: 180px;
color: @lightColor;
background: url('../../assets/img/bg_cb.webp') no-repeat 0 bottom;
}
}
</style>

View File

@ -0,0 +1,10 @@
const importFn = require.context('./', false, /\.vue$/)
export default {
install(app) {
importFn.keys().forEach((key) => {
const component = importFn(key).default
app.component(component.__name, component)
})
},
}

View File

@ -0,0 +1,550 @@
<template>
<div class="main">
<teleport to="#app">
<div
id="map"
:style="{
width: store.state.pagePosition.scale * 1920 + 'px',
height: store.state.pagePosition.scale * 1080 + 'px',
marginLeft: store.state.pagePosition.left,
marginTop: store.state.pagePosition.top,
}"
></div>
</teleport>
<transition
:appear="true"
enter-active-class="animate__animated animate__fadeInLeft"
>
<div class="main-l">
<CommonBox
title="需求列表"
height="720px"
width="440px"
bg="bg5"
>
<CommonList :listData="xqlb.list" @listItem="showMore" />
</CommonBox>
</div>
</transition>
<transition-group
enter-active-class="animate__animated animate__fadeInRight"
leave-active-class="animate__animated animate__fadeOutRight"
>
<div class="main-r" :key="1" v-show="detailsFlag">
<CommonBox
title="需求详情"
width="440px"
class="details"
bg="bg5"
>
<div class="details-info">
<p>
<span>标题</span
><span>{{ detailsSetData.title }}</span>
</p>
<p>
<span>类型</span>
<span>{{ detailsSetData.type }}</span>
</p>
<p>
<span>时间</span>
<span>{{ detailsSetData.time }}</span>
</p>
<p>
<span>发布人</span>
<span>{{ detailsSetData.author }}</span>
</p>
<p>
<span>联系电话</span>
<span>{{ detailsSetData.photo }}</span>
</p>
<p>
<span>需求清单</span>
<span>{{ detailsSetData.listing }}</span>
</p>
<p>
<span>具体内容</span
><span>{{ detailsSetData.matter }}</span>
</p>
</div>
<template
v-if="
detailsSetData.progress &&
detailsSetData.progress.length
"
>
<commonTitle title="需求流程" />
<el-steps
direction="vertical"
:current="detailsSetData.progress.length"
class="details-process scrollBar"
>
<el-step
v-for="(item, index) in detailsSetData.progress"
:key="index"
:title="item.name"
:description="item.date"
/>
</el-steps>
</template>
<template
v-if="detailsSetData.imgs && detailsSetData.imgs.length"
>
<commonTitle title="相关内容" />
<swiper
:pagination="{ clickable: true }"
:modules="modules"
:slidesPerView="1"
class="details-imgs"
>
<swiper-slide
v-for="(item, index) in detailsSetData.imgs"
:key="index"
>
<img :src="item" />
</swiper-slide>
</swiper>
</template>
<template v-if="detailsSetData.remark">
<commonTitle title="需求评价" />
<p class="details-remark">
{{ detailsSetData.remark }}
</p>
</template>
</CommonBox>
</div>
</transition-group>
<transition
:appear="true"
enter-active-class="animate__animated animate__fadeInUp"
>
<ul class="map-tip">
<li
v-for="(v, k, i) in mapPointsIcon"
:key="i"
@click="mapPointsChoose(v)"
>
<img :src="v.tipFlag ? v.tip : v.tip2" />
<span :style="{ color: v.tipFlag ? '#cff' : '#85b1bf' }">{{
k
}}</span>
</li>
</ul>
</transition>
</div>
</template>
<script setup>
import { useStore } from 'vuex'
import { onMounted } from '@vue/runtime-core'
import { reactive, ref, toRefs } from '@vue/reactivity'
import { Pagination, A11y } from 'swiper'
import { Swiper, SwiperSlide } from 'swiper/vue/swiper-vue.js'
import { hook } from '@/hook/hook'
const { delay, chartDate } = hook()
const store = useStore()
const modules = [Pagination, A11y]
const detailsFlag = ref(false)
const mapPointsIcon = reactive({
学校乐队: {
name: '学校乐队',
tip: require('@/assets/img/icon/s.png'),
tip2: require('@/assets/img/icon/s2.png'),
tipFlag: true,
},
老年舞队: {
name: '老年舞队',
tip: require('@/assets/img/icon/l.png'),
tip2: require('@/assets/img/icon/l2.png'),
tipFlag: true,
},
文艺团队: {
name: '文艺团队',
tip: require('@/assets/img/icon/w.png'),
tip2: require('@/assets/img/icon/w2.png'),
tipFlag: true,
},
艺术机构: {
name: '艺术机构',
tip: require('@/assets/img/icon/j.png'),
tip2: require('@/assets/img/icon/j2.png'),
tipFlag: true,
},
})
const mapPoints = reactive([
{
title: '丹城第二小学合唱团',
type: '学校乐队',
count: '115',
rating: '4.5',
location: '象山县建设路293号',
phone: '65477592',
x: 29.462307,
y: 121.886711,
},
{
title: '丹城中学合唱团',
type: '学校乐队',
count: '96',
rating: '4',
location: '象山县丹阳路附近',
phone: '65244785',
x: 29.467602,
y: 121.870499,
},
{
title: '丹河街道老年舞队',
type: '老年舞队',
count: '54',
rating: '4',
location: '象山县丹河东路1001号',
phone: '65855412',
x: 29.472591,
y: 121.879829,
},
{
title: '文峰小区文艺团',
type: '文艺团队',
count: '86',
rating: '4.5',
location: '象山县丹峰东路242号',
phone: '69655892',
x: 29.461435,
y: 121.884125,
},
{
title: '乐逍遥文艺团',
type: '文艺团队',
count: '65',
rating: '3.5',
location: '象山县天安路157号3楼',
phone: '65744895',
x: 29.481435,
y: 121.894125,
},
{
title: '飞韵琴行',
type: '艺术机构',
count: '105',
rating: '4.5',
location: '象山县象山河路世纪花园南侧约30米',
phone: '65322501',
x: 29.461435,
y: 121.864125,
},
{
title: '雅艺乐器行',
type: '艺术机构',
count: '105',
rating: '4.5',
location: '象山县象山河路世纪花园南侧约30米',
phone: '65322501',
x: 29.451435,
y: 121.884125,
},
{
title: '卓舞蹈培训中心',
type: '艺术机构',
count: '124',
rating: '5',
location: '象山县樟树下村34号 ',
phone: '65896632',
x: 29.471435,
y: 121.914125,
},
])
const commonBoxData = reactive({
xqlb: {
list: {
type: 'swiper',
height: '620px',
flex: [2, 1],
swiperView: 14,
header: [
{ headerName: '标题', key: 'title' },
{ headerName: '时间', key: 'time' },
],
data: [
{
title: '涌金广场文艺表演',
time: '2022-08-26',
},
{
title: '人民广场演唱会',
time: '2022-08-22',
},
{
title: '人民广场文艺演出',
time: '2022-08-19',
},
{
title: '第六届少儿慈善春晚活动',
time: '2022-08-10',
},
{
title: '《一心向党 歌唱祖国》文艺晚会',
time: '2022-08-05',
imgs: [],
},
{
title: '“象益山海”',
time: '2022-08-01',
},
{
title: '“中华慈善日”文艺汇演',
time: '2022-07-29',
},
{
title: '“红色领航·益暖象山”公益演出',
time: '2022-07-25',
},
{
title: '“百场演出进百乡”公演',
time: '2022-07-16',
},
{
title: '丹西街道军属慰问表演',
time: '2022-07-15',
},
{
title: '影视城端午节晚会',
time: '2022-07-10',
type: '演出',
author: '孙先生',
photo: '13905584151',
listing:
'需要主持人3人现场管理人员20人志愿者30人表演团队5支。',
matter: '端午即将到来,现在象山县影视城举办端午节晚会活动,喜迎端午。',
progress: [
{ name: '需求发布', date: '2022-05-28 20:14' },
{ name: '已接单', date: '2022-05-29 09:53' },
{ name: '已结束', date: '2022-06-08 18:00' },
{ name: '已评价', date: '2022-06-09 10:20' },
],
imgs: [
require('@/assets/img/pics/3.jpg'),
require('@/assets/img/pics/4.jpg'),
],
remark: '这台晚会不仅有了故事性和趣味性,而且逻辑串联也非常合理。节目制作的精良让我们看到了主创团队的用心,赢得赞誉是很自然的事情。',
},
{
title: '“善行象山、走进晓塘”文艺演出',
time: '2022-07-03',
},
{
title: '象山渔区巡演',
time: '2022-06-21',
},
{
title: '象山县第四届群众文化艺术节',
time: '2022-06-18',
},
{
title: '象山县第五届群众文化艺术节',
time: '2022-06-11',
type: '演出',
author: '李女士',
photo: '1325224101',
listing:
'需要主持人3人现场管理人员10人志愿者20人表演团队若干支。',
matter: '文化凝聚力量,艺术放飞梦想,特举办象山县第五届群众文化艺术节。',
progress: [
{ name: '需求发布', date: '2023-02-15 10:08' },
{ name: '已接单', date: '2023-02-15 14:23' },
{ name: '已结束', date: '2023-02-25 20:00' },
{ name: '已评价', date: '2023-02-26 09:21' },
],
imgs: [
require('@/assets/img/pics/1.jpg'),
require('@/assets/img/pics/2.jpg'),
],
remark: '满足人民群众对美好文化生活的需求,激发人民群众文化创造活力,发挥人民群众在文化活动中的主体作用,提增全民艺术知识普及、艺术欣赏普及、艺术技能普及、艺术活动普及水平,提升我县文化建设凝聚力、影响力和创造力.',
},
{
title: '象山县第十四届中小学艺术节',
time: '2022-06-08',
},
{
title: '象山开镰节音乐节',
time: '2022-06-03',
},
],
},
},
})
const { xqlb } = toRefs(commonBoxData)
var detailsSetData = reactive({})
var map
var opts = {
title: '',
}
const loadMap = (d) => {
for (const v in mapPointsIcon) {
mapPointsIcon[v].mapIcon = new window.BMapGL.Icon(
mapPointsIcon[v].tip,
new window.BMapGL.Size(26, 26)
)
}
for (const v of d) {
let points = new window.BMapGL.Point(v.y, v.x)
opts.title = v.title
let html = `
<p>服务商积分: ${v.count}</p>
<p>星级: ${v.rating}</p>
<p>类型: ${v.type}</p>
<p>地址: ${v.location}</p>
<p>电话: ${v.phone}</p>
`
let markers = new window.BMapGL.Marker(points, {
icon: mapPointsIcon[v.type].mapIcon,
type: v.type,
})
map.addOverlay(markers)
let infoWindow = new window.BMapGL.InfoWindow(html, opts)
markers.addEventListener('click', function () {
map.openInfoWindow(infoWindow, points)
})
}
}
onMounted(() => {
map = new window.BMapGL.Map('map')
map.setMapStyleV2({
styleId: '4a6029df2a52cd8be9496f0f2f47a1d4',
})
var point = new window.BMapGL.Point(121.879829, 29.472591)
map.centerAndZoom(point, 15)
map.setHeading(34.5)
map.setTilt(43)
map.enableScrollWheelZoom()
loadMap(mapPoints)
})
const mapPointsChoose = (e) => {
e.tipFlag = !e.tipFlag
if (e.tipFlag) {
let data = []
for (let v of mapPoints) if (v.type == e.name) data.push(v)
loadMap(data)
} else {
let allOverlay = map.getOverlays()
for (let v of allOverlay)
if (v._config.type == e.name) map.removeOverlay(v)
}
}
const showMoreData = (e) => {
for (const v in detailsSetData) detailsSetData[v] = null
for (const v in e) detailsSetData[v] = e[v]
detailsFlag.value = true
}
const showMore = (e) => {
if (detailsFlag.value) {
detailsFlag.value = false
delay(showMoreData, e, 400)
} else showMoreData(e)
}
</script>
<style lang="less" scoped>
@import "@/assets/theme/theme.less";
.main {
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
&-l,
&-r {
pointer-events: none;
> .commonBox {
pointer-events: all;
}
}
.main-r {
align-items: flex-end;
}
.map-tip {
position: absolute;
bottom: 20px;
left: 24%;
width: auto;
height: auto;
background-color: #333333;
border-radius: 10px;
padding: 5px 10px;
pointer-events: all;
li {
float: left;
margin: 5px;
padding: 2px 5px;
height: 30px;
cursor: pointer;
}
img {
height: 30px;
width: 30px;
}
}
}
.details {
position: relative;
padding-bottom: 10px;
.common-title {
margin: 8px;
}
&-info {
display: flex;
flex-wrap: wrap;
margin: 10px 0;
p {
line-height: 20px;
padding: 5px 15px 5px;
display: flex;
flex-direction: row;
width: 100%;
position: relative;
span {
color: @lightColor;
display: inline-block;
&:first-child {
color: @darkColor;
flex-basis: 80px;
white-space: nowrap;
}
}
&:nth-child(n + 2):not(:nth-child(n + 6)) {
width: 50%;
}
}
}
&-process {
margin-left: 20px;
height: 185px;
width: 410px;
}
&-imgs {
:deep(.swiper) {
position: relative;
&-wrapper {
width: 390px;
height: 220px;
.swiper-slide {
width: 100%;
img {
width: 100%;
height: 100%;
}
}
}
&-pagination {
span {
background-color: white;
}
}
}
}
&-remark {
color: @lightColor;
padding: 0px 10px 10px 15px;
text-indent: 2em;
line-height: 22px;
}
}
</style>

View File

@ -0,0 +1,650 @@
<template>
<div class="main">
<teleport to="#app">
<div
id="map"
:style="{
width: store.state.pagePosition.scale * 1920 + 'px',
height: store.state.pagePosition.scale * 1080 + 'px',
marginLeft: store.state.pagePosition.left,
marginTop: store.state.pagePosition.top,
}"
></div>
</teleport>
<transition
:appear="true"
enter-active-class="animate__animated animate__fadeInLeft"
>
<div class="main-l">
<CommonBox
title="服务点带动消费金额统计"
height="280px"
width="440px"
>
<div class="chart" ref="ddxfRef" />
</CommonBox>
<CommonBox title="消费订单" height="280px" width="440px">
<CommonList :listData="xfdd.list" />
</CommonBox>
</div>
</transition>
<transition
:appear="true"
enter-active-class="animate__animated animate__fadeInRight"
>
<div class="main-r">
<CommonBox
title="服务点服务频次统计"
height="280px"
width="440px"
>
<div class="chart" ref="fwpcRef" />
</CommonBox>
<CommonBox title="服务点类型占比" height="280px" width="440px">
<div class="chart" ref="lxzbRef" />
</CommonBox>
</div>
</transition>
</div>
</template>
<script setup>
import * as echarts from 'echarts'
import { useStore } from 'vuex'
import { onMounted, onBeforeMount } from '@vue/runtime-core'
import { reactive, ref, toRefs } from '@vue/reactivity'
import { hook } from '@/hook/hook'
const { delay, chartDate } = hook()
const store = useStore()
// import {
// Engine,
// GeoJSONDataSource,
// EmptySky,
// Polygon,
// ExtendMeshStandardMaterial,
// } from 'mapv-three'
// import { BoxGeometry, MeshStandardMaterial, Mesh } from 'three'
const ddxfRef = ref(null)
const fwpcRef = ref(null)
const lxzbRef = ref(null)
var mapPoints = reactive([
{
title: '文海培训学校',
integral: '120',
rating: '4',
pointType: '培训学校',
location: '象山县樟树下村34号',
phone: '65745598',
x: 29.472591,
y: 121.879829,
},
{
title: '雅意乐器行',
integral: '96',
rating: '3.5',
pointType: '艺术机构',
location: '象山县象山港路150号',
phone: '13596624584',
x: 29.462307,
y: 121.886711,
},
{
title: '象山影视城',
integral: '156',
rating: '4.5',
pointType: '景区',
location: '象山县新桥镇黄公岙村',
phone: '65221458',
x: 29.467602,
y: 121.870499,
},
{
title: '龙宫海鲜餐厅',
integral: '111',
rating: '4',
pointType: '美食',
location: '象山县丹南路涌金广场2号楼5楼',
phone: '65671616',
x: 29.461435,
y: 121.884125,
},
{
title: '南北面馆',
integral: '75',
rating: '3.5',
pointType: '美食',
location: '象山县白鹤路白石商业广场',
phone: '13566027505',
x: 29.473518,
y: 121.894125,
},
{
title: '强盛饭堂',
integral: '96',
rating: '4',
pointType: '美食',
location: '象山县丹青路象山科技创业园',
phone: '15744485962',
x: 29.478518,
y: 121.924125,
},
{
title: '现代网苑',
integral: '145',
rating: '4',
pointType: '娱乐',
location: ' 象山县天安路145号',
phone: '13606786811',
x: 29.496518,
y: 121.904125,
},
{
title: '台球会所',
integral: '106',
rating: '4',
pointType: '娱乐',
location: ' 象山县天安路135弄3945',
phone: '13705748147',
x: 29.460518,
y: 121.854125,
},
{
title: '好学教育',
integral: '135',
rating: '4.5',
pointType: '培训学校',
location: '象山县天安路157号3楼',
phone: '13386616597',
x: 29.479518,
y: 121.824125,
},
{
title: '艺卓舞蹈培训中心',
integral: '126',
rating: '4',
pointType: '培训学校',
location: '艺卓舞蹈培训中心',
phone: '15158340345',
x: 29.476518,
y: 121.844125,
},
{
title: '艺术酒庄',
integral: '121',
rating: '3.5',
pointType: '艺术机构',
location: '象山县象山河路世纪花园南侧约30米',
phone: '65236698',
x: 29.486518,
y: 121.864125,
},
])
const commonBoxData = reactive({
ddxf: {
chart: [
{
name: '第一季度',
value: 47,
},
{
name: '第二季度',
value: 52,
},
{
name: '第三季度',
value: 39,
},
{
name: '第四季度',
value: 43,
},
],
},
xfdd: {
list: {
type: 'swiper',
height: '190px',
header: [
{ headerName: '店名', key: 'storeName' },
{ headerName: '金额', key: 'price' },
{ headerName: '时间', key: 'time' },
],
data: [
{
storeName: '文海培训学校',
price: '60元',
time: '2022-08-28',
},
{
storeName: '雅意乐器行',
price: '60元',
time: '2022-08-25',
},
{
storeName: '象山影视城',
price: '60元',
time: '2022-08-21',
},
{
storeName: '馒头山',
price: '60元',
time: '2022-08-20',
},
{
storeName: '龙宫海鲜餐厅',
price: '60元',
time: '2022-08-17',
},
{
storeName: '南北面馆',
price: '60元',
time: '2022-08-13',
},
{
storeName: '卓舞蹈培训中心',
price: '60元',
time: '2022-08-09',
},
],
},
},
fwpc: {
chart: [
{ name: '1月', value: 1540 },
{ name: '2月', value: 1370 },
{ name: '3月', value: 1310 },
{ name: '4月', value: 1050 },
{ name: '5月', value: 1650 },
{ name: '6月', value: 1420 },
{ name: '7月', value: 1711 },
{ name: '8月', value: 1554 },
],
},
lxzb: {
chart: [
{ name: '美食', value: 100 },
{ name: '艺术机构', value: 200 },
{ name: '培训学校', value: 150 },
{ name: '景区', value: 80 },
{ name: '娱乐场所', value: 67 },
],
},
})
const { xfdd } = toRefs(commonBoxData)
//
var map
var opts = {
title: '',
}
const loadMap = (d) => {
for (const v of d) {
let points = new window.BMapGL.Point(v.y, v.x)
opts.title = v.title
let html = `
<p>服务商积分: ${v.integral}</p>
<p>星级: ${v.rating}</p>
<p>类型: ${v.pointType}</p>
<p>地址: ${v.location}</p>
<p>电话: ${v.phone}</p>
`
let markers = new window.BMapGL.Marker(points)
map.addOverlay(markers)
let infoWindow = new window.BMapGL.InfoWindow(html, opts)
markers.addEventListener('click', function () {
map.openInfoWindow(infoWindow, points)
})
}
}
const eDdxf = () => {
let data = commonBoxData.ddxf.chart
let xLabel = []
let valueData = []
for (let i of data) {
xLabel.push(i.name)
valueData.push(i.value)
}
let option = {
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(21, 44, 59,.9)',
borderColor: 'rgba(21, 44, 59,1)',
label: {
show: true,
},
textStyle: {
color: '#cff',
fontSize: 14,
},
padding: [12, 10],
extraCssText: 'z-index:10',
formatter: '{b0}: {c0}万元',
},
grid: {
top: '18%',
bottom: '5%',
left: '3%',
right: '4%',
containLabel: true,
},
toolbox: {
show: false,
},
xAxis: {
type: 'category',
data: xLabel,
axisLine: {
lineStyle: {
color: 'rgba(193, 207, 220, 1)',
},
},
axisLabel: {
color: '#afc3de',
},
},
yAxis: [
{
type: 'value',
name: '万元',
nameTextStyle: {
color: '#afc3de',
fontSize: 12,
},
axisLabel: {
color: '#afc3de',
},
axisLine: {
show: false,
lineStyle: {
color: '#cdd5e2',
},
},
splitLine: {
show: true,
lineStyle: {
color: '#afc3de',
},
},
},
],
series: [
{
name: '',
type: 'line',
data: valueData,
symbolSize: 10,
symbol: 'circle',
showSymbol: false,
smooth: false,
lineStyle: {
width: 2,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: 'RGBA(96, 122, 209, 1)',
},
{
offset: 1,
color: 'RGBA(96, 122, 209, 1)',
},
]),
shadowColor: 'RGBA(96, 122, 209, 0.4)',
shadowBlur: 10,
shadowOffsetY: 10,
},
itemStyle: {
color: 'rgba(167, 181, 230, 1)',
borderColor: '#afc3de',
borderWidth: 3,
shadowColor: 'rgba(167, 181, 230, 0.7)',
shadowBlur: 5,
},
areaStyle: {
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: 'RGBA(184, 204, 241, 1)',
},
{
offset: 0.5,
color: 'RGBA(184, 204, 241, 0.5)',
},
{
offset: 0.7,
color: 'RGBA(184, 204, 241, 0)',
},
],
false
),
shadowBlur: 0,
},
},
],
}
let myChart = echarts.init(ddxfRef.value)
myChart.clear()
myChart.setOption(option)
}
const eFwpc = () => {
let data = commonBoxData.fwpc.chart
let data1 = chartDate(8, 1)
let data2 = []
for (let i of data) {
data2.push(i.value)
}
let option = {
grid: {
top: '20%',
bottom: '6%',
left: '3%',
right: '6%',
containLabel: true,
},
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(21, 44, 59,.9)',
borderColor: 'rgba(21, 44, 59,1)',
label: {
show: true,
},
textStyle: {
color: '#cff',
fontSize: 14,
},
padding: [12, 10],
extraCssText: 'z-index:10',
formatter: '{b0}: {c0}次',
},
xAxis: {
type: 'category',
axisLine: {
show: true,
lineStyle: {
color: 'rgba(52, 51, 51, 1)',
},
},
splitLine: {
show: false,
},
axisLabel: {
fontSize: 12,
color: '#afc3de',
},
axisTick: {
show: false,
alignWithLabel: true,
},
boundaryGap: false,
data: data1,
},
yAxis: {
type: 'value',
name: '次',
nameTextStyle: {
fontFamily: 'MicrosoftYaHei',
fontSize: 12,
color: '#afc3de',
},
min: 0,
axisLine: {
show: false,
},
splitLine: {
show: true,
lineStyle: {
color: 'rgba(52, 51, 51, 0.8)',
},
},
axisLabel: {
show: true,
margin: 20,
fontFamily: 'MicrosoftYaHei',
fontSize: 12,
color: '#afc3de',
},
axisTick: {
show: false,
},
},
series: [
{
name: '积分数',
type: 'line',
showAllSymbol: true,
symbol: 'circle',
symbolSize: 5,
lineStyle: {
color: 'rgba(155, 155, 226, 1)',
},
label: {
show: false,
},
itemStyle: {
color: 'rgba(155, 155, 226, 0.8)',
borderColor: 'rgba(155, 155, 226, 0.8)',
borderWidth: 3,
},
areaStyle: {
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: 'rgba(155, 155, 226, 0.8)',
},
{
offset: 1,
color: 'rgba(155, 155, 226, 0)',
},
],
false
),
shadowColor: 'rgba(155, 155, 226, 0.8)',
shadowBlur: 20,
},
data: data2,
},
],
}
let myChart = echarts.init(fwpcRef.value)
myChart.clear()
myChart.setOption(option)
}
const eLxzb = () => {
let data = commonBoxData.lxzb.chart
let fucolor = ['#6e82b1', '#c465e0', '#ab98e8', '#47d3fa', '#cff0ff']
let option = {
tooltip: {
trigger: 'item',
backgroundColor: 'rgba(21, 44, 59,.9)',
borderColor: 'rgba(21, 44, 59,1)',
label: {
show: true,
},
textStyle: {
color: '#cff',
fontSize: 14,
},
padding: [12, 10],
extraCssText: 'z-index:10',
formatter: '{b} : {c}家 ({d}%)',
},
legend: {
orient: 'vertical',
top: 'center',
right: '5%',
itemGap: 15,
itemWidth: 16,
itemHeight: 16,
textStyle: {
color: '#697780',
fontSize: 14,
},
},
series: [
{
name: '',
type: 'pie',
radius: '81%',
center: ['36%', '50%'],
data: data,
label: {
show: false,
},
color: fucolor,
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)',
},
},
],
}
let myChart = echarts.init(lxzbRef.value)
myChart.clear()
myChart.setOption(option)
}
onMounted(() => {
eDdxf()
eFwpc()
eLxzb()
map = new window.BMapGL.Map('map')
map.setMapStyleV2({
styleId: '4a6029df2a52cd8be9496f0f2f47a1d4',
})
var point = new window.BMapGL.Point(121.879829, 29.472591)
map.centerAndZoom(point, 15)
map.setHeading(34.5)
map.setTilt(43)
map.enableScrollWheelZoom()
loadMap(mapPoints)
})
</script>
<style lang="less" scoped>
.main {
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
&-l,
&-r {
pointer-events: none;
> .commonBox {
pointer-events: all;
}
}
.main-r {
align-items: flex-end;
}
}
</style>

View File

@ -0,0 +1,72 @@
<template>
<div class="main">
<div id="map"></div>
<transition
:appear="true"
enter-active-class="animate__animated animate__fadeInLeft"
>
<div class="main-l">
<CommonBox title="标题1" height="280px"></CommonBox>
<CommonBox title="标题2" height="280px"></CommonBox>
</div>
</transition>
<transition
:appear="true"
enter-active-class="animate__animated animate__fadeInRight"
>
<div class="main-r">
<CommonBox title="标题3" height="280px"></CommonBox>
<CommonBox title="标题4" height="280px"></CommonBox>
</div>
</transition>
</div>
</template>
<script setup>
import { onMounted } from '@vue/runtime-core'
import mapJson from '@/assets/map/330225.json'
var map = null
var T = null
var polygon = null
const loadpolygon = (d, n) => {
let points = []
for (let v of d) points.push(new T.LngLat(v[0], v[1]))
polygon = new T.Polygon(points, {
name: n,
color: '#2D94E4',
weight: 1,
opacity: 0.6,
fillColor: '#ffffff',
fillOpacity: 0.3,
})
map.addOverLay(polygon)
}
const loadMapJson = () => {
let d = mapJson.features
for (let v of d) {
let pn = v.properties.name
let pd = v.geometry.coordinates
if (pd.length == 1) {
loadpolygon(pd[0], pn)
} else if (pd.length) {
for (let u of pd) loadpolygon(u[0], pn)
}
}
}
const showMap = () => {
T = window.T
map = new T.Map('map')
map.setMapType(window.TMAP_SATELLITE_MAP)
map.centerAndZoom(new T.LngLat(121.88, 29.38), 11)
}
onMounted(() => {
showMap()
loadMapJson()
})
</script>
<style lang="less" scoped>
#map {
width: 1920px;
height: 1080px;
}
</style>

View File

@ -0,0 +1,958 @@
<template>
<div class="main">
<transition :appear="true" enter-active-class="animate__animated animate__fadeInLeft">
<div class="main-l">
<CommonBox class="rytj" title="人员统计" flex="7">
<CommonList :listData="rytj.list" />
</CommonBox>
<CommonBox class="wyzt" title="文艺展厅" flex="6">
<div class="chart" ref="wyztRef" />
</CommonBox>
<CommonBox class="wydt" title="文艺动态" flex="8">
<CommonList :listData="wydt.list" />
</CommonBox>
</div>
</transition>
<transition :appear="true" enter-active-class="animate__animated animate__fadeIn">
<div class="main-c">
<CommonBox class="wyzp" title="文艺作品" flex="4" bg="cbg">
<img class="ball" :src="wyzp.ball" />
<span class="ball-title">2023</span>
<div class="ball-list">
<div v-for="(item, index) in wyzp.data" :key="index" :class="[
'ball-wrap',
index % 2 ? 'rightItem' : 'leftItem',
]">
<div class="ball-item">
<span class="ball-item-name">{{
item.name
}}</span>
<span class="ball-item-value">{{
item.value
}}</span>
<img class="ball-item-icon" :src="item.icon" />
</div>
</div>
</div>
</CommonBox>
<CommonBox class="dddt" title="点单大厅" flex="3">
<CommonList :listData="dddt.list" />
<div class="chart" ref="dddtRef" />
</CommonBox>
</div>
</transition>
<transition :appear="true" enter-active-class="animate__animated animate__fadeInRight">
<div class="main-r">
<CommonBox class="wyhd" title="文艺活动" flex="1" bg="bg4">
<CommonList :listData="wyhd.list" />
<div class="chart" ref="wyhdRef" />
</CommonBox>
<CommonBox title="热力值" flex="1" :boxData="rlz" @menuActive="changeMenu">
<div v-if="rlz.itemName === 'TOP5'" class="commonBox-item">
<div class="chart" ref="TOP5Ref" />
</div>
<div v-if="rlz.itemName === 'rmbq'" class="commonBox-item">
<div class="chart" ref="rmbqRef" />
</div>
</CommonBox>
<CommonBox class="wyyz" title="文艺援助" flex="1">
<div class="commonBox-item flex-1 flex-c">
<div class="wyyz-info flex-4 flex-r">
<div class="flex-1 flex-c">
<CommonList :listData="wyyz.list1" />
</div>
<div class="flex-2">
<div class="chart" ref="wyyzRef"></div>
</div>
</div>
<div class="wyyz-details flex-3">
<CommonList :listData="wyyz.list2" />
</div>
</div>
</CommonBox>
</div>
</transition>
</div>
</template>
<script setup>
import { reactive, ref, toRefs } from '@vue/reactivity'
import { nextTick, onMounted } from '@vue/runtime-core'
import { useStore } from 'vuex'
import * as echarts from 'echarts'
import 'echarts-liquidfill'
import 'echarts-wordcloud'
import { hook } from '@/hook/hook'
const { delay, boxMenu, propFuns, chartDate } = hook()
const wyztRef = ref(null)
const TOP5Ref = ref(null)
const rmbqRef = ref(null)
const wyhdRef = ref(null)
const dddtRef = ref(null)
const wyyzRef = ref(null)
const store = useStore()
const commonBoxData = reactive({
rytj: {
list: {
type: 'icon',
data: store.state.rytj,
},
},
wyzt: {
chart: store.state.wyzt,
},
wydt: {
list: {
type: 'scroll',
flex: [4, 1],
height: '260px',
header: [
{ headerName: '标题', key: 'title' },
{ headerName: '时间', key: 'time' },
],
data: store.state.wydt,
},
},
wyzp: {
ball: require('@/assets/img/ball.png'),
data: store.state.wyzp.stat,
},
wyhd: {
list: {
type: 'icon',
data: store.state.wyhd.list,
},
chart: store.state.wyhd.monChart,
},
wyyz: {
list1: {
type: 'icon',
data: [
{
name: '月援助人数',
value: '149',
unit: '人',
icon: require('@/assets/img/icon/icon1.webp'),
},
{
name: '总援助人数',
value: '6742',
unit: '人',
icon: require('@/assets/img/icon/icon1.webp'),
},
],
},
list2: {
type: 'swiper',
swiperView: '2',
height: '60px',
header: [
{ headerName: '申请用户', key: 'type' },
{ headerName: '申请用户', key: 'user' },
{ headerName: '申请时间', key: 'time' },
{ headerName: '进度', key: 'progressbar' },
],
data: store.state.wyyz,
},
},
rlz: {
name: 'rlz',
itemName: 'TOP5',
menu: [
{ name: 'TOP5', value: 'TOP5' },
{ name: '热门标签', value: 'rmbq' },
],
},
dddt: {
list: {
type: 'icon',
data: [
{
name: '需求数',
value: '2146',
unit: '个',
icon: require('@/assets/img/icon/icon1.webp'),
},
{
name: '实施率',
value: '87',
unit: '%',
icon: require('@/assets/img/icon/icon1.webp'),
},
{
name: '总接单人数',
value: '8764',
unit: '件',
icon: require('@/assets/img/icon/icon1.webp'),
},
],
},
chart: [
{
value: 501,
name: '作品求购',
},
{
value: 410,
name: '公益活动',
},
{
value: 501,
name: '演出表演',
},
{
value: 410,
name: '乡村剧场',
},
{
value: 501,
name: '其他',
},
],
},
})
const { rytj, wydt, wyzp, wyyz, rlz, wyhd, dddt } = toRefs(commonBoxData)
const eWyzt = () => {
const ColorList = ['#E8FF94', '#89FEBA', '#5EDCEB'] //
let arrayTemp = commonBoxData.wyzt.chart
let titleData = []
let series = []
arrayTemp.forEach((item, index) => {
const color = ColorList[index]
titleData.push({
text: item.name,
x: `${32 * index + 17}%`,
y: ' 80%',
textAlign: 'center',
textStyle: {
fontSize: '15',
color: color,
textAlign: 'center',
},
})
series.push({
type: 'liquidFill',
name: item.name,
radius: '56%',
center: [`${32 * index + 18}%`, '44%'],
data: [
{
value: 1,
itemStyle: {
color: 'transparent',
},
},
item.value / item.max,
],
backgroundStyle: {
color: 'transparent',
},
color: [color],
itemStyle: {
opacity: 0.6,
},
outline: {
borderDistance: 5,
itemStyle: {
borderWidth: 2,
borderColor: color,
shadowBlur: 10,
shadowColor: '#000',
},
},
label: {
position: ['50%', '50%'],
formatter: function () {
return `${item.value}`
},
fontSize: 36,
fontFamily: 'dsFont',
color: '#fff',
},
})
})
let option = {
title: titleData,
series: series,
}
let myChart = echarts.init(wyztRef.value)
myChart.clear()
myChart.setOption(option)
}
const eTOP5 = () => {
let datas = [
{
name: '抗疫',
value: 953,
},
{
name: '亚运',
value: 623,
},
{
name: '生活',
value: 510,
},
{
name: '美食',
value: 423,
},
{
name: '春游',
value: '263',
},
]
let data1 = [],
data2 = []
datas.forEach((value) => {
data1.push(value.name)
data2.push(value.value)
})
data1 = data1.reverse()
data2 = data2.reverse()
let option = {
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(21, 44, 59,.9)',
borderColor: 'rgba(21, 44, 59,1)',
label: {
show: true,
},
textStyle: {
color: '#ffffff',
fontSize: 14,
},
padding: [12, 10],
extraCssText: 'z-index:10',
},
grid: {
top: '4%',
bottom: '3%',
left: '5%',
right: '6%',
containLabel: true,
},
xAxis: {
type: 'value',
position: 'top',
splitLine: { show: false },
boundaryGap: [0, 0.01],
axisLine: {
show: false,
lineStyle: {
color: '#697780',
},
},
axisLabel: {
color: '#697780',
},
},
yAxis: {
axisLabel: {
rotate: 0,
color: '#697780',
},
axisLine: {
show: false,
},
type: 'category',
data: data1,
},
series: [
{
name: '热力值',
barWidth: '60%',
itemStyle: {
color: '#60C0DD',
shadowBlur: 5,
shadowColor: 'rgba(0, 0, 0, 0.5)',
},
type: 'bar',
data: data2,
},
],
}
let myChart = echarts.init(TOP5Ref.value)
myChart.clear()
myChart.setOption(option)
}
const eRmbq = () => {
let datas = [
{ name: '抗疫', value: 953 },
{ name: '亚运', value: 623 },
{ name: '生活', value: 510 },
{ name: '美食', value: 423 },
{ name: '春游', value: 263 },
{ name: '影视城', value: 214 },
{ name: '健身', value: 195 },
{ name: '网红', value: 164 },
{ name: '摄影', value: 84 },
{ name: '舞蹈', value: 41 },
]
let option = {
tooltip: {
backgroundColor: 'rgba(21, 44, 59,.9)',
borderColor: 'rgba(21, 44, 59,1)',
label: {
show: true,
},
textStyle: {
color: '#ffffff',
fontSize: 14,
},
padding: [12, 10],
extraCssText: 'z-index:10',
},
series: [
{
type: 'wordCloud',
//
gridSize: 45,
// circle cardioid diamond
// triangle-forward triangle star
shape: 'circle',
//
sizeRange: [16, 30],
//
// rotationRange: [0, 90],
rotationRange: [0, 0],
//
rotationStep: 90,
//
// maskImage: maskImage,
right: '0%',
top: '0%',
bottom: null,
//
width: '100%',
//
height: '100%',
//
drawOutOfBound: false,
textStyle: {
color: function () {
return (
'rgb(' +
[
Math.round(Math.random() * 100 + 55),
Math.round(Math.random() * 100 + 55),
Math.round(Math.random() * 100 + 55),
].join(',') +
')'
)
},
emphasis: {
shadowBlur: 10,
shadowColor: '#2ac',
},
},
data: datas,
},
],
}
let myChart = echarts.init(rmbqRef.value)
myChart.clear()
myChart.setOption(option)
}
const eWyhd = () => {
let data1 = chartDate(8, 1)
console.log('data1:', data1)
let data2 = []
for (let v of commonBoxData.wyhd.chart) {
data2.push(v.value)
}
let option = {
grid: {
top: '20%',
bottom: '16%',
left: '8%',
right: '2%',
},
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(21, 44, 59,.9)',
borderColor: 'rgba(21, 44, 59,1)',
label: {
show: true,
},
textStyle: {
color: '#ffffff',
fontSize: 14,
},
padding: [12, 10],
extraCssText: 'z-index:10',
formatter: '{a0}<br>{b0}: {c0}次',
},
xAxis: {
boundaryGap: true, //
axisLine: {
show: false,
},
splitLine: {
show: false,
},
axisLabel: {
interval: 0,
color: '#697780',
},
axisTick: {
show: false,
alignWithLabel: true,
},
data: data1,
},
yAxis: {
type: 'value',
name: '次数',
position: 'left',
show: true,
nameTextStyle: {
color: '#697780',
fontSize: '90%',
padding: [0, 0, 0, -45],
},
axisLine: {
show: false,
lineStyle: {
color: '#697780',
},
},
axisLabel: {
interval: 0,
color: '#697780',
},
splitLine: {
show: true,
lineStyle: {
type: 'dashed',
color: 'rgba(33,148,246,0.2)',
},
},
axisTick: {
show: false,
},
splitArea: {
show: false,
},
},
series: [
{
name: '举办次数',
type: 'line',
symbol: 'circle',
symbolSize: 7,
lineStyle: {
color: '#556bb9',
shadowBlur: 12,
shadowColor: 'rgb(33,148,246,0.9)',
shadowOffsetX: 1,
shadowOffsetY: 1,
},
itemStyle: {
color: '#556bb9',
borderWidth: 1,
borderColor: '#FFF',
},
label: {
show: false,
},
data: data2,
},
],
}
let myChart = echarts.init(wyhdRef.value)
myChart.clear()
myChart.setOption(option)
}
const eDddt = () => {
let data = commonBoxData.dddt.chart
let color = ['#9dabb4', '#54def5', '#47d3fa', '#79d9f1', '#00acee']
let baseData = []
for (let i = 0; i < data.length; i++) {
baseData.push({
value: data[i].value,
name: data[i].name,
itemStyle: {
borderWidth: 20,
shadowBlur: 50,
borderColor: color[i],
shadowColor: 'rgba(0, 0, 0, 0.8)',
},
})
}
let option = {
color: color,
tooltip: {
trigger: 'item',
backgroundColor: 'rgba(21, 44, 59,.9)',
borderColor: 'rgba(21, 44, 59,1)',
label: {
show: true,
},
textStyle: {
color: '#fff',
fontSize: 14,
},
padding: [12, 10],
extraCssText: 'z-index:10',
},
legend: {
orient: 'vertical',
top: '14%',
right: '5%',
itemGap: 15,
itemWidth: 16,
itemHeight: 16,
textStyle: {
color: '#697780',
fontSize: 14,
},
},
grid: {
top: 'bottom',
left: '90',
width: '90%',
height: '80%',
},
series: [
{
zlevel: 1,
name: '类型',
type: 'pie',
selectedMode: 'single',
radius: [84, 90],
center: ['36%', '50%'],
startAngle: '135',
label: {
show: false,
},
data: baseData,
},
],
}
let myChart = echarts.init(dddtRef.value)
myChart.setOption(option)
}
const eWyyz = () => {
let category = [
{
name: '月援助成功率',
value: 100,
},
{
name: '援助成功率',
value: 97,
},
] //
category = category.reverse()
let max = 100
let total = []
let datas = []
for (let v of category) {
datas.push(v.value)
total.push(max)
}
let option = {
xAxis: {
max: max,
splitLine: {
show: false,
},
axisLine: {
show: false,
},
axisLabel: {
show: false,
},
axisTick: {
show: false,
},
},
grid: {
left: '3%',
right: '7%',
top: '0%',
bottom: '14%',
},
yAxis: [
{
type: 'category',
inverse: false,
stack: '1',
data: category,
axisLine: {
show: false,
},
axisTick: {
show: false,
},
axisLabel: {
show: false,
},
},
],
series: [
{
//
type: 'bar',
stack: '1',
barWidth: 18,
silent: true,
itemStyle: {
color: '#28EAFD',
},
label: {
show: true,
position: 'right',
fontSize: 11,
color: '#fff',
padding: [0, 0, 0, -30],
rich: {
a: {
backgroundColor: {
image: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAUCAYAAAD/Rn+7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QzJGQTUxMzFGQ0M3MTFFQjg4QUNBRTRFRDBDQ0RBODEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QzJGQTUxMzJGQ0M3MTFFQjg4QUNBRTRFRDBDQ0RBODEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpDMjIzQzAzNEZDQzcxMUVCODhBQ0FFNEVEMENDREE4MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpDMkZBNTEzMEZDQzcxMUVCODhBQ0FFNEVEMENDREE4MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgnqNYIAAAHmSURBVHjaxJbLTsJQEIZnDmAxSsUNr+Fj4EKFjQuNQRMNKgroU5gYl6xELl633nYmujJx4wu48AnUWAzYcrHHOVqMIUBLgTLpnzbp9PTLnM4/xecad92W+dAwQhkAdGgeSOLgcLgBPO77CoeowsMBF0SIrtgmv0L6cpBP1jik3EEJv6Ij8Hih8bUAg0nHy9Riu951OM+M4xNyzqFIVIkC999U+JGMMD1IOFGggg7pfT/bnpKg9AMookyn1Q999K4MpyMIMzgAuBrpk0MmJWMy7MXSTzXrgPVYUnT5oQrHLoAZJ7dUE4Accnsybsx6Uf271wgoYuJFH6sCHNJlyAlA6lNRvfyOD9fnhlH7f481JoutpqMgikm67DecsAXyt9yuj8Ua4QyraRkKadm4DvWrITwIWfrm4iEJ1GY5zGSNN9IK6apPBcxIZCAhCT9bJTALi7ySFknXPYZLk5JUxVKtTRKzuJjY7vkeQmZI26SSWSLrYFExBhd6sN05UtwKXKeAIj5IkS66O0+KkVSrDzAbL7FrQTkDTuvkIWazEorR3VYhs6TNTirXLWC9u61YkGiIhBizdl7CuvzgzSzoQFiJ1YboB2A7CxKV2+oGruWoK/4Ob7BhQWekIOnEsBLVbNSZ/aJ/CzAAaE2fXTk9x2kAAAAASUVORK5CYII=',
},
fontSize: 12,
lineHeight: 20,
},
b: {
fontSize: 14,
lineHeight: 20,
padding: [0, 0, 0, -90],
},
},
formatter: (params) => {
return (
'\n\n\n\n\n\n{a|}\n' +
' {b|' +
params.name +
': ' +
params.value +
'%}'
)
},
},
data: category,
z: 1,
animationEasing: 'elasticOut',
},
{
//
type: 'pictorialBar',
itemStyle: {
color: '#0F2B57',
},
symbolRepeat: 'fixed',
symbolMargin: 10,
symbol: 'rect',
symbolClip: true,
symbolSize: [3, 18],
symbolPosition: 'start',
symbolOffset: [0, 0],
symbolBoundingData: total,
data: total,
z: 2,
animationEasing: 'elasticOut',
},
{
// label
type: 'pictorialBar',
symbolBoundingData: total,
itemStyle: {
color: 'none',
},
data: datas,
z: 0,
},
{
name: '外框',
type: 'bar',
barGap: '-100%',
data: total,
barWidth: 18,
itemStyle: {
color: '#144E76',
},
z: 0,
},
],
}
let myChart = echarts.init(wyyzRef.value)
myChart.clear()
myChart.setOption(option)
}
onMounted(() => {
nextTick(() => {
eWyzt()
eTOP5()
eWyhd()
eDddt()
eWyyz()
})
})
propFuns(commonBoxData)
const changeMenu = (n, r, s, p) => {
commonBoxData.rlz.itemName = r
if (r == 'TOP5') {
setTimeout(() => { eTOP5() }, 100)
} else if (r == 'rmbq') {
setTimeout(() => { eRmbq() }, 100)
}
}
</script>
<style lang="less" scoped>
@import "@/assets/theme/theme.less";
//
.rytj {
:deep(.list-icon) {
margin-top: 10px;
&-item {
margin-bottom: 6px;
}
}
}
//
.wyzp {
:deep(.commonBox-contain) {
position: relative;
background: url('../../../assets/img/bg_ball.png') no-repeat;
background-position: center center;
.ball {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -52%);
z-index: 0;
}
.ball-title {
position: absolute;
top: 47%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-flow: column nowrap;
text-align: center;
z-index: 2;
font-size: 26px;
font-family: dyFont;
font-weight: 400;
color: #fff;
line-height: 1.3;
}
.ball-list {
width: 100%;
margin-top: 120px;
box-sizing: border-box;
display: flex;
flex-flow: row wrap;
position: relative;
.ball-wrap {
width: 50%;
height: 70px;
margin-bottom: 42px;
box-sizing: border-box;
.ball-item {
background: url('../../../assets/img/w_ib.webp') no-repeat 0/100% 100%;
width: 245px;
height: 58px;
display: flex;
flex-flow: row nowrap;
align-items: center;
justify-content: space-between;
padding: 0 26px 0 14px;
box-sizing: border-box;
&-icon {
object-fit: cover;
}
&-name,
&-value {
display: inline-block;
}
&-name {
font-size: 14px;
font-family: Source;
font-weight: 400;
color: @darkColor;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
&-value {
order: -1;
font-size: 22px;
font-family: DIN Alternate Bold;
color: #d1f5ff;
}
}
&.leftItem {
padding-left: 38px;
}
&.rightItem {
padding-left: 88px;
.ball-item {
-moz-transform: rotateY(180deg);
transform: rotateY(180deg);
&-name,
&-value,
&-icon {
-moz-transform: rotateY(180deg);
transform: rotateY(180deg);
}
}
}
}
}
}
}
//
.dddt {
:deep(.list-icon) {
&-item {
width: 220px;
margin-left: 10px;
>div {
margin-left: 20px;
}
}
}
}
//
.wyhd {
:deep(.list-icon) {
&-item {
width: 130px;
}
}
}
//
.wyyz {
&-details {
margin-top: 10px;
}
}
</style>

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,398 @@
<template>
<div class="main">
<transition
:appear="true"
enter-active-class="animate__animated animate__fadeInLeft"
>
<div class="main-l">
<CommonBox
class="gqld"
title="公权力大数据监督"
width="555px"
height="260px"
:boxData="gqldData"
@menuActive="menuRadioActive"
@moreActive="moreBoxActive"
>
<div class="commonBox-content">
<div
v-if="gqldData.itemName === 'yghm'"
class="commonBox-content-item"
>
<div class="chart" ref="ecsRef"></div>
</div>
<div
v-if="gqldData.itemName === 'xwql'"
class="commonBox-content-item"
>
<div class="chart" ref="ecaRef"></div>
</div>
</div>
</CommonBox>
<CommonBox
class="zzdj"
title="组织建设"
width="555px"
height="374px"
:boxData="zzdjData"
@menuActive="menuRadioActive"
@moreActive="moreBoxActive"
>
<div class="commonBox-content">
<div
v-if="zzdjData.itemName === 'box1'"
class="commonBox-content-item"
>
box1
</div>
<div
v-if="zzdjData.itemName === 'box2'"
class="commonBox-content-item"
>
box2
</div>
</div>
</CommonBox>
<CommonBox title="意识形态" width="555px" height="346px">
<p>1412412</p>
</CommonBox>
</div>
</transition>
<transition
:appear="true"
enter-active-class="animate__animated animate__fadeIn"
>
<div class="main-c">
<CommonBox
title="工分+排名"
width="730px"
height="491px"
bg="cbg"
>
<p>1412412</p>
</CommonBox>
<CommonBox title="七张问题清单" width="730px" height="396px">
<p>1412412</p>
</CommonBox>
</div>
</transition>
<transition
:appear="true"
enter-active-class="animate__animated animate__fadeInRight"
>
<div class="main-r">
<CommonBox title="统一之家" flex="1">
<p>1412412</p>
</CommonBox>
<CommonBox title="民主法治" flex="1">
<p>1412412</p>
</CommonBox>
<CommonBox
title="群团组织"
flex="2"
:boxData="qtzzData"
@menuActive="menuRadioActive"
>
<div class="commonBox-content">
<div
v-if="qtzzData.itemName === 'list1'"
class="commonBox-content-item"
>
box1
</div>
<div
v-if="qtzzData.itemName === 'list2'"
class="commonBox-content-item"
>
box2
</div>
</div>
</CommonBox>
</div>
</transition>
<el-modal v-model:visible="showModal" title="标题" :footer="null">
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
<template #closeIcon>
<img src="@/assets/img/close.webp" />
</template>
</el-modal>
</div>
</template>
<script setup>
import * as echarts from 'echarts'
import { reactive, ref, toRefs, toRaw } from '@vue/reactivity'
import { onMounted } from '@vue/runtime-core'
import CommonBox from '../commonBox/CommonBox.vue'
import { hook } from '@/hook/hook'
const { delay } = hook()
//morename'',href,fn,
const commonBoxData = reactive({
gqldData: {
name: 'gqldData',
itemName: 'yghm',
more: {
name: '其他',
// href:'https://www.baidu.com/',
fn: 'gqld_a',
},
menu: [
{
name: '阳光惠民',
value: 'yghm',
choose: [
{
name: '2021年',
value: '2021',
},
{
name: '2022年',
value: '2022',
},
],
},
{
name: '小微权力',
value: 'xwql',
date: [
{
name: '1月',
datas: ['1', '2', '3'],
},
{
name: '2月',
datas: ['11', '22', '33'],
},
],
},
{
name: '外链',
value: 'wl',
href: 'http://220.191.238.2:998/zldn/',
},
],
},
zzdjData: {
name: 'zzdjData',
itemName: 'box1',
more: {
name: '更少',
href: 'https://wwww.baidu.com',
},
menu: [
{
name: '盒1',
value: 'box1',
},
{
name: '盒2',
value: 'box2',
date: [],
},
{
name: '转跳',
value: 'zt',
href: 'https://www.sogou.com/',
},
],
},
qtzzData: {
name: 'qtzzData',
itemName: 'list1',
menu: [
{
name: '列表1',
value: 'list1',
date: [],
},
{
name: '列表2',
value: 'list2',
},
],
},
})
const { gqldData, zzdjData, qtzzData } = toRefs(commonBoxData)
//echartdom
const ecsRef = ref(null)
const ecaRef = ref(null)
//flag
const showModal = ref(false)
//使d ||
const funs = {
yghm: function (d) {
delay(ecs)
},
xwql: function (d) {
delay(eca)
},
gqld_a: function (d) {
showModal.value = true
},
}
//nnamers,p
//sp
const menuRadioActive = (n, r, s, p) => {
s = s || '无'
p = p || '无'
console.log(n, r, s, p)
let d = s == '' ? p : s
let cbd = toRaw(commonBoxData)
for (let v in cbd) {
if (cbd[v].name === n) cbd[v].itemName = r
}
funs[r] && funs[r](d)
}
//
const moreBoxActive = (d) => {
funs[d] && funs[d](d)
}
const ecs = () => {
let option = {
title: {
show: true,
text: '党员民资占比', //
top: '50%',
left: '45%',
textAlign: 'center',
textStyle: {
fontSize: '14',
fontWeight: 'bold',
color: '#ffffff',
},
subtextStyle: {
fontSize: '20',
fontWeight: 'bold',
},
},
color: ['#FFFF00', '#0080FF'],
grid: {
left: 0,
// right: 0,
bottom: 0,
top: 0,
containLabel: true,
},
series: [
{
radius: ['70%', '80%'],
center: ['45%', '50%'],
type: 'pie',
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)', //
textColor: '#000',
normal: {
label: {
show: true,
textStyle: { fontSize: '16' },
formatter: function (val) {
//series
return val.name.split('-').join('\n')
},
},
labelLine: {
show: true,
},
},
},
data: [
{ name: '20%-少数民族', value: 20 },
{ name: '80%-汉族', value: 80 },
],
},
{
type: 'pie',
center: ['45%', '50%'],
radius: ['60%', '60%'],
data: [
{
value: 2,
name: '',
itemStyle: {
borderWidth: 2,
borderColor: '#61bad3',
},
},
],
},
],
}
let myChart = echarts.init(ecsRef.value)
myChart.clear()
myChart.setOption(option)
}
const eca = () => {
let option = {
grid: {
left: '8%',
right: '6%',
top: '10%',
bottom: '20%',
},
xAxis: {
type: 'category',
boundaryGap: false, //
axisTick: {
// x
show: false,
},
axisLabel: {
// x
margin: 15, // x
},
data: ['类型1', '类型2', '类型3', '类型4', '类型5', '类型6'],
},
yAxis: {
type: 'value',
// min: 0, // y
// max: 1800, // y
splitNumber: 9, // y
splitLine: {
// 线
show: true,
lineStyle: {
type: 'dotted', // dotted 线 solid 线
color: 'rgba(255, 255, 255,0.3)',
},
},
axisLabel: {
//y
formatter: '{value}',
color: '#A1A7B3',
fontSize: 14,
},
},
series: [
{
data: [200, 73, 110, 32, 125, 100],
type: 'line',
smooth: true, //
symbol: 'none', // ECharts 'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow', 'none' 'image://url' URL
// symbolSize: 8, //
lineStyle: {
//线
width: 5,
color: '#50e3c2',
type: 'solid', //线 dotted 线 solid 线 dashed 线
},
//
areaStyle: {
color: 'rgba(80, 227, 194, 0.3)',
},
},
],
}
let myChart = echarts.init(ecaRef.value)
myChart.clear()
myChart.setOption(option)
}
onMounted(() => {
ecs()
})
</script>
<style lang="less" scoped></style>

106
src/hook/hook.js Normal file
View File

@ -0,0 +1,106 @@
import { toRaw } from '@vue/reactivity'
export function hook() {
const delay = (f, d, t = 500) => {
setTimeout(() => f(d), t)
}
const chartDate = (n, type, flag) => {
let nowDate = new Date()
let dateArray = []
let nm = nowDate.getMonth() + 1 //nowDate.getMonth()默认从0开始定义nm获得正确的月份
if (!type) {
flag
? nowDate.setDate(nowDate.getDate() - n + 1)
: nowDate.setDate(nowDate.getDate() - n)
for (let i = 0; i < n; i++) {
let month = 0
let day = 0
nm < 10 ? (month = '0' + nm) : (month = nm)
nowDate.getDate() < 10
? (day = '0' + nowDate.getDate())
: (day = nowDate.getDate())
dateArray.push(month + '-' + day)
nowDate.setDate(nowDate.getDate() + 1)
}
} else if (type == 1) {
if (n) {
nm = flag ? nm + 1 : nm
for (let i = 0; i < n; i++) {
let k = nm - i - 1
k % 12 == 0
? dateArray.unshift('12月')
: k > 0
? dateArray.unshift(k + '月')
: dateArray.unshift(
12 * Math.ceil(Math.abs(k) / 12) + k + '月'
)
}
} else {
if (nm == 1) {
dateArray = flag
? ['1月']
: [
'1月',
'2月',
'3月',
'4月',
'5月',
'6月',
'7月',
'8月',
'9月',
'10月',
'11月',
'12月',
]
} else {
let i = flag ? 0 : 1
for (i; i < nm; i++) {
dateArray.unshift(nm - i + '月')
}
}
}
} else if (type == 2) {
let nowYear = nowDate.getFullYear()
nowYear = flag ? nowYear : nowYear - 1
for (let i = 0; i < n; i++) {
dateArray.unshift(nowYear - i)
}
}
return dateArray
}
const jsonSort = (array, field, reverse) => {
if (array.length < 2 || !field || typeof array[0] !== 'object')
return array
if (typeof array[0][field] === 'number') {
array.sort((x, y) => {
return y[field] - x[field]
})
}
if (typeof array[0][field] === 'string') {
array.sort((x, y) => {
return y[field].localeCompare(x[field])
})
}
if (reverse) array.reverse()
return array
}
var commonBoxData = null
var funs = null
const propFuns = (a = null, b = null) => {
commonBoxData = a
funs = b
}
const boxMenu = (n, r, s, p) => {
n &&
(() => {
let d = s == '' ? p : s
let cbd = toRaw(commonBoxData)
for (let v in cbd) if (v === n) cbd[v].itemName = r
funs[r] && funs[r](d)
})()
}
const boxMore = (d) => {
funs[d] && funs[d](d)
}
return { delay, boxMenu, boxMore, propFuns, chartDate, jsonSort }
}

View File

@ -29,6 +29,10 @@ import GrapeTableData from './views/grape/components/grapeTableData.vue';
import DialogUpload from './components/customs/dialogUpload.vue'
import DialogGoods from './components/customs/dialogGoods.vue'
import personQrcode from './views/grape/actions/personQrcode.vue';
import 'swiper/swiper-bundle.css'
import CommonBox from './components/lib/CommonBox.vue';
import CommonList from './components/lib/CommonList.vue';
import CommonTitle from './components/lib/CommonTitle.vue';
const app = createApp(App);
@ -59,6 +63,9 @@ app.component('GrapeTableData', GrapeTableData);
app.component('personQrcode', personQrcode);
app.component('dialogUpload', DialogUpload);
app.component('dialogGoods', DialogGoods);
app.component('CommonBox', CommonBox);
app.component('CommonList', CommonList);
app.component('CommonTitle', CommonTitle);
//注册全局指令
app.directive('auth', auth)

View File

@ -1,55 +1,95 @@
import Home from '@/components/view/lwt/Home'
import Yhhx from '@/components/view/lwt/Yhhx'
import Wyzp from '@/components/view/lwt/Wyzp'
import Wyhd from '@/components/view/lwt/Wyhd'
import Fwd from '@/components/view/lwt/Fwd'
import Dddt from '@/components/view/lwt/Dddt'
//系统路由
const routes = [{
name: "layout",
path: "/",
component: () => import(/* webpackChunkName: "layout" */ '@/layout'),
redirect: '/dashboard',
children: [
{
name: "home",
path: "/home",
component: () => import(`@/views/other/empty`),
meta: {
title: "首页",
icon: "el-icon-s-home"
},
children: [
{
name: "dashboard",
path: "/dashboard",
meta: {
title: "控制台",
icon: "el-icon-menu",
affix: true
},
component: () => import(/* webpackChunkName: "home" */ '@/views/home'),
},
{
name: "userCenter",
path: "/usercenter",
meta: {
title: "修改密码",
icon: "el-icon-user",
},
component: () => import(/* webpackChunkName: "usercenter" */ '@/views/userCenter'),
}
]
}
]
name: "layout",
path: "/",
component: () => import(/* webpackChunkName: "layout" */ '@/layout'),
redirect: '/dashboard',
children: [
{
name: "home",
path: "/home",
component: () => import(`@/views/other/empty`),
meta: {
title: "首页",
icon: "el-icon-s-home"
},
children: [
{
name: "dashboard",
path: "/dashboard",
meta: {
title: "控制台",
icon: "el-icon-menu",
affix: true
},
component: () => import(/* webpackChunkName: "home" */ '@/views/home'),
},
{
name: "userCenter",
path: "/usercenter",
meta: {
title: "修改密码",
icon: "el-icon-user",
},
component: () => import(/* webpackChunkName: "usercenter" */ '@/views/userCenter'),
}
]
}
]
},
{
path: "/login",
component: () => import(/* webpackChunkName: "login" */ '@/views/userCenter/login'),
meta: {
title: "登录"
}
path: "/login",
component: () => import(/* webpackChunkName: "login" */ '@/views/userCenter/login'),
meta: {
title: "登录"
}
},
{
path: "/force_password",
component: () => import('@/views/userCenter/forcePassword'),
meta: {
title: "重置密码"
}
path: "/cockpit",
component: () => import(/* webpackChunkName: "login" */ '@/views/cockpit'),
meta: {
title: "驾驶舱"
},
children: [
{
path: '/coHome',
component: Home,
},
{
path: '/yhhx',
component: Yhhx,
},
{
path: '/wyzp',
component: Wyzp,
},
{
path: '/wyhd',
component: Wyhd,
},
{
path: '/fwd',
component: Fwd,
},
{
path: '/dddt',
component: Dddt,
}
]
},
{
path: "/force_password",
component: () => import('@/views/userCenter/forcePassword'),
meta: {
title: "重置密码"
}
}
]

View File

@ -3,6 +3,7 @@
*/
import { createStore } from 'vuex';
import dayjs from 'dayjs'
const files = require.context('./modules', false, /\.js$/);
const modules = {}
@ -11,5 +12,412 @@ files.keys().forEach((key) => {
})
export default createStore({
modules
modules,
state: {
lastMonTime: dayjs().subtract(1, 'months'),
lastMon: dayjs().subtract(1, 'months').format('M月'),
pagePosition: {
defaultWidth: 1920,
defaultHeight: 1080,
scale: 1,
left: '0px',
top: '0px',
},
rytj: [
{
name: '平台用户总数',
value: '10649',
unit: '人',
icon: require('@/assets/img/icon/icon1.webp'),
},
{
name: '普通群众',
value: '76815',
unit: '人',
icon: require('@/assets/img/icon/icon1.webp'),
},
{
name: '文艺志愿者',
value: '17635',
unit: '人',
icon: require('@/assets/img/icon/icon1.webp'),
},
{
name: '协会会员',
value: '26699',
unit: '人',
icon: require('@/assets/img/icon/icon1.webp'),
},
{
name: '文艺人才',
value: '7883',
unit: '人',
icon: require('@/assets/img/icon/icon1.webp'),
},
{
name: '文艺名家',
value: '1944',
unit: '人',
icon: require('@/assets/img/icon/icon1.webp'),
},
{
name: '文联人员',
value: '833',
unit: '人',
icon: require('@/assets/img/icon/icon1.webp'),
},
{
name: '服务商',
value: '18862',
unit: '家',
icon: require('@/assets/img/icon/icon1.webp'),
},
{
name: '文联协会',
value: '12',
unit: '人',
icon: require('@/assets/img/icon/icon1.webp'),
},
],
wyyz: [
{
type: '文艺维权',
user: '韩佳琪',
time: '2022-08-29',
progressbar: '待办中',
},
{
type: '会员培训',
user: '屠郑振',
time: '2022-08-25',
progressbar: '处理中',
},
{
type: '艺术考级',
user: '董希贤',
time: '2022-08-20',
progressbar: '已解决',
},
{
type: '职称评审',
user: '徐宇晨',
time: '2022-08-19',
progressbar: '已解决',
},
{
type: '文艺维权',
user: '王梦莹',
time: '2022-08-14',
progressbar: '待办中',
},
{
type: '文艺维权',
user: '王美基',
time: '2022-08-08',
progressbar: '待办中',
},
{
type: '职称评审',
user: '林波君',
time: '2022-08-03',
progressbar: '处理中',
},
{
type: '艺术考级',
user: '胡剑略',
time: '2022-07-31',
progressbar: '已解决',
},
{
type: '文艺维权',
user: '李玲',
time: '2022-07-25',
progressbar: '待办中',
},
{
type: '会员培训',
user: '郑贤东',
time: '2022-07-20',
progressbar: '处理中',
},
],
wyzp: {
stat: [
{
name: '作品数量',
value: '203873',
unit: '个',
icon: require('@/assets/img/icon/icon_w.webp'),
},
{
name: '作者数量',
value: '56821',
unit: '人',
icon: require('@/assets/img/icon/icon_w.webp'),
},
{
name: '累计交易',
value: '34132',
unit: '次',
icon: require('@/assets/img/icon/icon_w.webp'),
},
{
name: '交易总额',
value: '1059172',
unit: '元',
icon: require('@/assets/img/icon/icon_w.webp'),
},
],
author: [
{
name: '作者总数',
value: '5.7',
unit: '万人',
icon: require('@/assets/img/icon/icon_w.webp'),
},
{
name: '作品总数',
value: '20.4',
unit: '万个',
icon: require('@/assets/img/icon/icon_w.webp'),
},
{
name: '月新增作者',
value: '23',
unit: '人',
icon: require('@/assets/img/icon/icon_w.webp'),
},
{
name: '月新增作品',
value: '159',
unit: '个',
icon: require('@/assets/img/icon/icon_w.webp'),
},
],
money: [
{
name: '累计交易',
value: '3.4',
unit: '万次',
icon: require('@/assets/img/icon/icon_w.webp'),
},
{
name: '交易总额',
value: '105.9',
unit: '万元',
icon: require('@/assets/img/icon/icon_w.webp'),
},
{
name: '当月交易',
value: '182',
unit: '次',
icon: require('@/assets/img/icon/icon_w.webp'),
},
{
name: '月交易额',
value: '1.2',
unit: '万元',
icon: require('@/assets/img/icon/icon_w.webp'),
},
],
},
wydt: [
{
title: '送万福,进万家,文艺惠民暖人心',
time: '2022-08-30',
},
{
title: '虎年新春活动再上央视《新闻联播》',
time: '2022-08-27',
},
{
title: '虎年新春活动再上央视《新闻联播》',
time: '2022-08-27',
},
{
title: '文联送欢乐,安置点享真情',
time: '2022-08-22',
},
{
title: '唱响象山“文艺春天”!',
time: '2022-08-20',
},
{
title: '摄影家协会公益拍照活动进行中',
time: '2022-08-17',
},
{
title: '祝贺迎亚运儿童画比赛圆满结束',
time: '2022-08-16',
},
{
title: '老年舞蹈队招新会举办在即',
time: '2022-08-14',
},
{
title: '文艺汇演活动走进丹东海山社区',
time: '2022-08-10',
},
{
title: '新时代五四青年文艺作品展在象举办',
time: '2022-08-05',
},
],
wyhd: {
list: [
{
name: '举办次数',
value: '171',
unit: '场',
icon: require('@/assets/img/icon/icon1.webp'),
},
{
name: '参与人数',
value: '1.3',
unit: '万人',
icon: require('@/assets/img/icon/icon1.webp'),
},
{
name: '支援人数',
value: '1225',
unit: '人',
icon: require('@/assets/img/icon/icon1.webp'),
},
{
name: '冠名单位',
value: '244',
unit: '家',
icon: require('@/assets/img/icon/icon1.webp'),
},
],
monChart: [
{
name: '1月',
value: 26,
},
{
name: '2月',
value: 18,
},
{
name: '3月',
value: 28,
},
{
name: '4月',
value: 9,
},
{
name: '5月',
value: 16,
},
{
name: '6月',
value: 20,
},
{
name: '7月',
value: 31,
},
{
name: '8月',
value: 23,
},
],
typeChart: [
{
value: 97,
name: '民俗',
},
{
value: 85,
name: '节庆',
},
{
value: 115,
name: '艺术',
},
{
value: 125,
name: '比赛',
},
{
value: 145,
name: '其他',
},
],
},
wyzt: [
{
value: 16,
name: '举办场次(次)',
max: 40,
},
{
value: 124,
name: '参展作品(件)',
max: 160,
},
{
value: 44926,
name: '累计观看(人次)',
max: 55000,
},
],
wyxx: {
iconList: [
{
name: '月下乡数',
value: '11',
unit: '次',
icon: require('@/assets/img/icon/icon1.webp'),
},
{
name: '总下乡数',
value: '493',
unit: '次',
icon: require('@/assets/img/icon/icon1.webp'),
},
{
name: '团队数',
value: '1225',
unit: '个',
icon: require('@/assets/img/icon/icon1.webp'),
},
{
name: '节目数',
value: '2.4',
unit: '万个',
icon: require('@/assets/img/icon/icon1.webp'),
},
],
dataList: [
{
wyTeam: '文化礼堂文艺团队',
wyShow: '《半岛新曲》',
startTime: '2023-01-27',
endTime: '2023-01-27',
},
{
wyTeam: '舞龙队、戏曲快闪',
wyShow: '《象山非遗新风貌》',
startTime: '2023-01-24',
endTime: '2023-01-24',
},
{
wyTeam: '西周镇土下村文艺团',
wyShow: '《快乐一家人》',
startTime: '2023-01-05',
endTime: '2023-01-05',
},
],
},
},
mutations: {
resizePage(state, d) {
state.pagePosition.scale = d.scale
state.pagePosition.left = d.left
state.pagePosition.top = d.top
},
},
});

101
src/views/cockpit/index.vue Normal file
View File

@ -0,0 +1,101 @@
<template>
<div
id="page"
ref="pageRef"
:style="[
{
'--scale': store.state.pagePosition.scale,
left: store.state.pagePosition.left,
top: store.state.pagePosition.top,
},
]"
>
<Header />
<Main />
<!-- <Foot /> -->
</div>
</template>
<script setup>
import Header from '@/components/Header.vue' // eslint-disable-line no-unused-vars
import Main from '@/components/Main.vue' // eslint-disable-line no-unused-vars
// import Foot from './components//Foot.vue'
import { onBeforeMount } from '@vue/runtime-core'
import { hook } from '@/hook/hook'
import { reactive } from 'vue'
import { useStore } from 'vuex'
const { delay } = hook()
const wPosition = reactive({
scale: 1,
left: 0,
top: 0,
})
const store = useStore()
const reset_window = async () => {
let width =
document.documentElement.clientWidth || document.body.clientWidth
let w1 = width / store.state.pagePosition.defaultWidth
let height =
document.documentElement.clientHeight || document.body.clientHeight
let h1 = height / store.state.pagePosition.defaultHeight
wPosition.scale = w1 > h1 ? h1 : w1
let w2 =
Math.abs(
(width - store.state.pagePosition.defaultWidth * wPosition.scale) /
2
) + 'px'
let h2 =
Math.abs(
(height -
store.state.pagePosition.defaultHeight * wPosition.scale) /
2
) + 'px'
wPosition.left = w1 > h1 ? w2 : 0
wPosition.top = w1 > h1 ? 0 : h2
store.commit('resizePage', wPosition)
}
onBeforeMount(() => {
reset_window()
})
var timer
window.onresize = () => {
if (timer) clearTimeout(timer)
delay(reset_window, null, 500)
}
</script>
<style lang="less" scoped>
#page {
background: #061119;
display: flex;
flex-direction: column;
box-sizing: border-box;
overflow: hidden;
width: 1920px !important;
height: 1080px !important;
position: absolute;
transform: scale(var(--scale));
transform-origin: 0 0;
transition: all 0.2s;
}
</style>
<style lang="less">
#app {
height: auto;
overflow: hidden;
}
#page {
z-index: 10000;
pointer-events: none;
> .header,
> main,
.commonBox {
pointer-events: all;
}
}
.anchorBL {
display: none;
}
</style>

6913
yarn.lock

File diff suppressed because it is too large Load Diff