新增自定义模板、监听尺寸变化动态缩放

des
吕天方 6 months ago
parent c77fe1cd93
commit 4a7156a4a4

@ -1,6 +1,6 @@
{
"name": "ruoyi",
"version": "1.0.202407240905",
"version": "1.0.202407251452",
"description": "金鸡湖现代服务业品牌管理系统",
"author": "若依",
"license": "MIT",
@ -53,6 +53,7 @@
"js-cookie": "3.0.1",
"jsencrypt": "3.0.0-rc.1",
"jspdf": "^2.5.1",
"lodash": "^4.17.21",
"nprogress": "0.2.0",
"quill": "1.3.7",
"screenfull": "5.0.2",

@ -1,28 +1,30 @@
<template>
<div id="app">
<router-view />
</div>
<ScaleBox>
<div id="app">
<router-view />
</div>
</ScaleBox>
</template>
<script>
import autofit from "autofit.js";
import ScaleBox from "@/components/scaleBox";
export default {
name: "App",
mounted() {
autofit.init({
dh: 919,
dw: 1920,
el: "#app",
resize: true,
// ignore:[
// {
// el:".ignoreElement",
// }
// ],
});
},
components:{ScaleBox},
// mounted() {
// autofit.init({
// dh: 919,
// dw: 1920,
// el: "#app",
// resize: true,
// // ignore:[
// // {
// // el:".ignoreElement",
// // }
// // ],
// });
// },
metaInfo() {
return {
title:

@ -1,5 +1,23 @@
import request from "@/utils/request"
// 数据云图项目追踪情况
export function servicesDevelop(params) {
return request({
url: "/jjh/dataScreen/servicesDevelop",
method: "get",
params
})
}
// 数据云图行业纵深情况
export function getIndustryDepth(params) {
return request({
url: "/jjh/dataScreen/getIndustryDepth",
method: "get",
params
})
}
// 数据云图荣誉情况
export function honor(params) {
return request({

@ -9,6 +9,15 @@ export function templateInfo(data) {
})
}
// 修改模板管理列表
export function templateInfoChange(data) {
return request({
url: '/system/templateInfo/edit',
method: 'post',
data
})
}
// 查询在线申报管理列表
export function listInfo(query) {
return request({

@ -1092,7 +1092,8 @@
//
.home-main {
padding: 10px;
height: calc(100% - 38%);
height: calc(100% - 32%);
// height: 100%;
overflow-y: scroll;
.main-row {
height: 100%;
@ -1323,7 +1324,8 @@
//
.dataCloudMap {
height: calc(100% - 55px);
// height: calc(100% - 55px);
height: 100%;
padding: 10px;
box-sizing: border-box;
background-color: #f1f5f8;
@ -1337,8 +1339,8 @@
flex-direction: column;
justify-content: space-between;
.dataCloudMap-left-top {
// height: 50%;
flex: 1;
height: 50%;
// flex: 1;
background-color: #fff;
border-radius: 10px;
padding: 10px 20px;
@ -1426,6 +1428,9 @@
}
}
}
.components-box {
height: 100%;
}
.echarts-data-box {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
@ -1491,7 +1496,7 @@
}
//
.dataCloudMap-left-bottom {
// height: 49%;
height: 49%;
margin-top: 10px;
background-color: #fff;
border-radius: 10px;
@ -1601,7 +1606,15 @@
height: 42%;
background-color: #fff;
border-radius: 10px;
padding: 10px 20px 15px;
// padding: 10px 20px 15px;
padding: 1vh 20px 1.5vh;
display: flex;
flex-direction: column;
// justify-content: space-between;
align-content: space-between;
.dataCloudMap-right-top-box {
flex: 1;
}
.right-top-title {
display: flex;
align-items: flex-end; /* 底部对齐 */
@ -1631,6 +1644,7 @@
}
.dataCloudMap-enterprise {
margin-top: 15px;
// margin-top: 2vh;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-column-gap: 10px;
@ -1638,10 +1652,10 @@
.el-card {
background-color: #fff;
border: none;
// height: 120px;
.el-card__header {
border-bottom: none;
padding: 10px 15px 3px;
// padding: 1vh 15px 1vh;
.clearfix {
text-align: center;
font-family: PingFang-SC, PingFang-SC;
@ -1652,10 +1666,12 @@
}
.el-card__body {
padding: 7px 20px 10px 20px;
// padding: 0.7vh 1vw 1.2vh 1vw;
}
.card-items {
margin-bottom: 10px;
margin-bottom: 0.5vw;
padding: 7px 10px;
// padding: 0.7vh 10px;
background-color: #F6F9FD;
display: flex;
justify-content: space-between;
@ -1666,6 +1682,7 @@
.card-img {
width: 15px;
height: 15px;
// height: 1.5vh;
background-image: url("../images/mapIconFour.png");
margin-right: 5px;
background-size: contain; /* 图片大小适应容器 */
@ -1674,6 +1691,7 @@
}
.card-type {
font-size: 12px;
// font-size: 1.5vh;
font-family: PingFang-SC, PingFang-SC;
font-weight: 500;
color: #666666;
@ -1692,6 +1710,7 @@
font-family: DINCondensed, DINCondensed;
font-weight: bold;
font-size: 26px;
// font-size: 2.6vh;
color: #0086FF;
margin-right: 5px;
cursor: pointer;
@ -1703,6 +1722,7 @@
font-family: PingFang-SC, PingFang-SC;
font-weight: bold;
font-size: 12px;
// font-size: 1.5vh;
color: #999999;
}
.number-two {
@ -1715,34 +1735,20 @@
}
.unit-two {
line-height: 24px;
// line-height: 2.4vh;
}
}
}
}
}
//
.dataCloudMap-enterprise-fullscreen {
.el-card {
.el-card__header {
.clearfix {
font-size: 18px;
}
}
.el-card__body {
padding: 14px 20px 20px;
}
.card-items {
padding: 10px 10px ;
margin-bottom: 20px;
}
}
}
.dataCloudMap-statistics {
margin-top: 15px;
// margin-top: 1.5vh;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
background: radial-gradient( 0% 0% at 0% 0%, #E8F3FC 0%, #F6F9FD 0%), #E8F3FC;
padding: 10px 0;
// padding: 1.5vh 1vh;
width: 100%;
.statistics-title {
display: flex;
@ -1751,6 +1757,7 @@
border-right: 1px solid #C7DAEE;
font-family: AlibabaPuHuiTiM;
font-size: 18px;
// font-size: 1.8vh;
color: #333333;
}
.statistics-items {
@ -1762,6 +1769,7 @@
.statistics-item-img {
width: 15px;
height: 15px;
// height: 1.5vh;
background-image: url("../images/mapIconSeven.png");
margin-right: 5px;
background-size: contain; /* 图片大小适应容器 */
@ -1778,6 +1786,7 @@
font-family: PingFang-SC, PingFang-SC;
font-weight: bold;
font-size: 15px;
// font-size: 1.5vh;
margin-right: 10px;
color: #666666;
}
@ -1788,6 +1797,7 @@
font-family: DINCondensed, DINCondensed;
font-weight: bold;
font-size: 26px;
// font-size: 2.6vh;
color: #0086FF;
margin-right: 5px;
cursor: pointer;
@ -1799,12 +1809,14 @@
font-family: PingFang-SC, PingFang-SC;
font-weight: bold;
font-size: 12px;
// font-size: 1.5vh;
line-height: 20px;
color: #999999;
.popover-Tooltip {
font-family: PingFang-SC-Medium;
font-weight: 500;
font-size: 5px;
// font-size: 0.7vh;
color: #333333;
}
}
@ -1818,6 +1830,7 @@
}
.unit-two {
line-height: 24px;
// line-height: 2.4vh;
position: relative;
img {
position: absolute;
@ -1843,6 +1856,7 @@
background-color: #fff;
border-radius: 10px;
padding: 10px 20px 20px;
// padding: 1vh 20px 2vh;
display: flex;
flex-direction: column;
.honor-title {
@ -1892,9 +1906,12 @@
}
.honor-data {
margin-top: 15px;
// margin-top: 2vh;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 15px;
// grid-column-gap: 1.5vh;
// grid-row-gap: 1.5vh;
// flex: 1;
// display: flex;
// flex-wrap: wrap;
@ -1904,6 +1921,7 @@
// width: 32%;
display: flex;
padding: 20px;
// padding: 2vh 1.5vw;
// padding: vh(25) vw(30);
align-items: center;
justify-content: space-between;
@ -1912,6 +1930,7 @@
font-family: PingFang-SC, PingFang-SC;
font-weight: bold;
font-size: 16px;
// font-size: 1.5vh;
color: #666666;
}
.honor-item-right {
@ -1921,6 +1940,7 @@
font-family: DINCondensed, DINCondensed;
font-weight: bold;
font-size: 26px;
// font-size: 2.6vh;
color: #0086FF;
margin-right: 5px;
}
@ -1928,24 +1948,13 @@
font-family: PingFang-SC, PingFang-SC;
font-weight: bold;
font-size: 12px;
// font-size: 1.5vh;
line-height: 24px;
// line-height: 2.4vh;
color: #999999;
}
}
}
//
.honor-item-fullscreen {
padding: 30px;
.honor-item-left {
font-size: 17px;
}
.honor-item-number {
font-size: 27px;
}
.honor-item-home {
font-size: 13px;
}
}
}
}
//

@ -0,0 +1,63 @@
<template>
<div v-bind:style="styleObject" class="scale-box">
<slot></slot>
</div>
</template>
<script>
import debounce from "lodash.debounce";
const that = this;
export default {
name:"ScaleBox",
components: {},
data() {
return {
width: 1920,
height: 911,
scaleX: null,
scaleY: null,
};
},
computed: {
styleObject() {
let obj = {
transform: `scale(${this.scaleX},${this.scaleY}) translate(-50%, -50%)`,
WebkitTransform: `scale(${this.scaleX},${this.scaleY}) translate(-50%, -50%)`,
width: this.width + "px",
height: this.height + "px",
margin: '-1px -1px 0 0',
};
return obj;
},
},
mounted() {
this.getScale();
window.addEventListener("resize", this.setScale);
},
methods: {
getScale() {
// XY
this.scaleX = window.innerWidth / this.width;
this.scaleY = window.innerHeight / this.height;
},
setScale: debounce(function () {
//
this.getScale();
}, 200),
},
beforeDestroy() {
window.addEventListener("resize", this.setScale);
},
};
</script>
<style scoped lang="scss">
.scale-box {
transform-origin: 0 0;
position: absolute;
left: 50%;
top: 50%;
transition: 0.3s;
}
</style>

@ -56,8 +56,10 @@ export default {
overflow: hidden;
}
.app-main-breadcrumb {
height: calc(100% - 1px);
padding: 0 0 10px 0;
// height: calc(100% - 1px);
height: calc(100% - 65px);
// padding: 0 0 10px 0;
padding: 0;
}
.fixed-header + .app-main {

@ -8,12 +8,13 @@ import { isRelogin } from "@/utils/request";
NProgress.configure({ showSpinner: false });
const whiteList = ["/login", "/register"];
const whiteList = ["/login", "/entLogin", "/register"];
router.beforeEach((to, from, next) => {
console.log(window.location.href);
NProgress.start();
if (window.location.href.includes("clienttoken=")) {
var reg = new RegExp(/[?&]clienttoken=([^&#]+)/);
if (window.location.href.includes("accesstoken=")) {
var reg = new RegExp(/[?&]accesstoken=([^&#]+)/);
var c = window.location.href.match(reg);
const clienttoken = c && c[1];
// console.log("clienttoken:", clienttoken);
@ -22,7 +23,7 @@ router.beforeEach((to, from, next) => {
store.dispatch("SingleSignOnGetInfo",{clientToken:clienttoken}).then(res => {
isRelogin.show = false;
let url = window.location.href;
var modifiedUrl = url.replace(/(\?appid&clienttoken=)[^&#]+/, '');
var modifiedUrl = url.replace(/(\&accesstoken=)[^&#]+/, '');
// console.log(modifiedUrl,'modifiedUrl');
window.location.href = modifiedUrl;
// store.dispatch("GenerateRoutes").then((accessRoutes) => {
@ -124,18 +125,16 @@ router.beforeEach((to, from, next) => {
// });
});
}
}
// else if(window.location.href.includes("clienttoken=")){
// }
else if (getToken()) {
} else if (getToken()) {
to.meta.title && store.dispatch("settings/setTitle", to.meta.title);
/* has token*/
if (to.path === "/login") {
if (to.path === "/entLogin") {
next({ path: "/" });
NProgress.done();
} else if (whiteList.indexOf(to.path) !== -1) {
next();
next({ path: "/" });
NProgress.done();
// next();
} else {
if (store.getters.roles.length === 0) {
isRelogin.show = true;
@ -166,7 +165,7 @@ router.beforeEach((to, from, next) => {
// 在免登录白名单,直接进入
next();
} else {
next(`/login?redirect=${encodeURIComponent(to.fullPath)}`); // 否则全部重定向到登录页
next(`/entLogin?redirect=${encodeURIComponent(to.fullPath)}`); // 否则全部重定向到登录页
NProgress.done();
}
// store.dispatch("LogOut").then(() => {

@ -46,6 +46,11 @@ export const constantRoutes = [
component: () => import("@/views/login"),
hidden: true,
},
{
path: "/entLogin",
component: () => import("@/views/entLogin"),
hidden: true,
},
{
path: "/register",
component: () => import("@/views/register"),

@ -0,0 +1,44 @@
//echarts专用求最大公约数 不含小数
export function chartlcm (a, b) {
var result = 1;
for (var i = 1; i <= a && i <= b; i++) {
if (a % i == 0 && b % i == 0) {
result = i;
}
if (result > 1 && i >= 10)//公约数大于10的时候 直接跳出 避免y轴刻度太多 (如果不介意刻度太多可以把这一段去掉)
break;
}
return result;
}
//获取echarts 多Y轴的最大值和间隔值 lcmval 最大公约数 divisor 间隔数量
export function YmaxvalAndinterval (m, n, lcmval, divisor) {
var interval1 = Math.ceil(m / lcmval);
var interval2 = Math.ceil(n / lcmval);
if (lcmval != 1 && lcmval != 0 && lcmval <= 10)
{
return { max1: m, max2: n, interval1: interval1, interval2: interval2 }
}
if (divisor == undefined || divisor == null)
divisor = 5;
//var mval = m % divisor;
//if (mval > 0) {
// m = ((m - mval) / divisor + 1) * divisor
//}
m = Math.ceil(m / divisor) * divisor
n = Math.ceil(n / divisor) * divisor
interval1 = Math.ceil(m / divisor );
interval2 = Math.ceil(n / divisor);
return { max1: m, max2: n, interval1: interval1, interval2: interval2 }
}

@ -22,7 +22,7 @@
height="550px"
> <!-- :max-height="tabHeader" -->
<el-table-column label="行业" prop="industry" width="300"/>
<el-table-column label="全年营收" prop="revenue" align="center"/>
<el-table-column label="全年营收(亿元)" prop="revenue" align="center"/>
<el-table-column label="增加值(亿元)" prop="valueAdded" align="center" />
<el-table-column label="增加值增速(按不变价)" prop="speedUp" align="center" />
<el-table-column label="增加值占GDP比重" prop="proportion" align="center" />

@ -0,0 +1,262 @@
<template>
<div class="components-box">
<div class="echarts-data-box">
<div class="E-box-item">
<div class="img-box-one img-box"></div>
<div class="data-box">
<div class="box-number">
<span class="number-yuan">{{ serviceData.valueAdded }}</span>
<span class="yuan-unit">亿元</span>
</div>
<div class="box-bottom">{{ serviceData.developYear }}服务业增加值</div>
</div>
</div>
<div class="E-box-item">
<div class="img-box-two img-box"></div>
<div class="data-box">
<div class="box-number">
<span class="number-yuan">{{ serviceData.increaseSpeed }}</span>
<span class="yuan-unit">%</span>
</div>
<div class="box-bottom">{{ serviceData.developYear }}服务业增速</div>
</div>
</div>
<div class="E-box-item">
<div class="img-box-three img-box"></div>
<div class="data-box">
<div class="box-number">
<span class="number-yuan">{{ serviceData.gdpProportion }}</span>
<span class="yuan-unit">%</span>
</div>
<div class="box-bottom">{{ serviceData.developYear }}服务业增加值占GDP比重</div>
</div>
</div>
</div>
<div id="echarts" ref="myChart"></div>
</div>
</template>
<script>
import * as echarts from "echarts";
import { servicesDevelop } from "@/api/jin_ji_hu/dataCloudMap"
import { chartlcm, YmaxvalAndinterval } from "@/utils/echart.js"
export default {
name:"echartData",
data() {
return {
myChart: false,
echartXdata:[],
echartYOnedata:[],
echartYTwodata:[],
serviceData:{
gdpProportion: 0,
increaseSpeed: 0,
quarterly: 0,
developYear: 0,
},
option: {
grid: {
top: "10%",
left: "5%",
right: "5%",
bottom: "8%", //leftright
},
xAxis: {
type: "category",
data: [],
axisLine: {
show: true, //X线
lineStyle: {
color: "#ccc",
opacity: 0.6,
},
},
axisTick: {
show: false, //X
},
axisLabel: {
show: true,
color: "#666666", //X
fontSize: 14,
},
},
yAxis: [
{
type: "value",
name:"增加值亿元",
nameTextStyle:{
padding: [0, 0, 0, -15],
},
min: 0,
max: 0,
interval: 0,
splitLine: {
show: true,
lineStyle :{
type: "dashed",
}
},
axisTick: {
show: false, //X
},
minorTick: {
show: false, //X
},
axisLabel: {
show: true,
color: "#666666",
fontSize: 12,
},
},
{
type: "value",
name:"增速%",
nameTextStyle:{
align:'center',
padding: [0, -15, 0, 0],
},
min: 0,
max: 0,
interval: 0,
splitLine: {
show: false,
lineStyle :{
type: "dashed",
}
},
axisTick: {
show: false, //X
},
minorTick: {
show: false, //X
},
axisLabel: {
show: true,
color: "#666666",
fontSize: 12,
},
},
],
series: [
{
name: "销售水量",
type: "line",
yAxisIndex: 1, //使 y index y
// smooth: true, //线 lineStyletypesolid
showAllSymbol: true, //
symbol: "circle", //
symbolSize: 10, //
itemStyle: {
//线
color: "#FFBB00",
borderColor: "#fff",
borderWidth: 2,
shadowColor: 'rgba(255, 187, 0, 0.7)',
shadowBlur: 10
},
lineStyle: {
type: "solid",
color: "#FFBB00",
shadowColor: 'rgba(255, 187, 0, 0.5)',
shadowBlur: 4
},
data:[]
},
{
name: "主营业务",
type: "bar",
barWidth: 25,
itemStyle: {
color: "#0086FF",
},
data:[]
},
],
}
}
},
props:{
activeIndex:{
type:Number,
default:1
}
},
mounted(){
this.$nextTick(()=>{
this.initEchart();
})
setTimeout(()=>{
this.getService(1);
},200)
},
methods:{
initEchart(){
var chartDom = document.getElementById("echarts");
this.myChart = echarts.init(chartDom);
this.myChart.setOption(this.option)
},
//
getService(activeIndex){
servicesDevelop({type:activeIndex}).then(res=>{
if(activeIndex == 1) {
this.option.xAxis.data = []
this.option.series[0].data = []
this.option.series[1].data = []
res.data.map(item=>{
this.option.xAxis.data.push(item.developYear)
this.option.series[1].data.push(item.valueAdded)
this.option.series[0].data.push(item.increaseSpeed)
})
const maxY1 = Math.max.apply(null, this.option.series[0].data);
const maxY2 = Math.max.apply(null, this.option.series[1].data);
let divisor = 5;
let lcmVal = chartlcm(maxY1, maxY2)
let Ymaxval_interval = YmaxvalAndinterval(maxY1, maxY2, lcmVal, divisor);
this.option.yAxis[0].max = Ymaxval_interval.max2;
this.option.yAxis[0].interval = Ymaxval_interval.interval2;
this.option.yAxis[1].max = Ymaxval_interval.max1;
this.option.yAxis[1].interval = Ymaxval_interval.interval1;
this.serviceData = {
valueAdded: res.data[res.data.length - 1].valueAdded,
increaseSpeed: res.data[res.data.length - 1].increaseSpeed,
gdpProportion: res.data[res.data.length - 1].gdpProportion,
developYear: res.data[res.data.length - 1].developYear,
}
} else {
this.option.xAxis.data = []
this.option.series[0].data = []
this.option.series[1].data = []
this.option.xAxis.data = ["第一季度","第二季度","第三季度","第四季度"]
let arr = [0,0,0,0]
let arrTwo = [0,0,0,0]
res.data.map((item,index)=>{
arr[index] = item.valueAdded
arrTwo[index] = item.increaseSpeed
this.option.series[1].data = arr
this.option.series[0].data = arrTwo
})
const maxY1 = Math.max.apply(null, this.option.series[0].data);
const maxY2 = Math.max.apply(null, this.option.series[1].data);
let divisor = 5;
let lcmVal = chartlcm(maxY1, maxY2)
let Ymaxval_interval = YmaxvalAndinterval(maxY1, maxY2, lcmVal, divisor);
this.option.yAxis[0].max = Ymaxval_interval.max2;
this.option.yAxis[0].interval = Ymaxval_interval.interval2;
this.option.yAxis[1].max = Ymaxval_interval.max1;
this.option.yAxis[1].interval = Ymaxval_interval.interval1;
this.serviceData = {
valueAdded: res.data[res.data.length - 1].valueAdded,
increaseSpeed: res.data[res.data.length - 1].increaseSpeed,
gdpProportion: res.data[res.data.length - 1].gdpProportion,
developYear: res.data[res.data.length - 1].developYear,
}
}
this.myChart.setOption(this.option);
})
},
},
}
</script>
<style lang="scss" scoped>
</style>

@ -18,48 +18,16 @@
class="tabStyle"
v-for="(item, index) in options1"
:key="index"
@click="active(index)"
:class="activeIndex == index ? 'change-blue' : ''"
@click="active(index + 1)"
:class="activeIndex == index + 1 ? 'change-blue' : ''"
>
<div class="change-grey-birght" :class="activeIndex == index ? 'change-blue-birght' : ''"></div>
<span class="change-grey-text" :class="activeIndex == index ? 'change-blue-text' : ''">{{ item.name }}</span>
<div class="change-grey-birght" :class="activeIndex == index + 1 ? 'change-blue-birght' : ''"></div>
<span class="change-grey-text" :class="activeIndex == index + 1 ? 'change-blue-text' : ''">{{ item.name }}</span>
</div>
</div>
</div>
</div>
<div class="echarts-data-box">
<div class="E-box-item">
<div class="img-box-one img-box"></div>
<div class="data-box">
<div class="box-number">
<span class="number-yuan">1758.13</span>
<span class="yuan-unit">亿元</span>
</div>
<div class="box-bottom">2023服务业增加值</div>
</div>
</div>
<div class="E-box-item">
<div class="img-box-two img-box"></div>
<div class="data-box">
<div class="box-number">
<span class="number-yuan">1.3</span>
<span class="yuan-unit">%</span>
</div>
<div class="box-bottom">2023服务业增速</div>
</div>
</div>
<div class="E-box-item">
<div class="img-box-three img-box"></div>
<div class="data-box">
<div class="box-number">
<span class="number-yuan">49.9</span>
<span class="yuan-unit">%</span>
</div>
<div class="box-bottom">2023服务业增加值占GDP比重</div>
</div>
</div>
</div>
<div id="echarts" ref="myChart"></div>
<echartData :activeIndex="activeIndex" ref="echartData"/>
</div>
<!-- 行业纵深情况 -->
@ -76,33 +44,37 @@
</div>
<section>
<el-table v-loading="loadingOne" class="dataMap-two-table" :data="tableOneData" :row-class-name="tableRowClassName" :header-cell-style="{background:'#E8F3FC'}"> <!-- :max-height="tabHeader" -->
<el-table-column label="行业大类" prop="bigType" width="320" align="center"/>
<el-table-column label="全年营收" prop="revenue" width="130" align="center">
<el-table-column label="行业大类" prop="industryCategories" align="center"/>
<el-table-column label="全年营收" prop="yearRevenue" align="center">
<template slot="header" slot-scope="scope">
<div class="Table-header">全年营收</div>
<span class="Table-unit">(亿元)</span>
</template>
<template slot-scope="scope">
<div class="project-trace-table-number">{{ scope.row.revenue }}</div>
<div class="project-trace-table-number">{{ scope.row.yearRevenue }}</div>
</template>
</el-table-column>
<el-table-column label="增加值(亿元)" prop="yuan" width="100" align="center">
<el-table-column label="增加值(亿元)" prop="addValue" align="center">
<template slot="header" slot-scope="scope">
<div class="Table-header">增加值</div>
<span class="Table-unit">(亿元)</span>
</template>
<template slot-scope="scope">
<div class="project-trace-table-number">{{ scope.row.yuan }}</div>
<div class="project-trace-table-number">{{ scope.row.addValue }}</div>
</template>
</el-table-column>
<el-table-column label="增加值增速(按不变价)" prop="speedUp" width="180" align="center">
<el-table-column label="增加值增速(按不变价)" prop="growth" align="center">
<template slot="header" slot-scope="scope">
<div class="Table-header">增加值增速</div>
<span class="Table-unit">(按不变价)</span>
</template>
<template slot-scope="scope">
<div class="project-trace-table-number">{{ scope.row.speedUp }} <span>%</span></div>
<div class="project-trace-table-number">{{ scope.row.growth }} <span>%</span></div>
</template>
</el-table-column>
<el-table-column label="增加值占GDP比重" prop="proportion" align="center">
<el-table-column label="增加值占GDP比重" prop="gdpProportion" align="center" width="100">
<template slot-scope="scope">
<div class="project-trace-table-number">{{ scope.row.proportion }} <span>%</span></div>
<div class="project-trace-table-number">{{ scope.row.gdpProportion }} <span>%</span></div>
</template>
</el-table-column>
</el-table>
@ -112,6 +84,8 @@
<el-col :span="13" class="dataCloudMap-main-right">
<!-- 企业情况 -->
<div class="dataCloudMap-right-top">
<!-- <div class="dataCloudMap-right-top-box">
</div> -->
<div class="right-top-title">
<div class="L-title-left">
<span class="dataCloudMap-birght"></span>
@ -119,7 +93,7 @@
</div>
<span class="dataCloudMap-data">统计数据截至2024-01</span>
</div>
<div class="dataCloudMap-enterprise" :class="isFullscreen ? 'dataCloudMap-enterprise-fullscreen' : ''">
<div class="dataCloudMap-enterprise">
<!-- 第一个卡片 -->
<el-card shadow="always">
<div slot="header" class="clearfix">
@ -342,42 +316,42 @@
<div class="rightBtn" @click="honorBtn">>></div>
</div>
<div class="honor-data">
<div class="honor-item" :class="isFullscreen ? 'honor-item-fullscreen' : ''">
<div class="honor-item">
<span class="honor-item-left">领军企业</span>
<div class="honor-item-right">
<span class="honor-item-number">{{ honorData.count1 }}</span>
<span class="honor-item-home"></span>
</div>
</div>
<div class="honor-item" :class="isFullscreen ? 'honor-item-fullscreen' : ''">
<div class="honor-item">
<span class="honor-item-left">两业融合试点</span>
<div class="honor-item-right">
<span class="honor-item-number">{{ honorData.count2 }}</span>
<span class="honor-item-home"></span>
</div>
</div>
<div class="honor-item" :class="isFullscreen ? 'honor-item-fullscreen' : ''">
<div class="honor-item">
<span class="honor-item-left">工业设计</span>
<div class="honor-item-right">
<span class="honor-item-number">{{ honorData.count3 }}</span>
<span class="honor-item-home"></span>
</div>
</div>
<div class="honor-item" :class="isFullscreen ? 'honor-item-fullscreen' : ''">
<div class="honor-item">
<span class="honor-item-left">服务型制造示范</span>
<div class="honor-item-right">
<span class="honor-item-number">{{ honorData.count4 }}</span>
<span class="honor-item-home"></span>
</div>
</div>
<div class="honor-item" :class="isFullscreen ? 'honor-item-fullscreen' : ''">
<div class="honor-item">
<span class="honor-item-left">现代服务业集聚区</span>
<div class="honor-item-right">
<span class="honor-item-number">{{ honorData.count5 }}</span>
<span class="honor-item-home"></span>
</div>
</div>
<div class="honor-item" :class="isFullscreen ? 'honor-item-fullscreen' : ''">
<div class="honor-item">
<span class="honor-item-left">楼宇经济</span>
<div class="honor-item-right">
<span class="honor-item-number">{{ honorData.count6 }}</span>
@ -388,8 +362,8 @@
</div>
<!-- 项目追踪情况 -->
<div class="dataCloudMap-right-bottom">
<div class="project-trace-title">
<div class="dataCloudMap-right-bottom" id="dataCloudMap-right-box">
<div class="project-trace-title" id="project-trace-title-id">
<div class="right-bottom-title">
<div class="L-title-left">
<span class="dataCloudMap-birght"></span>
@ -400,7 +374,7 @@
<div class="rightBtn" @click="projectBtn">>></div>
</div>
<section>
<el-table v-loading="loadingTwo" class="dataMap-two-table" :data="tableTwoData" :row-class-name="tableRowClassName" :height="isFullscreen ? 220 : 170" :header-cell-style="{background:'#E8F3FC'}"> <!-- :max-height="tabHeader" -->
<el-table v-loading="loadingTwo" class="dataMap-two-table" :data="tableTwoData" :row-class-name="tableRowClassName" :height="tabHeader" :header-cell-style="{background:'#E8F3FC'}"> <!-- :max-height="tabHeader" -->
<el-table-column label="申报任务名称" prop="enterpriseDirectory" width="500" align="center"/>
<el-table-column label="填报时间" prop="time" align="center">
<template slot-scope="scope">
@ -425,18 +399,17 @@
</div>
</template>
<script>
import screenfull from 'screenfull'
import * as echarts from "echarts";
import honorDialogVue from './components/honorDialog.vue';
import headqEnterprise from './components/headquarterEnterprise.vue'
import serviceIndustry from './components/serviceIndustry.vue'
import collectDialog from './components/collectDialog.vue'
import { honor, projectTracking } from "@/api/jin_ji_hu/dataCloudMap"
import echartData from './components/echartData.vue'
import { honor, projectTracking, getIndustryDepth } from "@/api/jin_ji_hu/dataCloudMap"
export default {
components:{honorDialogVue,headqEnterprise,serviceIndustry,collectDialog},
components:{honorDialogVue,headqEnterprise,serviceIndustry,collectDialog,echartData},
data() {
return {
activeIndex:0,
activeIndex:1,
options1: [
{
name: "按年",
@ -450,48 +423,7 @@ export default {
},
],
loadingOne: false,
tableOneData: [
{
bigType:"科学研究和技术服务业",
revenue:"506.63",
yuan:"201",
speedUp:"0.89",
proportion:"11",
},
{
bigType:"科学研究和技术服务业",
revenue:"506.63",
yuan:"201",
speedUp:"0.89",
proportion:"11",
},{
bigType:"科学研究和技术服务业",
revenue:"506.63",
yuan:"201",
speedUp:"0.89",
proportion:"11",
},
{
bigType:"科学研究和技术服务业",
revenue:"506.63",
yuan:"201",
speedUp:"0.89",
proportion:"11",
},{
bigType:"科学研究和技术服务业",
revenue:"506.63",
yuan:"201",
speedUp:"0.89",
proportion:"11",
},
{
bigType:"科学研究和技术服务业",
revenue:"506.63",
yuan:"201",
speedUp:"0.89",
proportion:"11",
}
],
tableOneData: [],
loadingTwo: false,
tableTwoData: [],
honorData: {
@ -504,58 +436,21 @@ export default {
},
honorTableData:[],
titleDialog:"",
isFullscreen: false,
myChart: false,
option:{}
tabHeader: undefined,
}
},
mounted(){
this.$nextTick(()=>{
this.initEchart();
})
this.getHonorList();
this.getProjectList();
this.screenFull();
this.getHonorList();
this.getIndustryDepthList();
// this.init()
this.cancalDebounce();
window.addEventListener('resize', this.cancalDebounce);
},
beforeDestroy() {
window.removeEventListener('keydown', this.KeyDown);
this.destroy()
window.removeEventListener('resize', this.cancalDebounce);
},
methods:{
change() {
this.isFullscreen = screenfull.isFullscreen;
// this.myChart.setOption(this.option)
window.onresize = this.myChart.resize;
// setTimeout(()=>{
// this.myChart && this.myChart.resize()
// },200)
// this.myChart.clear()
},
screenFull() {
window.addEventListener('keydown', this.KeyDown);
if (screenfull.isEnabled) {
screenfull.on('change', this.change)
}
},
destroy() {
if (screenfull.isEnabled) {
screenfull.off('change', this.change)
}
},
KeyDown(event) {
if (event.keyCode === 122) {
event.preventDefault();
// this.isScreenFull();
if (!screenfull.isEnabled) {
this.$message({ message: '你的浏览器不支持全屏', type: 'warning' })
return false
}
screenfull.toggle()
}
},
//
getHonorList(){
honor().then(res=>{
@ -577,6 +472,14 @@ export default {
})
})
},
//
getIndustryDepthList(){
this.loadingOne = true;
getIndustryDepth().then(res=>{
this.loadingOne = false;
this.tableOneData = res.data
})
},
//
getProjectList(){
this.loadingTwo = true;
@ -585,137 +488,7 @@ export default {
this.tableTwoData = res.data;
})
},
initEchart(){
var chartDom = document.getElementById("echarts");
this.myChart = echarts.init(chartDom);
this.option = {
// title: {
// text: "2019",
// textStyle: {
// align: "center",
// color: "#fff",
// fontSize: 20,
// },
// top: "3%",
// left: "10%",
// },
grid: {
top: "3%",
left: "3%",
right: "3%",
bottom: "8%", //leftright
},
// tooltip: {
// trigger: "axis",
// axisPointer: {
// type: "shadow",
// label: {
// show: true,
// },
// },
// },
// legend: {
// data: ["", ""],
// top: "1%",
// textStyle: {
// // color: "#ffffff",
// },
// },
xAxis: {
data: [
"2019",
"2020",
"2021",
"2022",
"2023",
"2024",
],
axisLine: {
show: true, //X线
lineStyle: {
color: "#ccc",
opacity: 0.6,
},
},
axisTick: {
show: false, //X
},
axisLabel: {
show: true,
color: "#666666", //X
fontSize: 14,
},
},
yAxis: [
{
type: "value",
splitLine: {
show: true,
lineStyle :{
type: "dashed",
}
},
axisLabel: {
show: true,
color: "#666666",
fontSize: 12,
},
},
],
series: [
{
name: "销售水量",
type: "line",
// yAxisIndex: 1, //使 y index y
// smooth: true, //线 lineStyletypesolid
showAllSymbol: true, //
symbol: "circle", //
symbolSize: 10, //
itemStyle: {
//线
color: "#FFBB00",
borderColor: "#fff",
borderWidth: 2,
shadowColor: 'rgba(255, 187, 0, 0.7)',
shadowBlur: 10
},
lineStyle: {
type: "solid",
color: "#FFBB00",
shadowColor: 'rgba(255, 187, 0, 0.5)',
shadowBlur: 4
},
// 线
// areaStyle: {
// color: "rgba(5,140,255, 0.2)",
// },
data: [4.8, 4.4, 5.4, 4.1, 3.6, 3.4],
},
{
name: "主营业务",
type: "bar",
barWidth: 25,
itemStyle: {
// normal: {
// color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
// {
// offset: 0,
// color: "#00FFE3",
// },
// {
// offset: 1,
// color: "#4693EC",
// },
// ]),
// },
color: "#0086FF",
},
data: [4.2, 3.8, 4.8, 3.5, 2.9, 2.8, 3, 5],
},
],
};
this.myChart.setOption(this.option)
},
//
honorBtn(){
this.$refs.honorDialog.open(this.honorTableData);
@ -740,6 +513,7 @@ export default {
},
active(e) {
this.activeIndex = e;
this.$refs.echartData.getService(e);
},
// table
tableRowClassName({row, rowIndex}){
@ -748,6 +522,14 @@ export default {
}
return '';
},
//
cancalDebounce(){
const element = document.getElementById('dataCloudMap-right-box'); // ID
const header = document.getElementById('project-trace-title-id'); // ID
const elementHeight = element.offsetHeight;
const headerHeight = header.offsetHeight;
this.tabHeader = elementHeight - headerHeight - 40;
}
},
}
</script>

@ -0,0 +1,317 @@
<template>
<div class="login">
<el-form
ref="loginForm"
:model="loginForm"
:rules="loginRules"
class="login-form"
>
<!-- <h3 class="title">若依后台管理系统</h3> -->
<el-tabs v-model="userType" @tab-click="handleClick">
<el-tab-pane label="企业用户登录" name="01"></el-tab-pane>
<el-tab-pane label="政务用户登录" name="02"></el-tab-pane>
</el-tabs>
<el-form-item prop="username" v-show="userType == '02'">
<el-input
v-model="loginForm.username"
type="text"
auto-complete="off"
placeholder="账号"
>
<svg-icon
slot="prefix"
icon-class="user"
class="el-input__icon input-icon"
/>
</el-input>
</el-form-item>
<el-form-item prop="password" v-show="userType == '02'">
<el-input
v-model="loginForm.password"
type="password"
auto-complete="off"
placeholder="密码"
@keyup.enter.native="handleLogin"
>
<svg-icon
slot="prefix"
icon-class="password"
class="el-input__icon input-icon"
/>
</el-input>
</el-form-item>
<el-form-item prop="code" v-if="captchaEnabled && userType == '02'">
<el-input
v-model="loginForm.code"
auto-complete="off"
placeholder="验证码"
style="width: 63%"
@keyup.enter.native="handleLogin"
>
<svg-icon
slot="prefix"
icon-class="validCode"
class="el-input__icon input-icon"
/>
</el-input>
<div class="login-code">
<img :src="codeUrl" @click="getCode" class="login-code-img" />
</div>
</el-form-item>
<el-checkbox
v-model="loginForm.rememberMe"
v-show="userType == '02'"
style="margin: 0px 0px 25px 0px"
>记住密码</el-checkbox
>
<el-form-item style="width: 100%" v-if="userType == '02'">
<el-button
:loading="loading"
size="medium"
type="primary"
style="width: 100%"
@click.native.prevent="handleLogin"
>
<span v-if="!loading"> </span>
<span v-else> ...</span>
</el-button>
<el-button
size="medium"
type="primary"
style="width: 100%;margin-left: 0;margin-top: 20px;"
@click.native.prevent="changeHttp"
>
<span>政务通统一身份认证登录</span>
<!-- <span v-else> ...</span> -->
</el-button>
<div style="float: right" v-if="register">
<router-link class="link-type" :to="'/register'"
>立即注册</router-link
>
</div>
</el-form-item>
<el-form-item style="width: 100%" v-else class="enterBtnLogin">
<div class="wai-box">
<el-button
:loading="loading"
size="medium"
type="primary"
style="width: 100%"
@click.native.prevent="handleLogin"
>
<span v-if="!loading"></span>
<span v-else> ...</span>
</el-button>
</div>
</el-form-item>
</el-form>
<!-- 底部 -->
<!-- <div class="el-login-footer">
<span>Copyright © 2018-2024 ruoyi.vip All Rights Reserved.</span>
</div> -->
<!-- 正式环境部署命令 unzip /var/www/html/dist.zip -d /var/www/html/bms -->
<!-- process.env.VUE_APP_BASE_API 替换 location.origin + '/api' publicPath /dome/JinJiHu 更换为./ -->
</div>
</template>
<script>
import { getCodeImg } from "@/api/login";
import Cookies from "js-cookie";
import { encrypt, decrypt } from "@/utils/jsencrypt";
export default {
name: "Login",
data() {
return {
codeUrl: "",
loginForm: {
username: "", // admin
password: "", // admin123
rememberMe: false,
code: "",
uuid: "",
},
loginRules: {
username: [
{ required: true, trigger: "blur", message: "请输入您的账号" },
],
password: [
{ required: true, trigger: "blur", message: "请输入您的密码" },
],
code: [{ required: true, trigger: "change", message: "请输入验证码" }],
},
loading: false,
//
captchaEnabled: true,
//
register: false,
redirect: undefined,
userType:"01",
};
},
watch: {
$route: {
handler: function (route) {
this.redirect = route.query && route.query.redirect;
},
immediate: true,
},
},
created() {
// this.getCode();
// this.getCookie();
location.href = process.env.VUE_APP_BASE_API + "/system/singlelogin/login"
},
methods: {
handleClick(tab){
if(tab.index == "1") {
this.getCode();
}
},
getCode() {
getCodeImg().then((res) => {
this.captchaEnabled =
res.captchaEnabled === undefined ? true : res.captchaEnabled;
if (this.captchaEnabled) {
this.codeUrl = "data:image/gif;base64," + res.img;
this.loginForm.uuid = res.uuid;
}
});
},
getCookie() {
const username = Cookies.get("username");
const password = Cookies.get("password");
const rememberMe = Cookies.get("rememberMe");
this.loginForm = {
username: username === undefined ? this.loginForm.username : username,
password:
password === undefined ? this.loginForm.password : decrypt(password),
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),
};
},
handleLogin() {
if(this.userType == '01') {
location.href = process.env.VUE_APP_BASE_API + "/system/singlelogin/login"
} else {
this.$refs.loginForm.validate((valid) => {
if (valid) {
this.loading = true;
if (this.loginForm.rememberMe) {
Cookies.set("username", this.loginForm.username, { expires: 30 });
Cookies.set("password", encrypt(this.loginForm.password), {
expires: 30,
});
Cookies.set("rememberMe", this.loginForm.rememberMe, {
expires: 30,
});
} else {
Cookies.remove("username");
Cookies.remove("password");
Cookies.remove("rememberMe");
}
this.$store
.dispatch("Login", {...this.loginForm,userType:this.userType})
.then(() => {
this.$router.push({ path: this.redirect || "/" }).catch(() => {});
})
.catch(() => {
this.loading = false;
if (this.captchaEnabled) {
if(this.userType == "02") {
this.getCode();
}
}
});
}
});
}
},
changeHttp(){
location.href = "https://qyt.sipac.gov.cn/sipsg-enterprise-mobile-manage/#/login"
},
},
};
</script>
<style rel="stylesheet/scss" lang="scss">
.login {
position: relative;
height: 100%;
background: url("../assets/images/login-background.jpg") no-repeat;
background-size: 100% 100%;
}
.title {
margin: 0px auto 30px auto;
text-align: center;
color: #707070;
}
.enterBtnLogin {
height: 100%;
.wai-box {
height: 100%;
margin-top: 30%;
}
}
.login-form {
position: absolute;
top: 45%;
left: 68%;
transform: translate(-50%, -50%);
border-radius: 6px;
background: #ffffff;
width: 400px;
height: 420px;
padding: 25px 25px 5px 25px;
box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.15);
.el-input {
height: 38px;
input {
height: 38px;
}
}
.input-icon {
height: 39px;
width: 14px;
margin-left: 2px;
}
::v-deep .el-tabs {
.el-tabs__nav .el-tabs__item {
width: 50%;
text-align: center;
}
}
}
.login-tip {
font-size: 13px;
text-align: center;
color: #bfbfbf;
}
.login-code {
width: 33%;
height: 38px;
float: right;
img {
cursor: pointer;
vertical-align: middle;
}
}
.el-login-footer {
height: 40px;
line-height: 40px;
position: fixed;
bottom: 0;
width: 100%;
text-align: center;
color: #fff;
font-family: Arial;
font-size: 12px;
letter-spacing: 1px;
}
.login-code-img {
height: 38px;
}
</style>

@ -16,4 +16,4 @@ export default {
};
</script>
<style></style>
<style></style>

@ -111,7 +111,7 @@
</div> -->
<!-- 正式环境部署命令 unzip /var/www/html/dist.zip -d /var/www/html/bms -->
<!-- 正式环境部署命令 unzip /var/www/html/dist.zip -o /var/www/html/bms -->
<!-- process.env.VUE_APP_BASE_API 替换 location.origin + '/api' publicPath /dome/JinJiHu 更换为./ -->
</div>
</template>

@ -1,186 +0,0 @@
<script>
import { deepClone } from '@/utils/index'
import render from './render/render.js'
const ruleTrigger = {
'el-input': 'blur',
'el-input-number': 'blur',
'el-select': 'change',
'el-radio-group': 'change',
'el-checkbox-group': 'change',
'el-cascader': 'change',
'el-time-picker': 'change',
'el-date-picker': 'change',
'el-rate': 'change'
}
const layouts = {
colFormItem(h, scheme) {
const config = scheme.__config__
const listeners = buildListeners.call(this, scheme)
let labelWidth = config.labelWidth ? `${config.labelWidth}px` : null
if (config.showLabel === false) labelWidth = '0'
return (
<el-col span={config.span}>
<el-form-item label-width={labelWidth} prop={scheme.__vModel__}
label={config.showLabel ? config.label : ''}>
<render conf={scheme} on={listeners} />
</el-form-item>
</el-col>
)
},
rowFormItem(h, scheme) {
let child = renderChildren.apply(this, arguments)
if (scheme.type === 'flex') {
child = <el-row type={scheme.type} justify={scheme.justify} align={scheme.align}>
{child}
</el-row>
}
return (
<el-col span={scheme.span}>
<el-row gutter={scheme.gutter}>
{child}
</el-row>
</el-col>
)
}
}
function renderFrom(h) {
const { formConfCopy } = this
return (
<el-row gutter={formConfCopy.gutter}>
<el-form
size={formConfCopy.size}
label-position={formConfCopy.labelPosition}
disabled={formConfCopy.disabled}
label-width={`${formConfCopy.labelWidth}px`}
ref={formConfCopy.formRef}
// model https://github.com/vuejs/jsx/issues/49#issuecomment-472013664
props={{ model: this[formConfCopy.formModel] }}
rules={this[formConfCopy.formRules]}
>
{renderFormItem.call(this, h, formConfCopy.fields)}
{formConfCopy.formBtns && formBtns.call(this, h)}
</el-form>
</el-row>
)
}
function formBtns(h) {
return <el-col>
<el-form-item size="large">
<el-button type="primary" onClick={this.submitForm}>提交</el-button>
<el-button onClick={this.resetForm}>重置</el-button>
</el-form-item>
</el-col>
}
function renderFormItem(h, elementList) {
return elementList.map(scheme => {
const config = scheme.__config__
const layout = layouts[config.layout]
if (layout) {
return layout.call(this, h, scheme)
}
throw new Error(`没有与${config.layout}匹配的layout`)
})
}
function renderChildren(h, scheme) {
const config = scheme.__config__
if (!Array.isArray(config.children)) return null
return renderFormItem.call(this, h, config.children)
}
function setValue(event, config, scheme) {
this.$set(config, 'defaultValue', event)
this.$set(this[this.formConf.formModel], scheme.__vModel__, event)
}
function buildListeners(scheme) {
const config = scheme.__config__
const methods = this.formConf.__methods__ || {}
const listeners = {}
// __methods__thisevent
Object.keys(methods).forEach(key => {
listeners[key] = event => methods[key].call(this, event)
})
// render.js vModel $emit('input', val)
listeners.input = event => setValue.call(this, event, config, scheme)
return listeners
}
export default {
components: {
render
},
props: {
formConf: {
type: Object,
required: true
}
},
data() {
const data = {
formConfCopy: deepClone(this.formConf),
[this.formConf.formModel]: {},
[this.formConf.formRules]: {}
}
this.initFormData(data.formConfCopy.fields, data[this.formConf.formModel])
this.buildRules(data.formConfCopy.fields, data[this.formConf.formRules])
return data
},
methods: {
initFormData(componentList, formData) {
componentList.forEach(cur => {
const config = cur.__config__
if (cur.__vModel__) formData[cur.__vModel__] = config.defaultValue
if (config.children) this.initFormData(config.children, formData)
})
},
buildRules(componentList, rules) {
componentList.forEach(cur => {
const config = cur.__config__
if (Array.isArray(config.regList)) {
if (config.required) {
const required = { required: config.required, message: cur.placeholder }
if (Array.isArray(config.defaultValue)) {
required.type = 'array'
required.message = `请至少选择一个${config.label}`
}
required.message === undefined && (required.message = `${config.label}不能为空`)
config.regList.push(required)
}
rules[cur.__vModel__] = config.regList.map(item => {
item.pattern && (item.pattern = eval(item.pattern))
item.trigger = ruleTrigger && ruleTrigger[config.tag]
return item
})
}
if (config.children) this.buildRules(config.children, rules)
})
},
resetForm() {
this.formConfCopy = deepClone(this.formConf)
this.$refs[this.formConf.formRef].resetFields()
},
submitForm() {
this.$refs[this.formConf.formRef].validate(valid => {
if (!valid) return false
// sumit
this.$emit('submit', this[this.formConf.formModel])
return true
})
}
},
render(h) {
return renderFrom.call(this, h)
}
}
</script>

@ -1,19 +0,0 @@
{
"name": "form-gen-render",
"version": "1.0.4",
"description": "表单核心render",
"main": "lib/form-gen-render.umd.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/JakHuang/form-generator.git"
},
"author": "jakhuang",
"license": "MIT",
"bugs": {
"url": "https://github.com/JakHuang/form-generator/issues"
},
"homepage": "https://github.com/JakHuang/form-generator#readme"
}

@ -1,122 +0,0 @@
import { deepClone } from '@/utils/index'
const componentChild = {}
/**
* ./slots中的文件挂载到对象componentChild上
* 文件名为key对应JSON配置中的__config__.tag
* 文件内容为value解析JSON配置中的__slot__
*/
const slotsFiles = require.context('./slots', false, /\.js$/)
const keys = slotsFiles.keys() || []
keys.forEach(key => {
const tag = key.replace(/^\.\/(.*)\.\w+$/, '$1')
const value = slotsFiles(key).default
componentChild[tag] = value
})
function vModel(dataObject, defaultValue) {
dataObject.props.value = defaultValue
dataObject.on.input = val => {
this.$emit('input', val)
}
}
function mountSlotFiles(h, confClone, children) {
const childObjs = componentChild[confClone.__config__.tag]
if (childObjs) {
Object.keys(childObjs).forEach(key => {
const childFunc = childObjs[key]
if (confClone.__slot__ && confClone.__slot__[key]) {
children.push(childFunc(h, confClone, key))
}
})
}
}
function emitEvents(confClone) {
['on', 'nativeOn'].forEach(attr => {
const eventKeyList = Object.keys(confClone[attr] || {})
eventKeyList.forEach(key => {
const val = confClone[attr][key]
if (typeof val === 'string') {
confClone[attr][key] = event => this.$emit(val, event)
}
})
})
}
function buildDataObject(confClone, dataObject) {
Object.keys(confClone).forEach(key => {
const val = confClone[key]
if (key === '__vModel__') {
vModel.call(this, dataObject, confClone.__config__.defaultValue)
} else if (dataObject[key] !== undefined) {
if (dataObject[key] === null
|| dataObject[key] instanceof RegExp
|| ['boolean', 'string', 'number', 'function'].includes(typeof dataObject[key])) {
dataObject[key] = val
} else if (Array.isArray(dataObject[key])) {
dataObject[key] = [...dataObject[key], ...val]
} else {
dataObject[key] = { ...dataObject[key], ...val }
}
} else {
dataObject.attrs[key] = val
}
})
// 清理属性
clearAttrs(dataObject)
}
function clearAttrs(dataObject) {
delete dataObject.attrs.__config__
delete dataObject.attrs.__slot__
delete dataObject.attrs.__methods__
}
function makeDataObject() {
// 深入数据对象:
// https://cn.vuejs.org/v2/guide/render-function.html#%E6%B7%B1%E5%85%A5%E6%95%B0%E6%8D%AE%E5%AF%B9%E8%B1%A1
return {
class: {},
attrs: {},
props: {},
domProps: {},
nativeOn: {},
on: {},
style: {},
directives: [],
scopedSlots: {},
slot: null,
key: null,
ref: null,
refInFor: true
}
}
export default {
props: {
conf: {
type: Object,
required: true
}
},
render(h) {
const dataObject = makeDataObject()
const confClone = deepClone(this.conf)
const children = this.$slots.default || []
// 如果slots文件夹存在与当前tag同名的文件则执行文件中的代码
mountSlotFiles.call(this, h, confClone, children)
// 将字符串类型的事件,发送为消息
emitEvents.call(this, confClone)
// 将json表单配置转化为vue render可以识别的 “数据对象dataObject
buildDataObject.call(this, confClone, dataObject)
return h(this.conf.__config__.tag, dataObject, children)
}
}

@ -1,5 +0,0 @@
export default {
default(h, conf, key) {
return conf.__slot__[key]
}
}

@ -1,13 +0,0 @@
export default {
options(h, conf, key) {
const list = []
conf.__slot__.options.forEach(item => {
if (conf.__config__.optionType === 'button') {
list.push(<el-checkbox-button label={item.value}>{item.label}</el-checkbox-button>)
} else {
list.push(<el-checkbox label={item.value} border={conf.border}>{item.label}</el-checkbox>)
}
})
return list
}
}

@ -1,8 +0,0 @@
export default {
prepend(h, conf, key) {
return <template slot="prepend">{conf.__slot__[key]}</template>
},
append(h, conf, key) {
return <template slot="append">{conf.__slot__[key]}</template>
}
}

@ -1,13 +0,0 @@
export default {
options(h, conf, key) {
const list = []
conf.__slot__.options.forEach(item => {
if (conf.__config__.optionType === 'button') {
list.push(<el-radio-button label={item.value}>{item.label}</el-radio-button>)
} else {
list.push(<el-radio label={item.value} border={conf.border}>{item.label}</el-radio>)
}
})
return list
}
}

@ -1,9 +0,0 @@
export default {
options(h, conf, key) {
const list = []
conf.__slot__.options.forEach(item => {
list.push(<el-option label={item.label} value={item.value} disabled={item.disabled}></el-option>)
})
return list
}
}

@ -1,17 +0,0 @@
export default {
'list-type': (h, conf, key) => {
const list = []
const config = conf.__config__
if (conf['list-type'] === 'picture-card') {
list.push(<i class="el-icon-plus"></i>)
} else {
list.push(<el-button size="small" type="primary" icon="el-icon-upload">{config.buttonText}</el-button>)
}
if (config.showTip) {
list.push(
<div slot="tip" class="el-upload__tip">只能上传不超过 {config.fileSize}{config.sizeUnit} {conf.accept}文件</div>
)
}
return list
}
}

@ -65,7 +65,7 @@
>
<el-table-column label="序号" align="center" width="50" fixed>
<template slot-scope="scope">
<span>{{(queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1}}</span>
<span>{{(queryParams.current - 1) * queryParams.size + scope.$index + 1}}</span>
</template>
</el-table-column>
<el-table-column prop="templateName" label="模版名称" min-width="160" :show-overflow-tooltip="true"></el-table-column>
@ -114,8 +114,8 @@
id="L-pagination"
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
:page.sync="queryParams.current"
:limit.sync="queryParams.size"
@pagination="getList"
/>
<!-- 添加或修改菜单对话框 -->
@ -188,8 +188,8 @@ export default {
queryParams: {
menuName: undefined,
visible: undefined,
ageNum: 1,
pageSize: 20,
current: 1,
size: 10,
},
enterpriseId: '',
templateDataList: [],
@ -234,8 +234,8 @@ export default {
getList() {
this.loading = true;
listInfo(this.queryParams).then(response => {
this.InfoList = response.rows;
this.total = response.total
this.InfoList = response.data.records;
this.total = response.data.total
this.loading = false;
});
},

@ -35,7 +35,7 @@
</el-form-item>
</el-col>
<el-col :span="2">
<el-button type="primary" class="import-btn" icon="icon iconfont icon-jc-daoru" size="mini" @click="importBtn"></el-button>
<el-button type="primary" class="import-btn" icon="icon iconfont icon-jc-daoru" size="mini" @click="importBtn(null)"></el-button>
</el-col>
</el-form>
@ -100,7 +100,7 @@
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="140" fixed="right">
<el-table-column label="操作" align="center" width="250" fixed="right">
<template slot-scope="scope">
<el-button
size="mini"
@ -110,8 +110,21 @@
<el-button
size="mini"
type="text"
style="margin-left: 5px;"
@click="handleExport(scope.row)"
>下载表单</el-button>
<el-button
size="mini"
type="text"
style="margin-left: 5px;"
@click="handleProcessView(scope.row)"
>流程设计</el-button>
<el-button
size="mini"
type="text"
style="margin-left: 5px;"
@click="importBtn(scope.row)"
>表单自定义</el-button>
</template>
</el-table-column>
</el-table>
@ -123,15 +136,24 @@
:limit.sync="queryParams.size"
@pagination="getList"
/>
<!-- 流程图 -->
<!-- <el-dialog :title="processView.title" :visible.sync="processView.open" width="70%" append-to-body>
<process-viewer :key="`designer-${processView.index}`" :xml="processView.xmlData" :style="{height: '400px'}" />
</el-dialog> -->
</div>
</template>
<script>
import { listInfo, exportData } from "@/api/onlineDeclartion/declarationManagement"
import { getAllList } from "@/api/system/dict/data";
// import ProcessViewer from '@/components/ProcessViewer'
export default {
name: "Template",
dicts: ['bms_product_area', 'bms_declaration_type', 'bms_responsibility_unit', 'bms_level', 'jjh_project_type', "project_small_type"],
// components: {
// ProcessViewer
// },
data() {
return {
//
@ -181,6 +203,11 @@ export default {
type: "success",
message: "新增模板成功!",
});
} else if(this.$route.params.code == 800) {
this.$message({
type: "success",
message: "修改模板成功!",
});
}
},
destroyed() {
@ -257,10 +284,17 @@ export default {
})
},
//
importBtn(){
this.$router.push({
name: 'onlineDeclarebBuild'
})
importBtn(row){
if(row) {
this.$router.push({
name: 'onlineDeclarebBuild',
query: { info: JSON.stringify(row) }
})
} else {
this.$router.push({
name: 'onlineDeclarebBuild',
})
}
},
}
};

@ -316,6 +316,15 @@
</el-descriptions-item>
</el-descriptions>
</div>
<div class="table-content" v-else>
<el-descriptions class="margin-top" title="【项目投资计划】" :column="2" :size="size" border :label-style="LS">
<el-descriptions-item v-for="(item,index) in templateJson.fields" :key="index" v-if="!item.action">
<template slot="label">
{{ item.label }}
</template>
</el-descriptions-item>
</el-descriptions>
</div>
<!-- 上传文件列表 -->
<div class="table-content last_upload">
<p>上传材料</p>
@ -432,6 +441,9 @@
<div v-if="templateId == 12 " class="upload_col">
<div class="upload_title">其他相关情况说明</div>
</div>
<div v-for="(item,index) in templateJson.fields" :key="index" v-if="item.action" class="upload_col">
<div class="upload_title">{{ item.label }}</div>
</div>
</div>
</div>
<!-- <div class="operate_btn">
@ -494,6 +506,7 @@ export default {
'work-break': 'break-all'
},
info:{},
templateJson:{},
};
},
async mounted(){
@ -503,6 +516,8 @@ export default {
getInfo(this.templateId).then(res=>{
// console.log(res);
this.info = res.data
this.templateJson = res.data.templateJson ? JSON.parse(res.data.templateJson) : {};
// console.log(this.templateJson);
})
switch (this.templateId){
case 1:

@ -221,7 +221,7 @@ import drawingDefault from '@/utils/generator/drawingDefault'
import logo from '@/assets/logo/logo.png'
import CodeTypeDialog from './CodeTypeDialog'
import DraggableItem from './DraggableItem'
import { templateInfo } from "@/api/onlineDeclartion/declarationManagement"
import { templateInfo, templateInfoChange } from "@/api/onlineDeclartion/declarationManagement"
import { getAllList } from "@/api/system/dict/data";
let oldActiveId
@ -308,7 +308,7 @@ export default {
projectBigType: undefined,
projectMiddleType: undefined,
projectSmallType: undefined,
createTemplate: true,
createTemplate: false,
}
},
created() {
@ -338,6 +338,14 @@ export default {
}
},
mounted() {
if(this.$route.query.info) {
this.createTemplate = false;
let obj = JSON.parse(this.$route.query.info)
let lists = JSON.parse(obj.templateJson)
this.drawingList = lists.fields
} else {
this.createTemplate = true;
}
const clipboard = new ClipboardJS('#copyNode', {
text: trigger => {
const codeStr = this.generateCode()
@ -520,6 +528,15 @@ export default {
}
})
} else if(this.$route.query.info){
templateInfoChange({...this.$route.params.info, templateJson: JSON.stringify(this.formData)}).then(res=>{
if(res.code == 200) {
this.$router.push({
name: 'Template',
params: {code:800},
})
}
})
} else {
this.createTemplate = true;
}

Loading…
Cancel
Save