Merge branch 'main' of http://47.109.205.240:3000/Web/digital-agriculture-admin
This commit is contained in:
commit
2d5b692ad5
@ -23,12 +23,11 @@ if (process.env.npm_config_preview || rawArgv.includes('--preview')) {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
app.listen(port, function () {
|
app.listen(port, function() {
|
||||||
console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`))
|
console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`))
|
||||||
if (report) {
|
if (report) {
|
||||||
console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`))
|
console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`))
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
run(`vue-cli-service build ${args}`)
|
run(`vue-cli-service build ${args}`)
|
||||||
|
@ -20,3 +20,6 @@ export default {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
<style>
|
||||||
|
@import url('./fonts/font.css');
|
||||||
|
</style>
|
||||||
|
BIN
src/assets/login/loginBG.png
Normal file
BIN
src/assets/login/loginBG.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.0 MiB |
BIN
src/fonts/DingTalk JinBuTi.ttf
Normal file
BIN
src/fonts/DingTalk JinBuTi.ttf
Normal file
Binary file not shown.
BIN
src/fonts/DingTalk Sans.ttf
Normal file
BIN
src/fonts/DingTalk Sans.ttf
Normal file
Binary file not shown.
15
src/fonts/font.css
Normal file
15
src/fonts/font.css
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'JinBuTi';
|
||||||
|
/* 自定义字体名称 */
|
||||||
|
src: url('./DingTalk JinBuTi.ttf') format('truetype');
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Sans';
|
||||||
|
/* 自定义字体名称 */
|
||||||
|
src: url('./DingTalk Sans.ttf') format('truetype');
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
@ -15,6 +15,6 @@ const getters = {
|
|||||||
topbarRouters: (state) => state.permission.topbarRouters,
|
topbarRouters: (state) => state.permission.topbarRouters,
|
||||||
defaultRoutes: (state) => state.permission.defaultRoutes,
|
defaultRoutes: (state) => state.permission.defaultRoutes,
|
||||||
sidebarRouters: (state) => state.permission.sidebarRouters,
|
sidebarRouters: (state) => state.permission.sidebarRouters,
|
||||||
isAdmin: (state) => (state.user.roles.includes('admin') || state.user.roles.includes('tenantadmin') ? true : false),
|
// isAdmin: (state) => (state.user.roles.includes('admin') || state.user.roles.includes('tenantadmin') ? true : false),
|
||||||
};
|
};
|
||||||
export default getters;
|
export default getters;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
let color = Vue.prototype.$colorList;
|
const color = Vue.prototype.$colorList;
|
||||||
export function pie(option, unit = '%') {
|
export function pie(option, unit = '%') {
|
||||||
return {
|
return {
|
||||||
color: color,
|
color: color,
|
||||||
@ -146,19 +146,19 @@ export function barColumn(option, unit = '个') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function autoHover(myChart, option, time) {
|
export function autoHover(myChart, option, time) {
|
||||||
let app = {
|
const app = {
|
||||||
currentIndex: -1,
|
currentIndex: -1,
|
||||||
};
|
};
|
||||||
var timeTicket = setInterval(function () {
|
var timeTicket = setInterval(function () {
|
||||||
let dataLen = option.series[0].data.length;
|
const dataLen = option.series[0].data.length;
|
||||||
// 取消之前高亮的图形
|
// 取消之前高亮的图形
|
||||||
myChart.dispatchAction({
|
myChart.dispatchAction({
|
||||||
type: 'downplay',
|
type: 'downplay',
|
||||||
seriesIndex: 0, //要展示的series数据索引
|
seriesIndex: 0, // 要展示的series数据索引
|
||||||
dataIndex: app.currentIndex,
|
dataIndex: app.currentIndex,
|
||||||
});
|
});
|
||||||
app.currentIndex = (app.currentIndex + 1) % dataLen;
|
app.currentIndex = (app.currentIndex + 1) % dataLen;
|
||||||
//console.log(app.currentIndex);
|
// console.log(app.currentIndex);
|
||||||
// 高亮当前图形
|
// 高亮当前图形
|
||||||
myChart.dispatchAction({
|
myChart.dispatchAction({
|
||||||
type: 'highlight',
|
type: 'highlight',
|
||||||
@ -174,7 +174,7 @@ export function autoHover(myChart, option, time) {
|
|||||||
}, time);
|
}, time);
|
||||||
|
|
||||||
myChart.on('mouseover', function (params) {
|
myChart.on('mouseover', function (params) {
|
||||||
//停止并显示当前的高亮和tooltip
|
// 停止并显示当前的高亮和tooltip
|
||||||
clearInterval(timeTicket);
|
clearInterval(timeTicket);
|
||||||
myChart.dispatchAction({
|
myChart.dispatchAction({
|
||||||
type: 'downplay',
|
type: 'downplay',
|
||||||
@ -195,7 +195,7 @@ export function autoHover(myChart, option, time) {
|
|||||||
myChart.on('mouseout', function () {
|
myChart.on('mouseout', function () {
|
||||||
timeTicket && clearInterval(timeTicket);
|
timeTicket && clearInterval(timeTicket);
|
||||||
timeTicket = setInterval(function () {
|
timeTicket = setInterval(function () {
|
||||||
let dataLen = option.series[0].data.length;
|
const dataLen = option.series[0].data.length;
|
||||||
// 取消之前高亮的图形
|
// 取消之前高亮的图形
|
||||||
myChart.dispatchAction({
|
myChart.dispatchAction({
|
||||||
type: 'downplay',
|
type: 'downplay',
|
||||||
@ -203,7 +203,7 @@ export function autoHover(myChart, option, time) {
|
|||||||
dataIndex: app.currentIndex,
|
dataIndex: app.currentIndex,
|
||||||
});
|
});
|
||||||
app.currentIndex = (app.currentIndex + 1) % dataLen;
|
app.currentIndex = (app.currentIndex + 1) % dataLen;
|
||||||
//console.log(app.currentIndex);
|
// console.log(app.currentIndex);
|
||||||
// 高亮当前图形
|
// 高亮当前图形
|
||||||
myChart.dispatchAction({
|
myChart.dispatchAction({
|
||||||
type: 'highlight',
|
type: 'highlight',
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="dataScreen-container" :style="{ width: `${style.width}px`, height: `${style.height}px`, transform: `${style.transform}` }">
|
<div class="dataScreen-container" :style="{ width: `${style.width}px`, height: `${style.height}px`, transform: `${style.transform}` }">
|
||||||
<div class="boxTop">
|
<div class="boxTop">
|
||||||
<img src="./img/leftTitle.png" alt="" class="img1" />
|
<img src="./img/leftTitle.png" alt="" class="img1">
|
||||||
<div class="boxTopRight">
|
<div class="boxTopRight">
|
||||||
<div class="index_animation__s5UDk"></div>
|
<div class="index_animation__s5UDk" />
|
||||||
<ul v-for="(item, index) in titleList" :key="index">
|
<ul v-for="(item, index) in titleList" :key="index">
|
||||||
<li
|
<li
|
||||||
:style="{
|
:style="{
|
||||||
@ -17,18 +17,18 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<component :baseId="baseId" :is="key"></component>
|
<component :is="key" :base-id="baseId" />
|
||||||
<base-select v-model="baseId" :type="2"></base-select>
|
<base-select v-model="baseId" :type="2" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// import './flexible'
|
// import './flexible'
|
||||||
import pageOne from './pageOne';
|
import pageOne from './pageOne'
|
||||||
import pageTwo from './pageTwo';
|
import pageTwo from './pageTwo'
|
||||||
import pageThree from './pageThree';
|
import pageThree from './pageThree'
|
||||||
import pageFour from './pageFour';
|
import pageFour from './pageFour'
|
||||||
import pageFive from './pageFive';
|
import pageFive from './pageFive'
|
||||||
export default {
|
export default {
|
||||||
name: '',
|
name: '',
|
||||||
components: {
|
components: {
|
||||||
@ -36,14 +36,14 @@ export default {
|
|||||||
pageTwo,
|
pageTwo,
|
||||||
pageThree,
|
pageThree,
|
||||||
pageFour,
|
pageFour,
|
||||||
pageFive,
|
pageFive
|
||||||
},
|
},
|
||||||
provide() {
|
provide() {
|
||||||
return {
|
return {
|
||||||
getType: () => this.key,
|
getType: () => this.key,
|
||||||
getX: () => this.scale.x,
|
getX: () => this.scale.x,
|
||||||
getY: () => this.scale.y,
|
getY: () => this.scale.y
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -53,48 +53,48 @@ export default {
|
|||||||
{ name: '科技支撑', type: 'pageTwo' },
|
{ name: '科技支撑', type: 'pageTwo' },
|
||||||
{ name: '产业基地', type: 'pageThree' },
|
{ name: '产业基地', type: 'pageThree' },
|
||||||
{ name: '全维监测', type: 'pageFour' },
|
{ name: '全维监测', type: 'pageFour' },
|
||||||
{ name: '朔源追朔', type: 'pageFive' },
|
{ name: '朔源追朔', type: 'pageFive' }
|
||||||
],
|
],
|
||||||
titleImg1: require('./img/1.png'),
|
titleImg1: require('./img/1.png'),
|
||||||
titleImg2: require('./img/2.png'),
|
titleImg2: require('./img/2.png'),
|
||||||
style: {
|
style: {
|
||||||
width: '1920',
|
width: '1920',
|
||||||
height: '1080',
|
height: '1080',
|
||||||
transform: 'scaleY(1) scaleX(1) translate(-50%, -50%)',
|
transform: 'scaleY(1) scaleX(1) translate(-50%, -50%)'
|
||||||
},
|
},
|
||||||
current: 0,
|
current: 0,
|
||||||
key: 'pageOne',
|
key: 'pageOne',
|
||||||
scale: {},
|
scale: {}
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.setScale();
|
this.setScale()
|
||||||
/*窗口改变事件*/
|
/* 窗口改变事件*/
|
||||||
window.onresize = () => {
|
window.onresize = () => {
|
||||||
this.setScale();
|
this.setScale()
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleTabs(item, index) {
|
handleTabs(item, index) {
|
||||||
window.addEventListener('resize', () => {
|
window.addEventListener('resize', () => {
|
||||||
this.setScale();
|
this.setScale()
|
||||||
});
|
})
|
||||||
if (index != this.current) {
|
if (index != this.current) {
|
||||||
this.current = index;
|
this.current = index
|
||||||
this.key = item.type;
|
this.key = item.type
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getScale() {
|
getScale() {
|
||||||
const w = window.innerWidth / this.style.width;
|
const w = window.innerWidth / this.style.width
|
||||||
const h = window.innerHeight / this.style.height;
|
const h = window.innerHeight / this.style.height
|
||||||
return { x: w, y: h };
|
return { x: w, y: h }
|
||||||
},
|
},
|
||||||
setScale() {
|
setScale() {
|
||||||
this.scale = this.getScale();
|
this.scale = this.getScale()
|
||||||
this.style.transform = 'scaleY(' + this.scale.y + ') scaleX(' + this.scale.x + ') translate(-50%, -50%)';
|
this.style.transform = 'scaleY(' + this.scale.y + ') scaleX(' + this.scale.x + ') translate(-50%, -50%)'
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.dataScreen-container {
|
.dataScreen-container {
|
||||||
|
@ -1,51 +1,51 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="screen" :style="{ 'background-image': `url(${bg})`, 'background-size': '100% 100%' }">
|
<div id="screen" :style="{ 'background-image': `url(${bg})`, 'background-size': '100% 100%' }">
|
||||||
<div
|
<div
|
||||||
id="indexMap"
|
|
||||||
v-if="type == 'pageThree'"
|
v-if="type == 'pageThree'"
|
||||||
|
id="indexMap"
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
element-loading-background="#263840"
|
element-loading-background="#263840"
|
||||||
element-loading-text="地图加载中"
|
element-loading-text="地图加载中"
|
||||||
element-loading-spinner="el-icon-loading"
|
element-loading-spinner="el-icon-loading"
|
||||||
:style="{ height: '100vh', width: '100vw', transform: `${scale}` }"
|
:style="{ height: '100vh', width: '100vw', transform: `${scale}` }"
|
||||||
></div>
|
/>
|
||||||
<div class="boxTop"></div>
|
<div class="boxTop" />
|
||||||
<div class="boxCentLeft" v-if="type != 'pageThree' && type != 'pageFive'">
|
<div v-if="type != 'pageThree' && type != 'pageFive'" class="boxCentLeft">
|
||||||
<slot name="one"></slot>
|
<slot name="one" />
|
||||||
</div>
|
</div>
|
||||||
<div class="boxRightTop">
|
<div class="boxRightTop">
|
||||||
<div class="title">{{ title[0] }}</div>
|
<div class="title">{{ title[0] }}</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<slot name="two"></slot>
|
<slot name="two" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxRightBom">
|
<div class="boxRightBom">
|
||||||
<div class="title">{{ title[1] }}</div>
|
<div class="title">{{ title[1] }}</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<slot name="three"></slot>
|
<slot name="three" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxBomLeft" v-if="type != 'pageFive' && type != 'pageFour'">
|
<div v-if="type != 'pageFive' && type != 'pageFour'" class="boxBomLeft">
|
||||||
<div class="title">{{ title[2] }}</div>
|
<div class="title">{{ title[2] }}</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<slot name="four"></slot>
|
<slot name="four" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxBomCent" v-if="type != 'pageFive' && type != 'pageFour'">
|
<div v-if="type != 'pageFive' && type != 'pageFour'" class="boxBomCent">
|
||||||
<div class="title">{{ title[3] }}</div>
|
<div class="title">{{ title[3] }}</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<slot name="five"></slot>
|
<slot name="five" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxBomRight">
|
<div class="boxBomRight">
|
||||||
<div class="title">{{ title[4] }}</div>
|
<div class="title">{{ title[4] }}</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<slot name="six"></slot>
|
<slot name="six" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="left" v-if="type == 'pageFive' || type == 'pageFour'">
|
<div v-if="type == 'pageFive' || type == 'pageFour'" class="left">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<slot name="seven"></slot>
|
<slot name="seven" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -56,13 +56,13 @@ import mapMixin from './map';
|
|||||||
export default {
|
export default {
|
||||||
name: '',
|
name: '',
|
||||||
mixins: [mapMixin],
|
mixins: [mapMixin],
|
||||||
|
inject: ['getType', 'getX', 'getY'],
|
||||||
props: {
|
props: {
|
||||||
bg: String,
|
bg: String,
|
||||||
title: Array,
|
title: Array,
|
||||||
baseId: Number,
|
baseId: Number,
|
||||||
},
|
},
|
||||||
inject: ['getType', 'getX', 'getY'],
|
// TODO:使用eventBus祖孙传参待优化
|
||||||
//TODO:使用eventBus祖孙传参待优化
|
|
||||||
computed: {
|
computed: {
|
||||||
type() {
|
type() {
|
||||||
return this.getType();
|
return this.getType();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { listDevice } from '@/api/iot/device';
|
import { listDevice } from '@/api/iot/device'
|
||||||
import { listLand } from '@/api/agriculture/land';
|
import { listLand } from '@/api/agriculture/land'
|
||||||
import { getDicts } from '@/api/system/dict/data';
|
import { getDicts } from '@/api/system/dict/data'
|
||||||
const mapMixin = {
|
const mapMixin = {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -9,66 +9,66 @@ const mapMixin = {
|
|||||||
baseUrl: process.env.VUE_APP_BASE_API,
|
baseUrl: process.env.VUE_APP_BASE_API,
|
||||||
loading: false,
|
loading: false,
|
||||||
landType: [],
|
landType: [],
|
||||||
deviceType: [],
|
deviceType: []
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
baseId: {
|
baseId: {
|
||||||
handler: async function (n) {
|
handler: async function(n) {
|
||||||
if (n) {
|
if (n) {
|
||||||
await this.$nextTick();
|
await this.$nextTick()
|
||||||
if (this.type == 'pageThree') {
|
if (this.type == 'pageThree') {
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
//获去地块数据
|
// 获去地块数据
|
||||||
let res = await listLand({ baseId: this.baseId });
|
const res = await listLand({ baseId: this.baseId })
|
||||||
this.area = res.rows;
|
this.area = res.rows
|
||||||
//获取设备数据
|
// 获取设备数据
|
||||||
let res1 = await listDevice({ baseId: this.baseId });
|
const res1 = await listDevice({ baseId: this.baseId })
|
||||||
this.device = res1.rows.map((item) => ({
|
this.device = res1.rows.map((item) => ({
|
||||||
...item,
|
...item,
|
||||||
imgUrl: item.imgUrl.split(',').length > 1 ? item.imgUrl.split(',')[1] : item.imgUrl,
|
imgUrl: item.imgUrl.split(',').length > 1 ? item.imgUrl.split(',')[1] : item.imgUrl
|
||||||
}));
|
}))
|
||||||
this.initMap();
|
this.initMap()
|
||||||
getDicts('agriculture_land_type').then((response) => {
|
getDicts('agriculture_land_type').then((response) => {
|
||||||
this.landType = response.data;
|
this.landType = response.data
|
||||||
});
|
})
|
||||||
getDicts('iot_device_status').then((response) => {
|
getDicts('iot_device_status').then((response) => {
|
||||||
this.deviceType = response.data;
|
this.deviceType = response.data
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
immediate: true,
|
immediate: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
async mounted() {},
|
async mounted() {},
|
||||||
methods: {
|
methods: {
|
||||||
/** 初始化map */
|
/** 初始化map */
|
||||||
async initMap() {
|
async initMap() {
|
||||||
this.map = new this.AMap.Map('indexMap', {
|
this.map = new this.AMap.Map('indexMap', {
|
||||||
//设置地图容器id
|
// 设置地图容器id
|
||||||
mapStyle: 'amap://styles/grey',
|
mapStyle: 'amap://styles/grey',
|
||||||
zoom: 16, //初始化地图级别
|
zoom: 16, // 初始化地图级别
|
||||||
// center: baseCoordinate, //初始化地图中心点位置
|
// center: baseCoordinate, //初始化地图中心点位置
|
||||||
doubleClickZoom: false,
|
doubleClickZoom: false
|
||||||
});
|
})
|
||||||
await this.createAreaPolygon();
|
await this.createAreaPolygon()
|
||||||
await this.createDevicePoint();
|
await this.createDevicePoint()
|
||||||
this.map.setFitView();
|
this.map.setFitView()
|
||||||
},
|
},
|
||||||
/** 绘制地块 */
|
/** 绘制地块 */
|
||||||
createAreaPolygon() {
|
createAreaPolygon() {
|
||||||
let label = [],
|
const label = []
|
||||||
overlayGroup = [];
|
const overlayGroup = []
|
||||||
this.area.forEach((item) => {
|
this.area.forEach((item) => {
|
||||||
if (item.landPath) {
|
if (item.landPath) {
|
||||||
let path = [],
|
const path = []
|
||||||
pointList = [];
|
const pointList = []
|
||||||
item.landPath.split('|').forEach((point) => {
|
item.landPath.split('|').forEach((point) => {
|
||||||
path.push(new this.AMap.LngLat(point.split(',')[0], point.split(',')[1]));
|
path.push(new this.AMap.LngLat(point.split(',')[0], point.split(',')[1]))
|
||||||
pointList.push([Number(point.split(',')[0]), Number(point.split(',')[1])]);
|
pointList.push([Number(point.split(',')[0]), Number(point.split(',')[1])])
|
||||||
});
|
})
|
||||||
let polygon = new this.AMap.Polygon({
|
const polygon = new this.AMap.Polygon({
|
||||||
path: path,
|
path: path,
|
||||||
fillColor: item.fillColor,
|
fillColor: item.fillColor,
|
||||||
fillOpacity: item.fillOpacity,
|
fillOpacity: item.fillOpacity,
|
||||||
@ -76,14 +76,14 @@ const mapMixin = {
|
|||||||
strokeWeight: item.strokeWeight,
|
strokeWeight: item.strokeWeight,
|
||||||
strokeOpacity: item.strokeOpacity,
|
strokeOpacity: item.strokeOpacity,
|
||||||
extData: {
|
extData: {
|
||||||
...item,
|
...item
|
||||||
},
|
}
|
||||||
});
|
})
|
||||||
polygon.on('click', (e) => {
|
polygon.on('click', (e) => {
|
||||||
this.createInfoWindow(e);
|
this.createInfoWindow(e)
|
||||||
});
|
})
|
||||||
overlayGroup.push(polygon);
|
overlayGroup.push(polygon)
|
||||||
//添加地块名称
|
// 添加地块名称
|
||||||
label.push(
|
label.push(
|
||||||
new this.AMap.Text({
|
new this.AMap.Text({
|
||||||
text: item.landName,
|
text: item.landName,
|
||||||
@ -93,119 +93,119 @@ const mapMixin = {
|
|||||||
background: 'transparent',
|
background: 'transparent',
|
||||||
color: '#fff',
|
color: '#fff',
|
||||||
border: 'none',
|
border: 'none',
|
||||||
fontSize: '16px',
|
fontSize: '16px'
|
||||||
},
|
}
|
||||||
})
|
})
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
this.map.add(new this.AMap.OverlayGroup(label));
|
this.map.add(new this.AMap.OverlayGroup(label))
|
||||||
this.map.add(new this.AMap.OverlayGroup(overlayGroup));
|
this.map.add(new this.AMap.OverlayGroup(overlayGroup))
|
||||||
},
|
},
|
||||||
/** 创建设备marker点 */
|
/** 创建设备marker点 */
|
||||||
createDevicePoint() {
|
createDevicePoint() {
|
||||||
let devicePointList = [];
|
const devicePointList = []
|
||||||
this.device.forEach((device) => {
|
this.device.forEach((device) => {
|
||||||
if ((device.longitude, device.latitude)) {
|
if ((device.longitude, device.latitude)) {
|
||||||
let marker = new this.AMap.Marker({
|
const marker = new this.AMap.Marker({
|
||||||
icon: new this.AMap.Icon({
|
icon: new this.AMap.Icon({
|
||||||
image: this.baseUrl + device.imgUrl,
|
image: this.baseUrl + device.imgUrl,
|
||||||
imageSize: new this.AMap.Size(32, 32),
|
imageSize: new this.AMap.Size(32, 32)
|
||||||
}),
|
}),
|
||||||
position: [device.longitude, device.latitude],
|
position: [device.longitude, device.latitude],
|
||||||
title: device.deviceName,
|
title: device.deviceName,
|
||||||
anchor: 'bottom-center',
|
anchor: 'bottom-center',
|
||||||
extData: {
|
extData: {
|
||||||
...device,
|
...device
|
||||||
},
|
}
|
||||||
});
|
})
|
||||||
marker.on('click', (e) => {
|
marker.on('click', (e) => {
|
||||||
this.createInfoWindow2(e);
|
this.createInfoWindow2(e)
|
||||||
});
|
})
|
||||||
devicePointList.push(marker);
|
devicePointList.push(marker)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
this.map.add(new this.AMap.OverlayGroup(devicePointList));
|
this.map.add(new this.AMap.OverlayGroup(devicePointList))
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
},
|
},
|
||||||
/** 获取地块中心点 */
|
/** 获取地块中心点 */
|
||||||
getAreaCenter(location) {
|
getAreaCenter(location) {
|
||||||
var total = location.length;
|
var total = location.length
|
||||||
var X = 0,
|
var X = 0
|
||||||
Y = 0,
|
var Y = 0
|
||||||
Z = 0;
|
var Z = 0
|
||||||
location.forEach((lnglat) => {
|
location.forEach((lnglat) => {
|
||||||
var lng = (lnglat[0] * Math.PI) / 180;
|
var lng = (lnglat[0] * Math.PI) / 180
|
||||||
var lat = (lnglat[1] * Math.PI) / 180;
|
var lat = (lnglat[1] * Math.PI) / 180
|
||||||
var x, y, z;
|
var x, y, z
|
||||||
x = Math.cos(lat) * Math.cos(lng);
|
x = Math.cos(lat) * Math.cos(lng)
|
||||||
y = Math.cos(lat) * Math.sin(lng);
|
y = Math.cos(lat) * Math.sin(lng)
|
||||||
z = Math.sin(lat);
|
z = Math.sin(lat)
|
||||||
X += x;
|
X += x
|
||||||
Y += y;
|
Y += y
|
||||||
Z += z;
|
Z += z
|
||||||
});
|
})
|
||||||
X = X / total;
|
X = X / total
|
||||||
Y = Y / total;
|
Y = Y / total
|
||||||
Z = Z / total;
|
Z = Z / total
|
||||||
|
|
||||||
var Lng = Math.atan2(Y, X);
|
var Lng = Math.atan2(Y, X)
|
||||||
var Hyp = Math.sqrt(X * X + Y * Y);
|
var Hyp = Math.sqrt(X * X + Y * Y)
|
||||||
var Lat = Math.atan2(Z, Hyp);
|
var Lat = Math.atan2(Z, Hyp)
|
||||||
return [parseFloat((Lng * 180) / Math.PI), parseFloat((Lat * 180) / Math.PI)];
|
return [parseFloat((Lng * 180) / Math.PI), parseFloat((Lat * 180) / Math.PI)]
|
||||||
},
|
},
|
||||||
/** 信息窗体 */
|
/** 信息窗体 */
|
||||||
createInfoWindow(e) {
|
createInfoWindow(e) {
|
||||||
var info = document.createElement('div');
|
var info = document.createElement('div')
|
||||||
info.className = 'InfoBox';
|
info.className = 'InfoBox'
|
||||||
var title = document.createElement('div');
|
var title = document.createElement('div')
|
||||||
title.className = 'title';
|
title.className = 'title'
|
||||||
title.innerHTML = `${e.target._opts.extData.landName}`;
|
title.innerHTML = `${e.target._opts.extData.landName}`
|
||||||
var type = document.createElement('div');
|
var type = document.createElement('div')
|
||||||
var typeName = '';
|
var typeName = ''
|
||||||
this.landType.forEach((item) => {
|
this.landType.forEach((item) => {
|
||||||
if (item.dictValue == e.target._opts.extData.landType) {
|
if (item.dictValue == e.target._opts.extData.landType) {
|
||||||
typeName = item.dictLabel;
|
typeName = item.dictLabel
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
type.className = 'type';
|
type.className = 'type'
|
||||||
type.innerHTML = `<div class="item">类型:<div class="tag">${typeName}</div></div>
|
type.innerHTML = `<div class="item">类型:<div class="tag">${typeName}</div></div>
|
||||||
<div class="item">面积:${e.target._opts.extData.landArea}亩</div>`;
|
<div class="item">面积:${e.target._opts.extData.landArea}亩</div>`
|
||||||
info.appendChild(title);
|
info.appendChild(title)
|
||||||
info.appendChild(type);
|
info.appendChild(type)
|
||||||
let infoWindow = new this.AMap.InfoWindow({
|
const infoWindow = new this.AMap.InfoWindow({
|
||||||
anchor: 'bottom-center',
|
anchor: 'bottom-center',
|
||||||
content: info, //使用默认信息窗体框样式,显示信息内容
|
content: info // 使用默认信息窗体框样式,显示信息内容
|
||||||
});
|
})
|
||||||
infoWindow.open(this.map, new this.AMap.LngLat(e.lnglat.getLng(), e.lnglat.getLat()));
|
infoWindow.open(this.map, new this.AMap.LngLat(e.lnglat.getLng(), e.lnglat.getLat()))
|
||||||
},
|
},
|
||||||
createInfoWindow2(e) {
|
createInfoWindow2(e) {
|
||||||
var info = document.createElement('div');
|
var info = document.createElement('div')
|
||||||
info.className = 'InfoBox';
|
info.className = 'InfoBox'
|
||||||
var title = document.createElement('div');
|
var title = document.createElement('div')
|
||||||
title.className = 'title';
|
title.className = 'title'
|
||||||
title.innerHTML = `${e.target._opts.extData.deviceName}`;
|
title.innerHTML = `${e.target._opts.extData.deviceName}`
|
||||||
var num = document.createElement('div');
|
var num = document.createElement('div')
|
||||||
num.className = 'num';
|
num.className = 'num'
|
||||||
num.innerHTML = `<div>编号:${e.target._opts.extData.serialNumber}</div>`;
|
num.innerHTML = `<div>编号:${e.target._opts.extData.serialNumber}</div>`
|
||||||
var tips = document.createElement('div');
|
var tips = document.createElement('div')
|
||||||
tips.className = 'tips';
|
tips.className = 'tips'
|
||||||
var statusName = '';
|
var statusName = ''
|
||||||
this.deviceType.forEach((item) => {
|
this.deviceType.forEach((item) => {
|
||||||
if (item.dictValue == e.target._opts.extData.status) {
|
if (item.dictValue == e.target._opts.extData.status) {
|
||||||
statusName = item.dictLabel;
|
statusName = item.dictLabel
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
tips.innerHTML = `${statusName}`;
|
tips.innerHTML = `${statusName}`
|
||||||
info.appendChild(title);
|
info.appendChild(title)
|
||||||
info.appendChild(num);
|
info.appendChild(num)
|
||||||
info.appendChild(tips);
|
info.appendChild(tips)
|
||||||
let infoWindow = new this.AMap.InfoWindow({
|
const infoWindow = new this.AMap.InfoWindow({
|
||||||
anchor: 'bottom-center',
|
anchor: 'bottom-center',
|
||||||
content: info, //使用默认信息窗体框样式,显示信息内容
|
content: info // 使用默认信息窗体框样式,显示信息内容
|
||||||
});
|
})
|
||||||
infoWindow.open(this.map, new this.AMap.LngLat(e.lnglat.getLng(), e.lnglat.getLat()));
|
infoWindow.open(this.map, new this.AMap.LngLat(e.lnglat.getLng(), e.lnglat.getLat()))
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
export default mapMixin;
|
export default mapMixin
|
||||||
|
@ -1,65 +1,52 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="login">
|
<div class="login">
|
||||||
<el-row>
|
<section class="system_name">数字农业平台</section>
|
||||||
<el-col :span="14">
|
<div class="login_content">
|
||||||
<div class="left">
|
<section class="login_text">登录</section>
|
||||||
<div class="login-title">{{ loginTitle }}</div>
|
<div>
|
||||||
<div class="login-subTitle">专注于农业,面向未来,自主创新</div>
|
<el-form label-position="top">
|
||||||
<div class="login-bgImage">
|
<el-form ref="loginForm" :model="loginForm" :rules="loginRules">
|
||||||
<img src="@/assets/images/loginBg.svg" alt="" />
|
<el-form-item label="账号" prop="username">
|
||||||
</div>
|
<el-input v-model="loginForm.username" prefix-icon="el-icon-user" placeholder="请输入用户名"></el-input>
|
||||||
</div>
|
</el-form-item>
|
||||||
</el-col>
|
<el-form-item label="密码" prop="password">
|
||||||
<el-col :span="10">
|
<el-input v-model="loginForm.password" prefix-icon="el-icon-lock" type="password" placeholder="请输入密码" show-password></el-input>
|
||||||
<div class="right">
|
</el-form-item>
|
||||||
<div class="loginForm-title">系统登录</div>
|
<el-form-item label="验证码" prop="code" v-if="captchaOnOff">
|
||||||
<div class="loginForm-subTitle">SYSTEM LOGIN</div>
|
<el-row class="login-captchaBox">
|
||||||
<div class="loginForm-form">
|
<el-col :span="15">
|
||||||
<el-form label-position="top">
|
<el-input
|
||||||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules">
|
v-model="loginForm.code"
|
||||||
<el-form-item label="账号" prop="username">
|
auto-complete="off"
|
||||||
<el-input v-model="loginForm.username" prefix-icon="el-icon-user" placeholder="请输入用户名"></el-input>
|
placeholder="验证码"
|
||||||
</el-form-item>
|
prefix-icon="el-icon-circle-check"
|
||||||
<el-form-item label="密码" prop="password">
|
@keyup.enter.native="handleLogin"
|
||||||
<el-input v-model="loginForm.password" prefix-icon="el-icon-lock" type="password" placeholder="请输入密码" show-password></el-input>
|
/>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
<el-form-item label="验证码" prop="code" v-if="captchaOnOff">
|
<el-col :span="8" :offset="1" style="display: flex">
|
||||||
<el-row class="login-captchaBox">
|
<div class="login-code">
|
||||||
<el-col :span="15">
|
<img :src="codeUrl" @click="getCode" />
|
||||||
<el-input
|
</div>
|
||||||
v-model="loginForm.code"
|
</el-col>
|
||||||
auto-complete="off"
|
</el-row>
|
||||||
placeholder="验证码"
|
</el-form-item>
|
||||||
prefix-icon="el-icon-circle-check"
|
|
||||||
@keyup.enter.native="handleLogin"
|
|
||||||
/>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8" :offset="1" style="display: flex">
|
|
||||||
<div class="login-code">
|
|
||||||
<img :src="codeUrl" @click="getCode" />
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-checkbox v-model="loginForm.rememberMe" style="margin: 0px 0px 25px 0px; color: #000">记住密码</el-checkbox>
|
<el-checkbox v-model="loginForm.rememberMe" style="margin: 0px 0px 25px 25px; color: #000; transform: scale(1.6)">记住密码</el-checkbox>
|
||||||
|
|
||||||
<el-form-item style="width: 100%">
|
<el-form-item class="login_btn" style="width: 100%">
|
||||||
<el-button v-if="!bindAccount" :loading="loading" type="primary" style="width: 100%" @click.native.prevent="handleLogin">
|
<el-button v-if="!bindAccount" :loading="loading" type="primary" style="width: 100%" @click.native.prevent="handleLogin">
|
||||||
<span v-if="!loading">登 录</span>
|
<span v-if="!loading">登 录</span>
|
||||||
<span v-else>登 录 中...</span>
|
<span v-else>登 录 中...</span>
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button v-else :loading="loading" type="primary" style="width: 100%" @click.native.prevent="handleLogin">
|
<el-button v-else :loading="loading" type="primary" style="width: 100%" @click.native.prevent="handleLogin">
|
||||||
<span v-if="!loading">绑定</span>
|
<span v-if="!loading">绑定</span>
|
||||||
<span v-else>绑 定 中...</span>
|
<span v-else>绑 定 中...</span>
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -266,73 +253,61 @@ export default {
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.login {
|
.login {
|
||||||
.left {
|
padding: 14vh 6vw 0;
|
||||||
height: 100vh;
|
display: flex;
|
||||||
background: #109b5e;
|
justify-content: space-between;
|
||||||
overflow: hidden;
|
width: 100vw;
|
||||||
.login-title {
|
height: 100vh;
|
||||||
display: flex;
|
overflow: hidden;
|
||||||
align-items: center;
|
background: url('../assets/login/loginBG.png') no-repeat fixed center / cover;
|
||||||
justify-content: center;
|
.system_name {
|
||||||
padding-bottom: 26px;
|
padding-top: 8vh;
|
||||||
color: #fff;
|
font-size: 100px;
|
||||||
letter-spacing: 11px;
|
font-weight: bold;
|
||||||
font-size: 50px;
|
color: #fff;
|
||||||
font-weight: 500;
|
font-family: 'JinBuTi', sans-serif;
|
||||||
margin-top: 15vh;
|
transform: skew(-12deg);
|
||||||
}
|
|
||||||
.login-subTitle {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
padding-bottom: 26px;
|
|
||||||
color: #fff;
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
.login-bgImage {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
margin-top: 15vh;
|
|
||||||
img {
|
|
||||||
width: 75%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.right {
|
.login_content {
|
||||||
height: 100vh;
|
.login_text {
|
||||||
|
margin: 0 auto 60px;
|
||||||
|
width: 128px;
|
||||||
|
height: 78px;
|
||||||
|
font-family: 'JinBuTi', sans-serif;
|
||||||
|
font-size: 64px;
|
||||||
|
color: #fff;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
}
|
||||||
|
padding: 60px 40px;
|
||||||
|
width: 640px;
|
||||||
|
height: 72vh;
|
||||||
|
background-color: rgba(0, 0, 0, 0.2);
|
||||||
|
backdrop-filter: blur(18px);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
border-radius: 40px;
|
||||||
.loginForm-title {
|
.loginForm-title {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
margin-top: 20vh;
|
|
||||||
}
|
|
||||||
.loginForm-subTitle {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
color: rgba(22, 23, 26, 0.1);
|
|
||||||
font-size: 23px;
|
|
||||||
white-space: nowrap;
|
|
||||||
letter-spacing: 2px;
|
|
||||||
margin-top: -10px;
|
|
||||||
}
|
|
||||||
.loginForm-form {
|
|
||||||
padding: 0 25%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-captchaBox {
|
|
||||||
display: flex;
|
|
||||||
img {
|
|
||||||
height: 50px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//组件样式修改
|
//组件样式修改
|
||||||
::v-deep {
|
::v-deep {
|
||||||
|
.el-form-item {
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
.el-form-item__label {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.login_btn {
|
||||||
|
margin-top: 40px;
|
||||||
|
span {
|
||||||
|
font-family: 'Sans';
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
.el-input__inner {
|
.el-input__inner {
|
||||||
height: 50px;
|
height: 50px;
|
||||||
border-radius: 25px;
|
border-radius: 25px;
|
||||||
|
@ -15,7 +15,7 @@ module.exports = {
|
|||||||
// 部署生产环境和开发环境下的URL。
|
// 部署生产环境和开发环境下的URL。
|
||||||
// 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上
|
// 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上
|
||||||
// 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
|
// 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
|
||||||
publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
|
publicPath: process.env.NODE_ENV === 'production' ? '/' : '/',
|
||||||
// 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist)
|
// 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist)
|
||||||
outputDir: 'dist',
|
outputDir: 'dist',
|
||||||
// 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
|
// 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
|
||||||
@ -38,13 +38,13 @@ module.exports = {
|
|||||||
['^' + process.env.VUE_APP_BASE_API]: ''
|
['^' + process.env.VUE_APP_BASE_API]: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
['/api/v4']: {
|
'/api/v4': {
|
||||||
target: process.env.VUE_APP_EMQX_API_URL,
|
target: process.env.VUE_APP_EMQX_API_URL,
|
||||||
changeOrigin: true,
|
changeOrigin: true
|
||||||
// logLevel: 'debug',
|
// logLevel: 'debug',
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
https:false,
|
https: false,
|
||||||
disableHostCheck: true
|
disableHostCheck: true
|
||||||
},
|
},
|
||||||
configureWebpack: {
|
configureWebpack: {
|
||||||
@ -53,17 +53,14 @@ module.exports = {
|
|||||||
alias: {
|
alias: {
|
||||||
'@': resolve('src')
|
'@': resolve('src')
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
chainWebpack(config) {
|
chainWebpack(config) {
|
||||||
config.plugins.delete('preload') // TODO: need test
|
config.plugins.delete('preload') // TODO: need test
|
||||||
config.plugins.delete('prefetch') // TODO: need test
|
config.plugins.delete('prefetch') // TODO: need test
|
||||||
|
|
||||||
// set svg-sprite-loader
|
// set svg-sprite-loader
|
||||||
config.module
|
config.module.rule('svg').exclude.add(resolve('src/assets/icons')).end()
|
||||||
.rule('svg')
|
|
||||||
.exclude.add(resolve('src/assets/icons'))
|
|
||||||
.end()
|
|
||||||
config.module
|
config.module
|
||||||
.rule('icons')
|
.rule('icons')
|
||||||
.test(/\.svg$/)
|
.test(/\.svg$/)
|
||||||
@ -76,47 +73,46 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
.end()
|
.end()
|
||||||
|
|
||||||
config
|
config.when(process.env.NODE_ENV !== 'development', (config) => {
|
||||||
.when(process.env.NODE_ENV !== 'development',
|
config
|
||||||
config => {
|
.plugin('ScriptExtHtmlWebpackPlugin')
|
||||||
config
|
.after('html')
|
||||||
.plugin('ScriptExtHtmlWebpackPlugin')
|
.use('script-ext-html-webpack-plugin', [
|
||||||
.after('html')
|
|
||||||
.use('script-ext-html-webpack-plugin', [{
|
|
||||||
// `runtime` must same as runtimeChunk name. default is `runtime`
|
|
||||||
inline: /runtime\..*\.js$/
|
|
||||||
}])
|
|
||||||
.end()
|
|
||||||
config
|
|
||||||
.optimization.splitChunks({
|
|
||||||
chunks: 'all',
|
|
||||||
cacheGroups: {
|
|
||||||
libs: {
|
|
||||||
name: 'chunk-libs',
|
|
||||||
test: /[\\/]node_modules[\\/]/,
|
|
||||||
priority: 10,
|
|
||||||
chunks: 'initial' // only package third parties that are initially dependent
|
|
||||||
},
|
|
||||||
elementUI: {
|
|
||||||
name: 'chunk-elementUI', // split elementUI into a single package
|
|
||||||
priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
|
|
||||||
test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
|
|
||||||
},
|
|
||||||
commons: {
|
|
||||||
name: 'chunk-commons',
|
|
||||||
test: resolve('src/components'), // can customize your rules
|
|
||||||
minChunks: 3, // minimum common number
|
|
||||||
priority: 5,
|
|
||||||
reuseExistingChunk: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
config.optimization.runtimeChunk('single'),
|
|
||||||
{
|
{
|
||||||
from: path.resolve(__dirname, './public/robots.txt'), //防爬虫文件
|
// `runtime` must same as runtimeChunk name. default is `runtime`
|
||||||
to: './' //到根目录下
|
inline: /runtime\..*\.js$/
|
||||||
|
}
|
||||||
|
])
|
||||||
|
.end()
|
||||||
|
config.optimization.splitChunks({
|
||||||
|
chunks: 'all',
|
||||||
|
cacheGroups: {
|
||||||
|
libs: {
|
||||||
|
name: 'chunk-libs',
|
||||||
|
test: /[\\/]node_modules[\\/]/,
|
||||||
|
priority: 10,
|
||||||
|
chunks: 'initial' // only package third parties that are initially dependent
|
||||||
|
},
|
||||||
|
elementUI: {
|
||||||
|
name: 'chunk-elementUI', // split elementUI into a single package
|
||||||
|
priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
|
||||||
|
test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
|
||||||
|
},
|
||||||
|
commons: {
|
||||||
|
name: 'chunk-commons',
|
||||||
|
test: resolve('src/components'), // can customize your rules
|
||||||
|
minChunks: 3, // minimum common number
|
||||||
|
priority: 5,
|
||||||
|
reuseExistingChunk: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
})
|
||||||
|
// eslint-disable-next-line no-sequences
|
||||||
|
config.optimization.runtimeChunk('single'),
|
||||||
|
{
|
||||||
|
from: path.resolve(__dirname, './public/robots.txt'), // 防爬虫文件
|
||||||
|
to: './' // 到根目录下
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user