# Conflicts:
#	README.md
#	pages/test.vue
#	pages/web3/index.vue
#	pages/wuzuzhi/environment.vue
#	pages/wuzuzhi/home.vue
#	pages/wuzuzhi/huanjingzhili.vue
#	pages/wuzuzhi/list.vue
This commit is contained in:
wangzg 2024-08-22 22:29:20 +08:00
commit 0f47c609e7
49 changed files with 1839 additions and 370 deletions

View File

@ -11,47 +11,71 @@ $ yarn dev
# build for production and launch server
$ yarn build
$ yarn start
# generate static project
$ yarn generate
```
## Special Directories
### mixins
vue混入代码主要是自适应相关的代码
### `assets`
静态资源
### `components`
公共组件目录
### `layouts`
布局目录,多了一个管理页
## 组件库文档地址
https://1x.antdv.com/components/icon/
## 路由说明
登录页 /login
登录页 /login 对接完成
### 管理页
|名称|路由|
|---|---|
|用户管理| /manager/user|
|角色管理| /manager/role|
|菜单管理| /manager/menu|
|设备管理 |/manager/device|
|工序管理 |/manager/organized|
用户管理 /manager/user 对接完成
角色管理 /manager/role 对接完成
菜单管理 /manager/menu 对接完成
设备管理 /manager/device 对接完成
工序管理 /manager/organized 对接完成
### 用户端
|名称|路由|
|---|---|
|首页| /home|
首页 /home
#### 有组织
有组织
有组织排放 /youzuzhi/paifang 缺少排放源清单接口
有组织排放统计 /youzuzhi/paifangtongji 待联调 接口暂无
#### 无组织
| 名称 | 路由 |
|-------|----------------------|
| 无组织首页 | /wuzuzhi/home |
| 洗车机管理 | /wuzuzhi/carWasher |
| 环境治理 | /wuzuzhi/environment |
无组织排放 /wuzuzhi/paifang 待联调 接口暂无
洗车机管理 /wuzuzhi/xichejiguanli 待联调 缺少导出接口 监控信息 运行信息
环境治理 /wuzuzhi/huanjingzhili 待联调 缺少 实时数据的接口
环卫巡航 /wuzuzhi/huanweixunhang 待联调
#### 清洁运输
|名称| 路由 |
|---|------------------------|
|清洁运输 | /cleanTravel/home |
|厂区车辆台账| /cleanTravel/ledger |
|清洁运输趋势 | /cleanTravel/trend |
|磅秤台账 | /cleanTravel/bangcheng |
清洁运输 /cleanTravel/home 联调完成
厂区车辆台账 /cleanTravel/ledger 联调完成
清洁运输趋势 /cleanTravel/trend 待联调 /api/Transport/gettransport
磅秤台账 /cleanTravel/bangcheng 待联调 不要了
#### 视频广场
视频广场 /video/list 未做

View File

@ -42,3 +42,44 @@
}
}
}
.event-none {
pointer-events: none;
}
.event-auto {
pointer-events: auto;
}
.bottom-btn {
position: absolute;
.event-auto;
width: 100%;
bottom: 0;
left: 0;
}
.custom-tab {
.ant-tabs-ink-bar {
background: rgba(120, 240, 253, 1);
}
.ant-tabs-nav .ant-tabs-tab-active {
color: #fff;
}
.ant-tabs-bar {
margin: 0;
}
.ant-tabs-nav {
color: #fff;
}
.ant-tabs-nav-wrap {
background: linear-gradient(90deg, rgba(0, 107, 207, 0.4) 0%, rgba(0, 128, 247, 0.08) 100%) !important;
}
.ant-tabs-nav-scroll {
background: linear-gradient(90deg, rgba(0, 107, 207, 0.4) 0%, rgba(0, 128, 247, 0.08) 100%) !important;
}
}

View File

@ -1,9 +1,4 @@
<!--
* @Description: Description
* @ComponentName: BFC
* @Author: wangzhigang11
* @Date: 2023-05-10 18:59
-->
<template>
<div class="BFC">
<div v-if="showLeft" class="left" :style="curStyle">

View File

@ -1,9 +1,4 @@
<!--
* @Description: Description
* @ComponentName: FlexCol
* @Author: wangzhigang11
* @Date: 2023-05-10 13:42
-->
<template>
<div class="FlexCenter" :style="{height: cHeight}">
<slot></slot>

View File

@ -1,9 +1,4 @@
<!--
* @Description: Description
* @ComponentName: FlexCol
* @Author: wangzhigang11
* @Date: 2023-05-10 13:42
-->
<template>
<div class="FlexCol" :style="curStyle">
<slot></slot>

View File

@ -1,9 +1,4 @@
<!--
* @Description: Description
* @ComponentName: FlexCol
* @Author: wangzhigang11
* @Date: 2023-05-10 13:42
-->
<template>
<div class="FlexRow" :style="{height: cHeight}">
<slot></slot>

View File

@ -1,5 +1,8 @@
<template>
<div class="map-container" ref="mapRef" id="mars3dContainer"></div>
<div class="map-wrapper">
<div class="bg event-none"></div>
<div class="map-container" ref="mapRef" id="mars3dContainer"></div>
</div>
</template>
<script>
@ -17,12 +20,6 @@ const mapLayerTypeToPointIcon = {
}
export default {
async asyncData({ $axios }) {
console.log('axios:', 1)
const { data } = await $axios.$get('http://101.43.201.20:5000/api/Home/view');
return { pageTitle: data.home.title }; // { data: '' }
},
name: "Map",
data () {
return {
@ -39,18 +36,23 @@ export default {
default: 'big'
}
},
mounted() {
this.$nextTick(() => {
if (this.$refs.mapRef) {
const win = window.top
this.$http.get('http://101.43.201.20:5000/api/Home/view').then(({ data }) => {
win.document.title = data.home.title
this.setTitle(data.home.title)
this.setInfo(data)
this.initMap(data.home.center)
})
watch: {
info: {
immediate: true,
deep: true,
handler (info) {
if (info) {
this.$nextTick(() => {
if (this.$refs.mapRef) {
this.initMap(info.home.center)
}
})
}
}
})
}
},
mounted() {
this.$evBus.$on('setVisibility', (layerType, show) => {
this.setVisibility(layerType, show)
})
@ -68,6 +70,7 @@ export default {
shisc: state => state.map.shisc,
wz: state => state.map.wz,
jkd: state => state.map.jkd,
info: state => state.system.info
})
},
methods: {
@ -77,7 +80,6 @@ export default {
const { lon, lat } = center
ms3dConfig.scene.center.lng = lon
ms3dConfig.scene.center.lat = lat
console.log('ms3dConfig:', ms3dConfig);
this.map = new mars3d.Map(this.$refs.mapRef, ms3dConfig)
this.map.on("load", () => {
Object.keys(mapLayerTypeToPointIcon).forEach(layerType => {
@ -208,6 +210,23 @@ export default {
</style>
<style scoped lang="less">
.map-wrapper {
width: 100%;
height: 100%;
position: absolute;
transform: translateX(-50%);
left: 50%;
top: 0;
z-index: 1;
.bg {
background: radial-gradient(transparent, rgba(3, 5, 51, 0.19), rgba(3, 5, 51, 0.68), #020433);
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
z-index: 2;
}
.map-container {
width: 100%;
height: 100%;
@ -217,4 +236,6 @@ export default {
top: 0;
z-index: 1;
}
}
</style>

View File

@ -1,9 +1,4 @@
<!--
* @Description: 内容
* @ComponentName: ModuleContent
* @Author: wangzhigang11
* @Date: 2023-05-06 18:30
-->
<template>
<div class="Content " :style="curStyle">
<div class="content-box" :style="{padding}" :class="{ noneEvent }">
@ -84,6 +79,7 @@ import {getSize} from "@/utils/tools";
overflow: hidden;
position: relative;
pointer-events: none;
z-index: 111;
.content-border {
}

View File

@ -1,9 +1,4 @@
<!--
* @Description: 内容
* @ComponentName: ModuleContent
* @Author: wangzhigang11
* @Date: 2023-05-06 18:30
-->
<template>
<div class="bg">
<slot></slot>
@ -21,7 +16,7 @@
.bg {
width: 100%;
box-sizing: border-box;
height: 100%;
height: 100vh;
box-sizing: border-box;
background: url('~/assets/images/new/大背景.png') center no-repeat;
background-size: 100% 100%;

View File

@ -1,9 +1,4 @@
<!--
* @description:
* @component: TabItem
* @author: wangzhigang11
* @date: 2023/11/9 11:12
-->
<template>
<div class="TabItem" :class="{ selected }" v-on="$listeners" v-bind="$attrs">
<slot></slot>

View File

@ -1,9 +1,8 @@
<template>
<div style="text-align: left">
<div class="table-search" v-if="searchItems.length > 0">
<a-form class="ant-advanced-search-form" :form="form" @submit="handleSearch" layout="inline" @change="handleSearchFormChange">
<a-form class="ant-advanced-search-form" :form="form" @submit="handleSearch" layout="inline"
@change="handleSearchFormChange">
<a-form-item v-for="menuItem in searchItems" :key="menuItem.key" :label="menuItem.label">
<a-input
v-decorator="[menuItem.key]"
@ -15,30 +14,39 @@
:placeholder="menuItem.placeholder || ''"
v-else-if="menuItem.type === 'select'"
>
<a-select-option :value="cItem.value" v-for="cItem in menuItem.children || []" :key="cItem.value">{{ cItem.label }}</a-select-option>
<a-select-option :value="cItem.value" v-for="cItem in menuItem.children || []" :key="cItem.value">
{{ cItem.label }}
</a-select-option>
</a-select>
<a-range-picker
:placeholder="menuItem.placeholder || ''" v-decorator="[menuItem.key]" v-else-if="menuItem.type === 'dateRange'" format="YYYY-MM-DD" />
:placeholder="menuItem.placeholder || ''" v-decorator="[menuItem.key]"
v-else-if="menuItem.type === 'dateRange'" format="YYYY-MM-DD"/>
</a-form-item>
<a-form-item>
<a-button type="primary" html-type="submit" v-if="!hideSearch">查询</a-button>
<a-button :style="{ marginLeft: '8px' }" @click="reset" v-if="!hideSearch">重置</a-button>
<slot name="search-button" v-bind:search="form.getFieldsValue()"></slot>
</a-form-item>
<a-form-item>
<a-button type="primary" html-type="submit" v-if="!hideSearch">查询</a-button>
<a-button :style="{ marginLeft: '8px' }" @click="reset" v-if="!hideSearch">重置</a-button>
<slot name="search-button" v-bind:search="form.getFieldsValue()"></slot>
</a-form-item>
</a-form>
</div>
<a-divider v-if="!hideButton && searchItems.length > 0" />
<a-divider v-if="!hideButton && searchItems.length > 0"/>
<div class="table-operations" v-if="!hideButton">
<a-button @click="addRow" type="primary">
添加
</a-button>
</div>
<a-table v-bind="tableProps" :pagination="page" :row-key="primaryKey" :columns="realColumns" :data-source="tableDataSource" @change="handleChange" >
<a-table v-bind="tableProps" :pagination="page" :row-key="primaryKey" :columns="realColumns"
:data-source="tableDataSource" @change="handleChange">
<span slot="action" slot-scope="text, record">
<a-button type="danger" size="small" @click="deleteRow(record)">删除</a-button>
<a-divider type="vertical" />
<a-divider type="vertical"/>
<a-button type="primary" size="small" @click="editRow(record)">编辑</a-button>
</span>
<span slot="details" slot-scope="text, record">
<!-- <a-button type="danger" size="small" @click="deleteRow(record)">删除</a-button>-->
<!-- <a-divider type="vertical"/>-->
<a-button type="primary" size="small" @click="viewDetails(record)">详情</a-button>
</span>
</a-table>
<a-modal
:title="dialog.title"
@ -48,7 +56,7 @@
@cancel="handleCancel"
>
<a-form class="ant-advanced-search-form" :form="editForm" @submit="handleSearch" @change="handleSearchFormChange">
<a-form-item v-for="menuItem in formItems" :key="menuItem.key" :label="menuItem.label" v-if="!menuItem.hide">
<a-form-item v-for="menuItem in formItems" :key="menuItem.key" :label="menuItem.label" v-if="!menuItem.hide">
<a-input
v-bind="menuItem.props || {}"
v-decorator="gtDecorator(menuItem)"
@ -61,7 +69,9 @@
v-else-if="menuItem.type === 'select'"
v-bind="menuItem.props || {}"
>
<a-select-option :value="cItem.value" v-for="cItem in menuItem.children || []" :key="cItem.value">{{ cItem.label }}</a-select-option>
<a-select-option :value="cItem.value" v-for="cItem in menuItem.children || []" :key="cItem.value">
{{ cItem.label }}
</a-select-option>
</a-select>
<a-tree-select
v-bind="menuItem.props || {}"
@ -74,9 +84,15 @@
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
v-else-if="menuItem.type === 'treeSelect'"
>
<a-select-option :value="cItem.value" v-for="cItem in menuItem.children || []" :key="cItem.value">{{ cItem.label }}</a-select-option>
<a-select-option :value="cItem.value" v-for="cItem in menuItem.children || []" :key="cItem.value">
{{ cItem.label }}
</a-select-option>
</a-tree-select>
<a-range-picker v-bind="menuItem.props || {}" v-decorator="gtDecorator(menuItem)" v-else-if="menuItem.type === 'dateRange'" format="YYYY-MM-DD" />
<a-range-picker v-bind="menuItem.props || {}" v-decorator="gtDecorator(menuItem)"
v-else-if="menuItem.type === 'dateRange'" format="YYYY-MM-DD"/>
<a-date-picker style="width: 100%" v-decorator="gtDecorator(menuItem)" v-bind="menuItem.props || {}"
v-else-if="menuItem.type === 'date'" format="YYYY-MM-DD"/>
</a-form-item>
</a-form>
</a-modal>
@ -85,12 +101,13 @@
<script>
export default {
name: "user",
data () {
data() {
return {
cacheData: [],
isValidate: false,
tableDataSource: [],
form: this.$form.createForm(this, { name: `form_${new Date().valueOf()}` }),
editForm: this.$form.createForm(this, { name: `edit_form_${new Date().valueOf()}` }),
form: this.$form.createForm(this, {name: `form_${new Date().valueOf()}`}),
editForm: this.$form.createForm(this, {name: `edit_form_${new Date().valueOf()}`}),
dialog: {
title: '',
visible: false,
@ -126,12 +143,12 @@ export default {
//
formItems: {
type: Array,
default: ()=> []
default: () => []
},
//
columns: {
type: Array,
default: ()=> []
default: () => []
},
primaryKey: {
type: String,
@ -142,38 +159,44 @@ export default {
type: Object,
default: () => ({})
},
customSearch: {
type: Function,
default: () => null
}
},
computed: {
searchItems () {
searchItems() {
return this.formItems.filter(item => !!item.isSearch)
},
realColumns () {
if (this.hideAction) return [ ...this.columns ]
realColumns() {
if (this.hideAction) return [...this.columns]
return [
...this.columns,
{
title: '操作',
dataIndex: 'action',
scopedSlots: { customRender: 'action' },
scopedSlots: {customRender: 'action'},
fixed: 'right',
width: 155
},
]
}
},
watch: {
},
watch: {},
mounted() {
this.handleSearch()
},
methods: {
gtDecorator (menuItem) {
viewDetails(data) {
this.$emit('viewDetails', data)
},
gtDecorator(menuItem) {
if (menuItem.rules) {
this.isValidate = true
return [
menuItem.key,
{ rules: menuItem.rules }
{rules: menuItem.rules}
]
}
return [
@ -181,9 +204,9 @@ export default {
]
},
handleSearchFormChange(changedFields) {
this.searchFormModel = { ...this.searchFormModel, ...changedFields }
this.searchFormModel = {...this.searchFormModel, ...changedFields}
},
addRow () {
addRow() {
this.handleCancel()
this.$emit('edit', false)
this.dialog.visible = true
@ -191,7 +214,7 @@ export default {
async editRow(row) {
if (this.apiConf.detailApi) {
const {api, method, detailHandler} = this.apiConf.detailApi
const { data } = await this[`$${method}`](api, { [this.primaryKey]: row[this.primaryKey] })
const {data} = await this[`$${method}`](api, {[this.primaryKey]: row[this.primaryKey]})
this.selectRow = detailHandler && detailHandler(data) || data
} else {
this.selectRow = row
@ -215,7 +238,7 @@ export default {
cancelText: '再想想',
onOk() {
const { api,deleteKey, paramsType, method } = self.apiConf.deleteApi
const {api, deleteKey, paramsType, method} = self.apiConf.deleteApi
let params = {}
if (paramsType === 'Array') {
params = [row[self.primaryKey]]
@ -229,30 +252,36 @@ export default {
});
},
handleChange ({ pageSize, current }) {
handleChange({pageSize, current}) {
this.page.pageSize = pageSize
this.page.current = current
this.handleSearch()
},
reset() {
this.form.resetFields();
},
},
doSearch () {
if (this.customSearch) {
this.tableDataSource = this.customSearch(JSON.parse(JSON.stringify(this.cacheData)))
}
},
async handleSearch(e) {
e && e.preventDefault();
const values = this.form.getFieldsValue()
const { api, noPage, method } = this.apiConf.listApi
const { data } = await this[`$${method}`](api, {
const {api, noPage, method} = this.apiConf.listApi
const {data} = await this[`$${method}`](api, {
...values,
pageSize: this.page.pageSize,
current: this.page.current,
})
if (noPage) {
this.page = false
this.cacheData = data
this.tableDataSource = data
} else {
this.page.total = data.total || 0
this.cacheData = data.items
this.tableDataSource = data.items
}
},
@ -261,13 +290,13 @@ export default {
this.editForm.validateFields(async (err, values) => {
if (!err) {
if (this.dialog.isEdit) {
const { api, method, updateKey } = this.apiConf.editApi
const {api, method, updateKey} = this.apiConf.editApi
await this[`$${method}`](api, {
[updateKey || this.primaryKey]: this.selectRow[this.primaryKey],
...values
})
} else {
const { api, method } = this.apiConf.addApi
const {api, method} = this.apiConf.addApi
await this[`$${method}`](api, values)
}
this.handleCancel()
@ -277,13 +306,13 @@ export default {
} else {
const values = this.editForm.getFieldsValue()
if (this.dialog.isEdit) {
const { api, method, updateKey } = this.apiConf.editApi
const {api, method, updateKey} = this.apiConf.editApi
await this[`$${method}`](api, {
[updateKey || this.primaryKey]: this.selectRow[this.primaryKey],
...values
})
} else {
const { api, method } = this.apiConf.addApi
const {api, method} = this.apiConf.addApi
await this[`$${method}`](api, values)
}
this.handleCancel()
@ -306,9 +335,11 @@ export default {
.table-operations {
margin-bottom: 16px;
}
.ant-form-item {
margin-bottom: 0;
}
.ant-divider-horizontal {
margin: 16px 0;
}

View File

@ -39,6 +39,9 @@ export default {
color: rgba(255, 255, 255, 1);
text-align: left;
vertical-align: top;
a {
color: rgba(255, 255, 255, 1) !important;
}
&.small {
padding: 2px 10px;
background: linear-gradient(180deg, rgba(188, 216, 247, 0.4) 0%, rgba(152, 217, 237, 0.15) 48.61%, rgba(156, 255, 248, 0.4) 100%);

View File

@ -0,0 +1,60 @@
<template>
<div class="cusbutton" @click="$emit('click')" :class="{ flex, selected }">
<slot></slot>
</div>
</template>
<script>
export default {
name: "CusButton5",
props: {
flex: {
type: Boolean,
default: false
},
selected: {
type: Boolean,
default: false
}
}
}
</script>
<style scoped lang="less">
.cusbutton {
display: inline-block;
border-radius: 2.56px;
padding: 10px 13px;
/** 文本1 */
font-size: 16px;
font-weight: 400;
letter-spacing: 0px;
color: #fff;
text-align: center;
vertical-align: top;
cursor: pointer;
background: rgba(0, 128, 247, 0.2);
&.flex {
flex: 1;
}
&.selected {
background: rgba(0, 128, 247, 0.5);
}
&:hover {
background: rgba(0, 128, 247, 0.5);
}
}
</style>

View File

@ -1,9 +1,9 @@
<template>
<div class="cusdesc">
<div class="desc" v-for="(col, index) in columns" :key="index">
<div class="desc" v-for="(col, index) in columns" :key="index" :style="{ width: col.width || '50%' }">
<div class="desc-title">{{ col.title }}:</div>
<div class="desc-value">{{ data[col.key] }}</div>
<div class="desc-value">{{ data[col.key || col.dataIndex] }}</div>
</div>
</div>
</template>
@ -37,7 +37,11 @@ export default {
text-align: left;
vertical-align: top;
.desc {
width: 100%;
margin-top: 16px;
display: flex;
justify-content: flex-start;
align-items: center;
&:first-child {
margin-top: 0;
}

View File

@ -0,0 +1,61 @@
<template>
<div class="cusdesc">
<div class="desc" v-for="(col, index) in columns" :key="index">
<div class="desc-title">{{ col.title }}</div>
<div class="desc-value">{{ data[col.key || col.dataIndex] || defaultValue }}</div>
</div>
</div>
</template>
<script>
export default {
name: "CusDesc2",
props: {
columns: {
type: Array,
default: () => []
},
data: {
type: Object,
default: () => ({})
},
defaultValue: {
type: String,
default: ''
}
}
}
</script>
<style scoped lang="less">
.cusdesc {
width: 100%;
/** 文本1 */
font-size: 16px;
font-weight: 400;
letter-spacing: 0px;
line-height: 23.17px;
color: rgba(255, 255, 255, 1);
text-align: left;
vertical-align: top;
.desc {
width: 100%;
margin-top: 16px;
display: flex;
justify-content: space-between;
align-items: center;
height: 36px;
line-height: 36px;
background: rgba(1, 105, 216, 0.2);
border: 1px solid rgba(212, 230, 255, 0.1);
padding: 0 16px;
box-sizing: border-box;
&:first-child {
margin-top: 0;
}
}
}
</style>

View File

@ -2,7 +2,11 @@
<template>
<div class="custom-table">
<Curd v-bind="$attrs" v-on="$listeners"></Curd>
<Curd v-bind="$attrs" v-on="$listeners" ref="curd">
<template slot="search-button" slot-scope="{ search }">
<slot name="search-button" v-bind:search="search"></slot>
</template>
</Curd>
</div>
</template>
<script>
@ -10,11 +14,27 @@ import Curd from "./Curd.vue";
export default {
name: "CustomTable",
components: {Curd}
components: {Curd},
methods : {
doSearch () {
this.$refs.curd.doSearch()
},
}
}
</script>
<style scoped lang="less">
.custom-table {
/deep/ .ant-form-item-label > label {
color: #fff !important;
}
/deep/ .ant-table-header {
background-color: transparent !important;
border-bottom: 0px ;
}
/deep/ .ant-table-fixed-header > .ant-table-content > .ant-table-scroll > .ant-table-body {
background-color: transparent !important;
}
/deep/ .ant-table-thead > tr > th {
background: linear-gradient(180deg, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0) 100%);
color: rgba(255, 255, 255, 1);

View File

@ -0,0 +1,24 @@
<template>
<div class="faguiang event-auto">
<slot></slot>
</div>
</template>
<script>
export default {
name: "Faguang"
}
</script>
<style scoped lang="less">
.faguiang {
padding: 28px 24px;
opacity: 1;
background: linear-gradient(180deg, rgba(0, 196, 255, 0) 0%, rgba(16, 134, 173, 0.2) 100%);
border: 1px solid rgba(224, 254, 255, 1);
box-shadow:inset 1px 1px 13px rgba(0, 191, 255, 0.96), 0px 0px 17px rgba(0, 170, 255, 0.69);
border-radius: 10px;
}
</style>

View File

@ -1,9 +1,4 @@
<!--
* @Description: 内容
* @ComponentName: ModuleContent
* @Author: wangzhigang11
* @Date: 2023-05-06 18:30
-->
<template>
<div class="Content " :style="curStyle">
<div class="content-header" :class="{ border }"></div>

View File

@ -5,7 +5,7 @@
<div class="progress-item" v-for="(item, index) in rate" :key="index">
<BFC>
<div class="percent" slot="right">
{{ item.val * 100 }}
{{ (item.val * 100).toFixed(0) }}
<div class="unit">%</div>
</div>
<div class="info" slot="center">

View File

@ -5,7 +5,17 @@
<div class="header-content">
<div class="time"><a-icon type="clock-circle" style="margin-right: 10px;" />{{ time }}</div>
<div class="tq">{{ tq }}</div>
<p class="_title">{{ title }}一体化平台</p>
<p class="_title" v-if="customTitle">{{ customTitle }}</p>
<p class="_title" v-else>{{ customTitle || title }}一体化平台</p>
<div class="back" v-if="showBack" @click="() => $router.go(-1)">
<a-icon type="arrow-left" /> 返回</div>
<div class="btn-box">
<div class="btn" :key="btn.key" v-for="btn in btns" @click="$emit('click', btn)">
{{ btn.title }}
</div>
</div>
</div>
</div>
</template>
@ -27,6 +37,20 @@ export default {
return ''
}
},
props: {
customTitle: {
type: String,
default: ''
},
showBack: {
type: Boolean,
default: false
},
btns: {
type: Array,
default: () => []
}
},
data () {
return {
time: moment().format('YYYY-MM-DD HH:mm:ss'),
@ -56,6 +80,42 @@ export default {
box-sizing: border-box;
padding-top: 5px;
position: relative;
.btn-box {
display: flex;
justify-content: center;
align-items: center;
margin-top: 20px;
position: absolute;
top: 30px;
left: 50%;
transform: translateX(-50%);
.btn {
height: 30px;
pointer-events: auto;
color: #fff;
padding: 5px 10px;
background-color: #1890ff;
cursor: pointer;
margin-left: 10px;
&:first-child {
margin-left: 0;
}
}
}
.back {
position: absolute;
right: 10px;
top: 40px;
opacity: 1;
font-size: 20px;
font-weight: 400;
letter-spacing: 0px;
line-height: 28.96px;
color: rgba(35, 209, 232, 1);
vertical-align: top;
cursor: pointer;
}
.time {
position: absolute;
left: 20px;

View File

@ -0,0 +1,45 @@
<template>
<div class="web2tit">
<slot></slot>
</div>
</template>
<script>
export default {
name: "Web5Title"
}
</script>
<style scoped lang="less">
.web2tit {
width: 100%;
height: 48px;
line-height: 48px;
border-bottom: 1px solid rgba(255, 255, 255, 0.4);
/** 文本1 */
font-size: 14px;
font-weight: 500;
letter-spacing: 0px;
color: rgba(255, 255, 255, 1);
text-align: left;
vertical-align: top;
background-size: 10px 16px;
box-sizing: border-box;
padding-left: 20px;
position: relative;
&::after {
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
display: table;
content: ' ';
width: 10px;
height: 10px;
opacity: 1;
border: 2px solid rgba(255, 255, 255, 1);
border-radius: 50%;
}
}
</style>

36
layouts/default.vue Normal file
View File

@ -0,0 +1,36 @@
<template>
<div>
<nuxt />
</div>
</template>
<script>
import { mapActions, mapState } from 'vuex'
export default {
name: "default",
computed: {
...mapState({
info: state => state.system.info
})
},
created() {
this.getViewData()
},
methods: {
...mapActions('system', ['setInfo']),
async getViewData () {
if (!this.info) {
const { data } = await this.$get('/api/Home/view');
this.setInfo(data)
}
}
}
}
</script>
<style scoped lang="less">
</style>

17
layouts/loginLayout.vue Normal file
View File

@ -0,0 +1,17 @@
<template>
<div>
<nuxt />
</div>
</template>
<script>
export default {
name: "LoginLayout"
}
</script>
<style scoped lang="less">
</style>

46
middleware/auth.js Normal file
View File

@ -0,0 +1,46 @@
// 在某个适当的时间点检查登录状态是否过期
function isLoginExpired(loginTimestamp, expirationDuration) {
// 获取登录时间戳
// 如果没有登录时间戳,说明用户未登录或状态已过期
if (!loginTimestamp) {
return true;
}
// 计算登录时间和现在的时间差
const currentTimestamp = Date.now();
const duration = currentTimestamp - loginTimestamp;
// 如果时间差大于3小时的毫秒数则登录状态过期
return duration > expirationDuration;
}
export default function ({ route, redirect, store }) {
if (route.name === 'manager-login') {
return
}
if (localStorage.getItem('userInfo')) {
const cache = JSON.parse(localStorage.getItem('userInfo'))
const { expire, loginTime } = cache
// 在页面加载时检查登录状态
if (isLoginExpired(loginTime, expire)) {
// 用户登录已过期,执行登录过期的逻辑
console.log('登录已过期');
return redirect('/manager/login')
} else {
// 用户登录有效,执行登录有效的逻辑
store.dispatch('user/setUserInfo', cache)
if (route.path === '/') {
return redirect('/home')
}
}
} else {
// 假设用户信息存储在 Vuex store 中
const user = store.state.user
// 检查路由是否需要认证
if (!user.isLogin) {
return redirect('/manager/login')
}
}
}

View File

@ -39,6 +39,10 @@ export default {
'@/assets/styles/mixin.less'
],
router: {
middleware: 'auth' // 应用全局中间件
},
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [
'@/plugins/antd-ui',

View File

@ -1,9 +1,4 @@
<!--
* @description:
* @component: index
* @author: wangzhigang11
* @date: 2023/8/21 19:30
-->
<template>
<div class="index">
<div :style="autoStyle" class="iframe-container">

View File

@ -1,65 +1,143 @@
<template>
<div>
<a-page-header
:ghost="false"
style="border-bottom: 1px solid rgb(235, 237, 240)"
title="厂区车辆台账"
@back="() => $router.go(-1)"
/>
<a-row :gutter="16">
<a-col :span="6">
<a-card title="运输车辆" size="small">
<p>card content</p>
</a-card>
</a-col>
<a-col :span="6">
<a-card title="国Ⅵ输车辆" size="small">
<p>card content</p>
</a-card>
</a-col>
<a-col :span="6">
<a-card title="非道路工程机械" size="small">
<p>card content</p>
</a-card>
</a-col>
<a-col :span="6">
<a-card title="燃油运输车辆" size="small">
<p>card content</p>
</a-card>
</a-col>
</a-row>
<new-bg>
<flex-col>
<system-title show-back custom-title="磅秤台账"/>
<ModuleContent padding="0px 20px 20px">
<flex-col>
<Butgroup2 class="type-button">
<cus-button :class="['tabs-button',activeTabsButton == null?'active-tabs-button':'']"
@click="tabsChange(null)">
全部
</cus-button>
<cus-button :class="['tabs-button',activeTabsButton == 1?'active-tabs-button':'']" @click="tabsChange(1)">
东门
</cus-button>
<cus-button :class="['tabs-button',activeTabsButton == 2?'active-tabs-button':'']" @click="tabsChange(2)">
东门
</cus-button>
<cus-button :class="['tabs-button',activeTabsButton == 3?'active-tabs-button':'']" @click="tabsChange(3)">
东门
</cus-button>
<cus-button :class="['tabs-button',activeTabsButton == 4?'active-tabs-button':'']" @click="tabsChange(4)">
东门
</cus-button>
</Butgroup2>
<Split num="10"></Split>
<ModuleContent2 bg padding="20px">
<a-row :gutter="16">
<a-col :span="18">
<CustomTable
hide-action
hide-search
hide-button
:columns="columns"
:api-conf="apiConf"
:form-items="formItems"
@edit="editHandler"
@viewDetails="viewDetails"
>
<template slot="search-button" slot-scope="{ search }">
<a-button type="primary" @click="exportList(search)">导出历史数据</a-button>
<Split num="10"></Split>
</template>
</CustomTable>
</a-col>
<a-col :span="6">
<flex-col>
<web3-title>驾驶人详情</web3-title>
<ModuleContent padding="0">
<flex-col>
<img :src="selectedRecord.imgUrl" alt="" class="car-preview">
<butgroup2>
<cus-button2 flex>进出场抓拍图</cus-button2>
<!-- <cus-button2>行驶证-正面</cus-button2>-->
<!-- <cus-button2>行驶证-反面</cus-button2>-->
<!-- <cus-button2>环保清单</cus-button2>-->
</butgroup2>
<ModuleContent padding="20px 27px" class="desc">
<cus-desc :data="selectedRecord" :columns="descColumns"></cus-desc>
</ModuleContent>
</flex-col>
<a-divider />
<Curd
hide-action
hide-search
hide-button
:columns="columns"
:api-conf="apiConf"
:form-items="formItems"
@edit="editHandler"
>
<template slot="search-button" slot-scope="{ search }">
<a-button type="primary" @click="exportList(search)">导出历史数据</a-button>
</template>
</Curd>
</div>
</ModuleContent>
</flex-col>
</a-col>
</a-row>
</ModuleContent2>
</flex-col>
</ModuleContent>
</flex-col>
</new-bg>
</template>
<script>
import Curd from "../../components/smallCommon/Curd.vue";
import moment from 'moment'
import SystemTitle from "../../components/smallCommon/SystemTitle.vue";
import NewBg from "../../components/NewBg.vue";
import FlexCol from "../../components/FlexCol.vue";
import ModuleContent from "../../components/ModuleContent.vue";
import ModuleContent2 from "../../components/smallCommon/ModuleContent2.vue";
import CustomTable from "../../components/smallCommon/CustomTable.vue";
import Split from "../../components/Split.vue";
import Web3Title from "../../components/smallCommon/Web3Title.vue";
import CusDesc from "../../components/smallCommon/CusDesc.vue";
import CusButton2 from "../../components/smallCommon/CusButton2.vue";
import Butgroup2 from "../../components/smallCommon/butgroup2.vue";
import CusButton from "../../components/smallCommon/CusButton4.vue";
export default {
name: "user",
layout: "user",
components: {
CusButton,
Butgroup2, CusButton2, CusDesc,
Web3Title,
Split,
CustomTable,
ModuleContent2,
ModuleContent, FlexCol, NewBg, SystemTitle,
Curd
},
data () {
data() {
return {
isEdit: false,
roles: [],
descColumns: [
{
title: '车牌号',
dataIndex: 'carNumber',
width: '100%'
}, {
title: '车牌颜色',
dataIndex: 'carColorString',
width: '100%'
}, {
title: '车辆类型',
dataIndex: 'carType',
width: '100%'
}, {
title: '车辆类型',
dataIndex: 'carType',
width: '100%'
}, {
title: '排放等级',
dataIndex: 'effluent',
width: '100%'
}, {
title: 'VIN',
dataIndex: 'vin',
width: '100%'
}, {
title: '发动机号',
dataIndex: 'entryExitPictureUrl',
width: '100%'
}, {
title: '注册日期',
dataIndex: 'registrationDate',
width: '100%'
}
],
selectedRecord: {},
columns: [
{
dataIndex: 'outTime',
@ -80,7 +158,7 @@ export default {
dataIndex: 'newCar',
key: 'newCar',
title: '新能源',
customRender (text) {
customRender(text) {
if (text) return '是'
return '否'
}
@ -97,13 +175,16 @@ export default {
}
],
apiConf: {
listApi: { api: '/api/Ledger/list', method: 'get' },
}
listApi: {api: '/api/Ledger/list', method: 'get'},
},
isShowInfoDetails: false,
activeButton: 1,
activeTabsButton: null
}
},
computed: {
formItems () {
formItems() {
return [
{
type: 'dateRange',
@ -112,7 +193,7 @@ export default {
isSearch: true,
placeholder: ['请选择开始日期', '请选择结束日期'],
rules: [
{ required: true, message: '请选择时间范围' }
{required: true, message: '请选择时间范围'}
],
fields: ['startTime', 'endTime']
}
@ -123,18 +204,136 @@ export default {
},
methods: {
editHandler (isEdit) {
editHandler(isEdit) {
this.isEdit = isEdit
},
exportList ({ time }) {
const [ start, end ] = time
exportList({time}) {
const [start, end] = time
const fmt = 'YYYY-MM-DD'
window.open(`http://101.43.201.20:5000/api/Ledger/export?start=${moment(start).format(fmt)}&end=${moment(end).format(fmt)}`, '_blank')
},
viewDetails(data) {
console.log('data:', data)
this.isShowInfoDetails = true
},
//
viewImgByType(value) {
this.activeButton = value
},
//
closeDetails() {
this.isShowInfoDetails = false
},
//
tabsChange(value) {
this.activeTabsButton = value
}
}
}
</script>
<style scoped lang="less">
.car-preview {
width: 100%;
height: 260px;
}
.desc {
background: rgba(24, 131, 201, 0.2);
border: 1px solid rgba(15, 81, 122, 1);
}
.type-button {
max-width: 70%;
.tabs-button {
height: 40px;
cursor: pointer;
border: 1px solid #e8e8e8;
width: 200px;
text-align: center;
line-height: 40px;
}
.active-tabs-button {
background: #0088ff;
color: #FFFFFF;
}
}
.data-info {
display: flex;
flex-flow: row;
.left-table {
flex: 1;
}
.right-details {
width: 600px;
height: 700px;
display: flex;
flex-flow: column;
align-items: center;
border: 1px solid #e8e8e8;
margin-left: 10px;
.header-title {
font-size: 18px;
text-align: center;
}
img {
margin-top: 10px;
width: 500px;
height: 300px;
}
.group-button {
margin-top: 20px;
display: flex;
flex-flow: row;
width: 500px;
justify-content: space-between;
._button {
width: 100px;
height: 50px;
border: 1px solid #777777;
cursor: pointer;
text-align: center;
line-height: 50px;
}
.active_button {
background: #0088ff;
color: #FFFFFF;
}
}
.details-info {
padding-left: 50px;
width: 100%;
flex: 1;
display: flex;
flex-flow: column;
justify-content: space-around;
align-items: flex-start;
.details-info-item {
display: flex;
flex-flow: row;
}
}
.footer-button {
height: 30px;
margin-bottom: 10px;
cursor: pointer;
}
}
}
</style>

View File

@ -2,10 +2,9 @@
<template>
<new-bg>
<flex-col>
<system-title/>
<system-title show-back />
<ModuleContent padding="20px">
<flex-col>
<web2-title>清洁运输</web2-title>
<ModuleContent padding="0 20px 20px">
<BFC>
<div class="sou-suo-kuang" slot="right">
@ -27,9 +26,9 @@
<img :src="selectedRecord.imgUrl" alt="" class="car-preview">
<butgroup2>
<cus-button2 flex>进出场抓拍图</cus-button2>
<cus-button2>行驶证-正面</cus-button2>
<cus-button2>行驶证-反面</cus-button2>
<cus-button2>环保清单</cus-button2>
<!-- <cus-button2>行驶证-正面</cus-button2>-->
<!-- <cus-button2>行驶证-反面</cus-button2>-->
<!-- <cus-button2>环保清单</cus-button2>-->
</butgroup2>
<ModuleContent padding="20px 27px" class="desc">
<cus-desc :data="selectedRecord" :columns="descColumns"></cus-desc>
@ -75,7 +74,9 @@
hide-button
:columns="columns"
:api-conf="apiConf"
:tableProps="tableProps"
:table-props="tableProps"
:custom-search="customSearch"
ref="cusTable"
/>
</div>
@ -87,10 +88,15 @@
</BFC>
</ModuleContent>
<butgroup>
<cus-button>厂区车辆台账</cus-button>
<cus-button>清洁运输趋势</cus-button>
<cus-button>磅秤台账</cus-button>
<cus-button>门禁监控</cus-button>
<cus-button>
<nuxt-link to="/cleanTravel/ledger">厂区车辆台账</nuxt-link>
</cus-button>
<cus-button>
<nuxt-link to="/cleanTravel/trend">清洁运输趋势</nuxt-link>
</cus-button>
<cus-button>
<nuxt-link to="/cleanTravel/bangcheng">磅秤台账</nuxt-link>
</cus-button>
</butgroup>
</flex-col>
</ModuleContent>
@ -142,6 +148,7 @@ export default {
const self = this
return {
tableProps: {
scroll: {y: 500},
customRow (record) {
return {
on: {
@ -157,7 +164,7 @@ export default {
}
},
apiConf: {
listApi: { api: '/api/Transport/list', method: 'get' },
listApi: { api: '/api/Transport/list', method: 'get', noPage: true },
},
selectedRecord: {},
bgStr,
@ -172,19 +179,37 @@ export default {
dataSource: [],
descColumns: [
{
title: '设备掉线',
dataIndex: 'deviceName',
width: '33.333%'
},
{
title: '故障异常',
dataIndex: 'errorName',
width: '33.333%'
},
{
title: '异常报警',
dataIndex: 'errorImg',
width: '33.333%'
title: '车牌号',
dataIndex: 'carNumber',
width: '100%'
},{
title: '车牌颜色',
dataIndex: 'carColorString',
width: '100%'
},{
title: '车辆类型',
dataIndex: 'carType',
width: '100%'
},{
title: '车辆类型',
dataIndex: 'carType',
width: '100%'
},{
title: '排放等级',
dataIndex: 'effluent',
width: '100%'
},{
title: 'VIN',
dataIndex: 'vin',
width: '100%'
},{
title: '发动机号',
dataIndex: 'entryExitPictureUrl',
width: '100%'
},{
title: '注册日期',
dataIndex: 'registrationDate',
width: '100%'
}
],
columns: [
@ -230,17 +255,20 @@ export default {
title: state => state.system.title,
})
},
watch : {
searchCarNum () {
this.$nextTick(() => {
if (this.$refs.cusTable) {
this.$refs.cusTable.doSearch()
}
})
}
},
mounted() {
this.getCount()
this.getDataSource()
this.$nextTick(() => {
const win = window.top
this.$http.get('http://101.43.201.20:5000/api/Home/view').then(({data}) => {
win.document.title = data.home.title
this.setTitle(data.home.title)
this.setInfo(data)
})
if (this.$refs.module) {
const offsetHeight = this.$refs.module.$el.offsetHeight - 40
this.tableH = offsetHeight
@ -337,6 +365,11 @@ export default {
})
}
},
customSearch (data = []) {
if (!this.searchCarNum) return data
return data.filter(item => item.carNumber.indexOf(this.searchCarNum) >= 0)
}
}
}
</script>
@ -346,7 +379,6 @@ body, html, #__nuxt, #__layout {
width: 100%;
height: 100%;
overflow: hidden;
background: #09151F;
}
.list-enter-active, .list-leave-active {

View File

@ -1,41 +1,38 @@
<template>
<div>
<a-page-header
:ghost="false"
style="border-bottom: 1px solid rgb(235, 237, 240)"
title="厂区车辆台账"
@back="() => $router.go(-1)"
/>
<a-row :gutter="16">
<a-col :span="6">
<a-card title="运输车辆" size="small">
<p>card content</p>
</a-card>
</a-col>
<a-col :span="6">
<a-card title="国Ⅵ输车辆" size="small">
<p>card content</p>
</a-card>
</a-col>
<a-col :span="6">
<a-card title="非道路工程机械" size="small">
<p>card content</p>
</a-card>
</a-col>
<a-col :span="6">
<a-card title="燃油运输车辆" size="small">
<p>card content</p>
</a-card>
</a-col>
</a-row>
<new-bg>
<flex-col>
<system-title show-back/>
<ModuleContent padding="0px 20px 20px">
<web2-title>厂区车辆台账</web2-title>
<Split :height="16"></Split>
<div style="height: 144px;width: 100%;">
<ModuleContent2 bg bg-str :border="false">
<butgroup2 style="height: 100%;">
<ModuleContent2 bg bg-color border>
<miaoshu title="运输车辆" :value="headCount.t1" color="rgba(42, 207, 255, 1)"></miaoshu>
</ModuleContent2>
<ModuleContent2 bg bg-color border style="margin-left: 16px;">
<miaoshu title="国Ⅵ输车辆" :value="headCount.t2" color="rgba(255, 171, 87, 1)"></miaoshu>
</ModuleContent2>
<ModuleContent2 bg bg-color border style="margin-left: 16px;">
<miaoshu title="非道路工程机械" :value="headCount.t3" color="rgba(122, 175, 255, 1)"></miaoshu>
</ModuleContent2>
<ModuleContent2 bg bg-color border style="margin-left: 16px;">
<miaoshu title="燃油运输车辆" :value="headCount.t4" color="rgba(76, 243, 129, 1)"></miaoshu>
</ModuleContent2>
</butgroup2>
</ModuleContent2>
</div>
<a-divider />
<Curd
hide-action
<CustomTable
hide-search
hide-button
hide-action
:columns="columns"
:api-conf="apiConf"
:form-items="formItems"
@ -43,21 +40,41 @@
>
<template slot="search-button" slot-scope="{ search }">
<a-button type="primary" @click="exportList(search)">导出历史数据</a-button>
<Split height="10"></Split>
</template>
</Curd>
</div>
</CustomTable>
</ModuleContent>
</flex-col>
</new-bg>
</template>
<script>
import Curd from "../../components/smallCommon/Curd.vue";
import moment from 'moment'
import SystemTitle from "../../components/smallCommon/SystemTitle.vue";
import NewBg from "../../components/NewBg.vue";
import FlexCol from "../../components/FlexCol.vue";
import ModuleContent from "../../components/ModuleContent.vue";
import CustomTable from "../../components/smallCommon/CustomTable.vue";
import Miaoshu from "../../components/smallCommon/miaoshu.vue";
import ModuleContent2 from "../../components/smallCommon/ModuleContent2.vue";
import Butgroup2 from "../../components/smallCommon/butgroup2.vue";
import Split from "../../components/smallCommon/Split.vue";
import Web2Title from "../../components/smallCommon/Web2Title.vue";
export default {
name: "user",
layout: "user",
components: {
Web2Title,
Split,
Butgroup2, ModuleContent2, Miaoshu,
CustomTable,
ModuleContent,
FlexCol, NewBg, SystemTitle,
Curd
},
data () {
return {
headCount: {},
isEdit: false,
roles: [],
columns: [
@ -88,7 +105,7 @@ export default {
{
dataIndex: 'emissions',
key: 'emissions',
title: '燃油车'
title: '燃油车标准'
},
{
dataIndex: 'createDateTime',
@ -98,6 +115,7 @@ export default {
],
apiConf: {
listApi: { api: '/api/Ledger/list', method: 'get' },
addApi: {api: '/api/Ledger/add', method: 'post',}
}
}
},
@ -110,19 +128,68 @@ export default {
key: 'time',
label: '日期',
isSearch: true,
hide: true,
placeholder: ['请选择开始日期', '请选择结束日期'],
rules: [
{ required: true, message: '请选择时间范围' }
],
fields: ['startTime', 'endTime']
},
{
type: 'date',
key: 'outTime',
label: '日期',
placeholder: '请选择日期'
},
{
type: 'input',
key: 'carNum',
label: '车牌号',
placeholder: '请输入车牌号'
},
{
type: 'input',
key: 'carModel',
label: '车型',
placeholder: '请输入车型'
},
{
type: 'select',
key: 'newCar',
label: '新能源',
placeholder: '是否新能源',
children: [
{ label: '是', value: '是' },
{ label: '否', value: '否' },
]
},
{
type: 'select',
key: 'emissions',
label: '燃油车标准',
placeholder: '',
},
{
type: 'date',
key: 'createDateTime',
label: '出厂日期',
placeholder: '',
}
]
}
},
created() {
this.$get('/api/Ledger/HeaderCount').then(({data}) => {
this.headCount = data || {}
})
},
methods: {
add () {
},
editHandler (isEdit) {
this.isEdit = isEdit
},

View File

@ -1,52 +1,66 @@
<template>
<div>
<a-page-header
:ghost="false"
title="清洁运输+趋势"
@back="() => $router.go(-1)"
/>
<a-divider style="margin-top: 0;" />
<a-row :gutter="16">
<a-col :span="12">
<a-card>
<div slot="title">
运输总量: {{ yunshuzongliang }}
</div>
<new-bg>
<flex-col>
<system-title show-back/>
<ModuleContent padding="0px 20px 20px">
<web2-title>清洁运输+趋势</web2-title>
<Split height="16"/>
<a-row :gutter="16">
<a-col :span="6">
<ModuleContent2 :border="false" padding="0">
<web3-title>运输车辆占比</web3-title>
<web3-title>运输量占比</web3-title>
</ModuleContent2>
</a-col>
<a-col :span="18">
<CustomTable
hide-action
hide-search
hide-button
:columns="columns"
:api-conf="apiConf"
:form-items="formItems"
>
<template slot="search-button" slot-scope="{ search }">
<a-button type="primary" @click="exportList(search)">查询</a-button>
<a-button type="primary" @click="exportList(search)" style="margin-left: 10px;">导出</a-button>
<Split height="10"></Split>
</template>
</CustomTable>
</a-col>
</a-row>
<Curd
hide-action
hide-search
hide-button
:columns="columns"
:api-conf="apiConf"
:form-items="formItems"
>
</Curd>
</a-card>
</ModuleContent>
</flex-col>
</new-bg>
</a-col>
<a-col :span="12">
<a-card title="国Ⅵ输车辆" size="small">
<p>card content</p>
</a-card>
</a-col>
</a-row>
</div>
</template>
<script>
import Curd from "../../components/smallCommon/Curd.vue";
import moment from 'moment'
import SystemTitle from "../../components/smallCommon/SystemTitle.vue";
import NewBg from "../../components/NewBg.vue";
import FlexCol from "../../components/FlexCol.vue";
import ModuleContent from "../../components/ModuleContent.vue";
import CustomTable from "../../components/smallCommon/CustomTable.vue";
import Split from "../../components/smallCommon/Split.vue";
import Web2Title from "../../components/smallCommon/Web2Title.vue";
import ModuleContent2 from "../../components/smallCommon/ModuleContent2.vue";
import CustomDesc2 from "../../components/smallCommon/CusDesc2.vue";
import Web3Title from "../../components/smallCommon/Web3Title.vue";
export default {
name: "user",
layout: "user",
components: {
Web3Title,
CustomDesc2, ModuleContent2,
Web2Title,
Split,
CustomTable,
ModuleContent, FlexCol, NewBg, SystemTitle,
Curd
},
data () {
data() {
return {
yunshuzongliang: 0,
isEdit: false,
@ -71,7 +85,7 @@ export default {
dataIndex: 'newCar',
key: 'newCar',
title: '新能源',
customRender (text) {
customRender(text) {
if (text) return '是'
return '否'
}
@ -88,14 +102,26 @@ export default {
}
],
apiConf: {
listApi: { api: '/api/Transport/list', method: 'get' },
listApi: {api: '/api/Transport/list', method: 'get'},
}
}
},
computed: {
formItems () {
formItems() {
return [
{
type: 'dateRange',
key: 'time',
label: '日期',
isSearch: true,
hide: true,
placeholder: ['请选择开始日期', '请选择结束日期'],
rules: [
{required: true, message: '请选择时间范围'}
],
fields: ['startTime', 'endTime']
},
]
}
},
@ -104,16 +130,16 @@ export default {
},
methods: {
getyunshuzongliang () {
getyunshuzongliang() {
/*this.$get('/api/Transport/count').then(({ data }) => {
this.yunshuzongliang = data
})*/
},
editHandler (isEdit) {
editHandler(isEdit) {
this.isEdit = isEdit
},
exportList ({ time }) {
const [ start, end ] = time
exportList({time}) {
const [start, end] = time
const fmt = 'YYYY-MM-DD'
window.open(`http://101.43.201.20:5000/api/Ledger/export?start=${moment(start).format(fmt)}&end=${moment(end).format(fmt)}`, '_blank')
}

View File

@ -1,6 +1,10 @@
<!--峰煤监控系统-->
<template>
<new-bg>
<flex-col>
<system-title />
<div class="center-panel">
<Map type="middle" @pointClick="pointClick" />
</div>
@ -37,8 +41,8 @@
清洁运输比例
<template slot="action">
<butgroup2 style="height: 20px;line-height: 20px;">
<cus-button4 @click="active = 'Yesterday'" :selected="active === 'Yesterday'">昨日</cus-button4>
<cus-button4 @click="active = 'LastWeek'" :selected="active === 'LastWeek'">上周</cus-button4>
<cus-button4 @click="active = 'yesterday'" :selected="active === 'yesterday'">昨日</cus-button4>
<cus-button4 @click="active = 'lastWeek'" :selected="active === 'lastWeek'">上周</cus-button4>
</butgroup2>
</template>
</web3-title>
@ -53,10 +57,10 @@
<ModuleContent padding="20px 0 0" height="140">
<div class="pf">
<div class="t">当前VOC的日排放量</div>
<div class="v">{{ todaypf.voc || 0 }}mg/m3</div>
<div class="v">{{ todaypf.today?.voc || 0 }}mg/m3</div>
</div><div class="pf">
<div class="t">当前CEMS的日排放量</div>
<div class="v">{{ todaypf.cems || 0 }}mg/m3</div>
<div class="v">{{ todaypf.today?.cems || 0 }}mg/m3</div>
</div>
</ModuleContent>
@ -80,15 +84,24 @@
<butgroup class="real-data">
<cus-button>有组织</cus-button>
<cus-button>无组织</cus-button>
<cus-button>清洁运输</cus-button>
<cus-button>视频广场</cus-button>
<cus-button>
<nuxt-link to="/youzuzhi/paifang">有组织</nuxt-link>
</cus-button>
<cus-button>
<nuxt-link to="/wuzuzhi/paifang">无组织</nuxt-link>
</cus-button>
<cus-button>
<nuxt-link to="/cleanTravel/home">清洁运输</nuxt-link>
</cus-button>
<cus-button>
<nuxt-link to="/video/list">视频广场</nuxt-link>
</cus-button>
</butgroup>
</div>
</BFC>
</ModuleContent>
</flex-col>
</flex-col>
</new-bg>
</template>
@ -248,7 +261,7 @@ export default {
data () {
return {
mapTab: 'rl',
active: 'Yesterday',
active: 'yesterday',
columnsForTable: [
{
@ -258,12 +271,12 @@ export default {
},
{
title: '报警时间',
dataIndex: 'CreateDateTime',
dataIndex: 'time',
width: '33.333%'
},
{
title: '报警内容',
dataIndex: 'AlertContent',
dataIndex: 'alarmName',
width: '33.333%'
},
]
@ -355,7 +368,6 @@ body, html, #__nuxt, #__layout {
width: 100%;
height: 100%;
overflow: hidden;
background: #09151F;
}
.list-enter-active, .list-leave-active {

View File

@ -1,9 +1,4 @@
<!--
* @description:
* @component: index
* @author: wangzhigang11
* @date: 2023/8/21 19:30
-->
<template>
<div class="index">
<div :style="autoStyle" class="iframe-container">

View File

@ -37,10 +37,12 @@
</template>
<script>
import { mapActions } from 'vuex'
function hasErrors(fieldsError) {
return Object.keys(fieldsError).some(field => fieldsError[field]);
}
export default {
layout: 'LoginLayout',
data() {
return {
hasErrors,
@ -54,6 +56,7 @@ export default {
});
},
methods: {
...mapActions('user', ['setUserInfo']),
// Only show error after a field is touched.
usernameError() {
const { getFieldError, isFieldTouched } = this.form;
@ -69,8 +72,8 @@ export default {
this.form.validateFields(async (err, values) => {
if (!err) {
const { data } = await this.$post('/api/User/login', values)
localStorage.setItem('userInfo', JSON.stringify(data))
this.$router.replace({ path: '/web1' })
this.setUserInfo({ expire: 1 * 60 * 60 * 1000, userInfo: data, loginTime: Date.now() })
this.$router.replace({ path: '/home' })
}
});
},

View File

@ -156,7 +156,6 @@ body, html, #__nuxt, #__layout {
width: 100%;
height: 100%;
overflow: hidden;
background: #09151F;
}
.list-enter-active, .list-leave-active {

25
pages/video/list.vue Normal file
View File

@ -0,0 +1,25 @@
<script>
import SystemTitle from "../../components/smallCommon/SystemTitle.vue";
import NewBg from "../../components/NewBg.vue";
import FlexCol from "../../components/FlexCol.vue";
import ModuleContent from "../../components/ModuleContent.vue";
export default {
name: "list",
components: {ModuleContent, FlexCol, NewBg, SystemTitle}
}
</script>
<template>
<new-bg>
<flex-col>
<system-title show-back custom-title="视频广场" />
<ModuleContent padding="0px 20px 20px">
</ModuleContent>
</flex-col>
</new-bg>
</template>
<style scoped lang="less">
</style>

View File

@ -260,7 +260,6 @@ export default {
body, html, #__nuxt, #__layout {
width: 100%;
height: 100%;
background-color: #000;
overflow: hidden;
}

View File

@ -1,11 +0,0 @@
<script setup>
</script>
<template>
</template>
<style scoped lang="less">
</style>

View File

@ -5,11 +5,10 @@
<Map type="middle" @pointClick="pointClick" />
</div>
<flex-col class="main">
<system-title/>
<ModuleContent none-event padding="0 20px 20px">
<system-title show-back custom-title="环境治理"/>
<ModuleContent none-event padding="0 50px 20px">
<BFC>
<flex-col slot="left" width="412">
<web2-title>环境治理</web2-title>
<ModuleContent padding="20px 0" height="218">
<div class="video"></div>
</ModuleContent>
@ -177,12 +176,6 @@ export default {
mounted() {
this.$nextTick(() => {
const win = window.top
this.$http.get('http://101.43.201.20:5000/api/Home/view').then(({data}) => {
win.document.title = data.home.title
this.setTitle(data.home.title)
this.setInfo(data)
})
if (this.$refs.module) {
const offsetHeight = this.$refs.module.$el.offsetHeight - 40
this.tableH = offsetHeight
@ -276,7 +269,6 @@ body, html, #__nuxt, #__layout {
width: 100%;
height: 100%;
overflow: hidden;
background: #09151F;
}
.list-enter-active, .list-leave-active {

View File

@ -0,0 +1,36 @@
<template><new-bg>
<flex-col>
<system-title show-back custom-title="环卫巡航" />
<ModuleContent padding="0px 20px 20px">
<div class="_map">
<Map></Map>
</div>
</ModuleContent>
</flex-col>
</new-bg>
</template>
<script>
import Map from "../../components/Map.vue";
import SystemTitle from "../../components/smallCommon/SystemTitle.vue";
import NewBg from "../../components/NewBg.vue";
import FlexCol from "../../components/FlexCol.vue";
import ModuleContent from "../../components/ModuleContent.vue";
export default {
name: "huanweixunhang",
components: {
ModuleContent,
FlexCol, NewBg, SystemTitle,
Map
}
}
</script>
<style scoped lang="less">
._map {
width: 100%;
height: 100%;
position: relative;
}
</style>

116
pages/wuzuzhi/paifang.vue Normal file
View File

@ -0,0 +1,116 @@
<template>
<new-bg>
<flex-col>
<system-title show-back/>
<Map></Map>
<ModuleContent padding="0px 50px 20px" class="event-none" none-event>
<web2-title>无组织排放</web2-title>
<a-row :gutter="16" style="height: calc(100% - 62px);margin-top: 16px;">
<a-col :span="5" style="height: 100%;">
<div class="con" style="height: 100%;display: flex;flex-direction: column; width: 100%;">
<web3-title>设备数量统计</web3-title>
<Split height="10"></Split>
<ModuleContent2 :border="false" height="30%" padding="0">
<custom-desc2 default-value="0" :data="tongji" :columns="descColumns"></custom-desc2>
</ModuleContent2>
<web3-title>报警类型数据分析</web3-title>
<Split height="10"></Split>
<ModuleContent2 :border="false" padding="0">
</ModuleContent2>
</div>
</a-col>
<a-col span="14">
<butgroup :bg="false">
<cus-button5>干雾点位置</cus-button5>
<cus-button5>TSP点位</cus-button5>
<cus-button5>微站点位</cus-button5>
<cus-button5>雾炮点位</cus-button5>
<cus-button5>雾桩点位</cus-button5>
<cus-button5>洗车机点位</cus-button5>
</butgroup>
</a-col>
<a-col :span="5" class="event-auto" style="height: 100%;">
<FlexCol>
<ModuleContent2 :border="false" padding="0">
</ModuleContent2>
<web3-title>项目介绍</web3-title>
<Split height="10"></Split>
<ModuleContent2 :border="false" padding="0">
</ModuleContent2>
</FlexCol>
</a-col>
</a-row>
<butgroup class="bottom-btn">
<cus-button>
<nuxt-link to="/wuzuzhi/xichejiguanli">洗车机管理</nuxt-link>
</cus-button>
<cus-button>
<nuxt-link to="/wuzuzhi/huanjingzhili">环境治理</nuxt-link>
</cus-button>
<cus-button>
<nuxt-link to="/wuzuzhi/huanweixunhang">环卫巡航</nuxt-link>
</cus-button>
</butgroup>
</ModuleContent>
</flex-col>
</new-bg>
</template>
<script>
import Map from "../../components/Map.vue";
import SystemTitle from "../../components/smallCommon/SystemTitle.vue";
import NewBg from "../../components/NewBg.vue";
import FlexCol from "../../components/FlexCol.vue";
import ModuleContent from "../../components/ModuleContent.vue";
import Butgroup from "../../components/smallCommon/butgroup.vue";
import CusButton from "../../components/smallCommon/CusButton.vue";
import Web3Title from "../../components/smallCommon/Web3Title.vue";
import ModuleContent2 from "../../components/smallCommon/ModuleContent2.vue";
import Split from "../../components/smallCommon/Split.vue";
import CusDesc from "../../components/smallCommon/CusDesc.vue";
import Web2Title from "../../components/smallCommon/Web2Title.vue";
import CustomDesc2 from "../../components/smallCommon/CusDesc2.vue";
import CusButton3 from "../../components/smallCommon/CusButton3.vue";
import CusButton5 from "../../components/smallCommon/CusButton5.vue";
export default {
name: "paifang",
components: {
CusButton5,
CusButton3,
CustomDesc2,
Web2Title,
CusDesc,
Split,
ModuleContent2,
Web3Title,
CusButton, Butgroup,
ModuleContent,
FlexCol, NewBg, SystemTitle,
Map
},
data () {
return {
tongji: {},
descColumns: [
{ title: '设备数量', key: 'total' },
{ title: '运行设备数量', key: 'total' },
{ title: '设备异常数量', key: 'total' },
{ title: '关闭设备数量', key: 'total' },
]
}
}
}
</script>
<style scoped lang="less">
</style>

View File

@ -0,0 +1,278 @@
<template>
<new-bg>
<flex-col>
<system-title show-back/>
<Map></Map>
<ModuleContent padding="0px 50px 20px" class="event-none" none-event>
<web2-title>洗车机管理</web2-title>
<Split height="16"></Split>
<a-row :gutter="16" style="height: calc(100% - 62px);">
<a-col :span="5" style="height: 100%;">
<FlexCol>
<ModuleContent2 bg height="490">
<FlexCol>
<web3-title>洗车机列表</web3-title>
<Split height="10"></Split>
<ModuleContent2 :border="false" padding="0">
<div :class="['car-washing-machine-tabs',activeCarTabs ==1?'active-car-washing-machine-tabs':'']"
@click="carChange(1)">
<div class="rank-num">1</div>
<div class="car-washing-machine-name">西门洗车</div>
<div class="state-icon">
正常
</div>
</div>
</ModuleContent2>
</FlexCol>
</ModuleContent2>
<ModuleContent2 bg>
<FlexCol>
<web3-title>历史记录</web3-title>
<Split height="10"></Split>
<ModuleContent2 :border="false" padding="0">
<CustomTable
hide-action
hide-search
hide-button
:columns="columns"
:api-conf="apiConf"
:form-items="formItems"
@edit="editHandler"
>
<template slot="search-button" slot-scope="{ search }">
<a-button type="primary" @click="exportList(search)">导出历史数据</a-button>
<Split height="10"></Split>
</template>
</CustomTable>
</ModuleContent2>
</FlexCol>
</ModuleContent2>
</FlexCol>
</a-col>
<a-col :span="5" :offset="14" style="height: 100%;">
<FlexCol>
<ModuleContent2 bg>
<FlexCol>
<web3-title>洗车机视频</web3-title>
<Split height="10"></Split>
<ModuleContent2 padding="0" :border="false" height="300px" >
</ModuleContent2>
<web3-title>洗车机运行信息</web3-title>
<Split height="10"></Split>
<ModuleContent2 padding="0" :border="false">
</ModuleContent2>
</FlexCol>
</ModuleContent2>
</FlexCol>
</a-col>
</a-row>
</ModuleContent>
</flex-col>
</new-bg>
</template>
<script>
import Map from "../../components/Map.vue";
import Curd from "../../components/smallCommon/Curd.vue";
import moment from "moment/moment";
import SystemTitle from "../../components/smallCommon/SystemTitle.vue";
import NewBg from "../../components/NewBg.vue";
import FlexCol from "../../components/FlexCol.vue";
import ModuleContent from "../../components/ModuleContent.vue";
import Web3Title from "../../components/smallCommon/Web3Title.vue";
import Split from "../../components/smallCommon/Split.vue";
import ModuleContent2 from "../../components/smallCommon/ModuleContent2.vue";
import CustomTable from "../../components/smallCommon/CustomTable.vue";
import Web2Title from "../../components/smallCommon/Web2Title.vue";
export default {
name: "xichejiguanli",
components: {
Web2Title,
CustomTable,
ModuleContent2,
Split,
Web3Title,
ModuleContent,
FlexCol, NewBg, SystemTitle,
Map,
Curd
},
data() {
return {
activeCarTabs: 1,
columns: [
{
dataIndex: 'outTime',
key: 'outTime',
title: '进场日期'
},
{
dataIndex: 'carNum',
key: 'carNum',
title: '车牌号'
},
{
dataIndex: 'carModel',
key: 'carModel',
title: '车型'
},
{
dataIndex: 'createDateTime',
key: 'createDateTime',
title: '清洗时间'
}
],
apiConf: {
listApi: {api: '/api/Ledger/list', method: 'get'},
},
}
},
computed: {
formItems() {
return [
{
type: 'dateRange',
key: 'time',
label: '日期',
isSearch: true,
placeholder: ['请选择开始日期', '请选择结束日期'],
rules: [
{required: true, message: '请选择时间范围'}
],
fields: ['startTime', 'endTime']
}
]
}
},
methods: {
carChange(value) {
this.activeCarTabs = value
},
editHandler(isEdit) {
this.isEdit = isEdit
},
exportList({time}) {
const [start, end] = time
const fmt = 'YYYY-MM-DD'
window.open(`http://101.43.201.20:5000/api/Ledger/export?start=${moment(start).format(fmt)}&end=${moment(end).format(fmt)}`, '_blank')
},
}
}
</script>
<style scoped lang="less">
.map-content {
height: 400px;
width: 100%;
position: relative;
}
.table-content {
flex: 1;
padding-top: 10px;
}
.xichejiguanli {
height: 100vh;
display: flex;
flex-flow: column;
._body {
flex: 1;
display: flex;
flex-flow: row;
padding: 20px;
.left-list {
width: 240px;
height: 100%;
border: 1px solid #e8e8e8;
border-radius: 10px;
.car-washing-machine-tabs {
height: 40px;
display: flex;
flex-flow: row;
align-items: center;
padding: 10px;
cursor: pointer;
border: 1px solid #e8e8e8;
margin-top: 10px;
&:first-child {
margin-top: 0;
}
border-radius: 10px;
.rank-num {
}
.car-washing-machine-name {
padding-left: 10px;
flex: 1;
}
}
.active-car-washing-machine-tabs {
background: #0088ff;
color: #FFFFFF;
}
}
.right-content {
width: 300px;
border: 1px solid #e8e8e8;
border-radius: 10px;
padding: 10px;
._title {
height: 30px;
line-height: 30px;
font-size: 16px;
font-weight: 700;
}
.car-wash-video {
margin: 20px 0;
height: 400px;
border: 1px solid #e8e8e8;
}
.car-run-info {
margin-top: 20px;
border: 1px solid #e8e8e8;
height: 260px;
padding: 10px;
display: flex;
flex-flow: column;
.details-info {
width: 100%;
flex: 1;
display: flex;
flex-flow: column;
justify-content: space-around;
align-items: flex-start;
.details-info-item {
display: flex;
flex-flow: row;
}
}
}
}
}
}
</style>

169
pages/youzuzhi/paifang.vue Normal file
View File

@ -0,0 +1,169 @@
<template>
<new-bg>
<flex-col>
<system-title @click="changeTab" show-back/>
<Map></Map>
<ModuleContent padding="0px 50px 20px" class="event-none" none-event>
<web2-title>有组织排放</web2-title>
<a-row style="margin-top: 16px;" :gutter="16" class="event-none">
<a-col :span="17">
<div style="height: 112px;width: 100%;" class="event-auto">
<ModuleContent2 :border="false" padding="0">
<butgroup2 style="height: 100%;">
<ModuleContent2 bg bg-color border>
<miaoshu title="全厂有组织排放源" :value="count.comeCount" color="rgba(42, 207, 255, 1)"></miaoshu>
</ModuleContent2>
<ModuleContent2 bg bg-color border style="margin-left: 16px;">
<miaoshu title="全厂重要排放源" :value="count.outCount" color="rgba(255, 171, 87, 1)"></miaoshu>
</ModuleContent2>
<ModuleContent2 bg bg-color border style="margin-left: 16px;">
<miaoshu title="当前区域排放源" :value="count.inCount" color="rgba(122, 175, 255, 1)"></miaoshu>
</ModuleContent2>
<ModuleContent2 bg bg-color border style="margin-left: 16px;">
<miaoshu title="当前区域其中重要排放源" :value="count.addCount" color="rgba(76, 243, 129, 1)"></miaoshu>
</ModuleContent2>
</butgroup2>
</ModuleContent2>
<div class="gongxu-wrapper event-auto">
<web3-title>工序步骤</web3-title>
<div class="gongxu-box">
<div class="gongxu-item" v-for="item in gongxu" :key="item.id">
{{ item.name }}
</div>
</div>
</div>
</div>
</a-col>
<a-col :span="7">
<faguang class="custom-tab">
<a-tabs default-active-key="1" class="custom-tab">
<a-tab-pane key="1" tab="VOC">
<web3-title>排放源清单</web3-title>
<a-table :columns="columns" :data-source="data"/>
</a-tab-pane>
<a-tab-pane key="2" tab="CEMS" force-render>
<web3-title>排放源清单</web3-title>
<a-table :columns="columns" :data-source="data"/>
</a-tab-pane>
</a-tabs>
</faguang>
</a-col>
</a-row>
<butgroup class="bottom-btn">
<cus-button>
<nuxt-link to="/youzuzhi/paifangtongji">环保排放统计</nuxt-link>
</cus-button>
</butgroup>
</ModuleContent>
</flex-col>
</new-bg>
</template>
<script>
import Map from "../../components/Map.vue";
import NewBg from "../../components/NewBg.vue";
import SystemTitle from "../../components/smallCommon/SystemTitle.vue";
import FlexCol from "../../components/FlexCol.vue";
import ModuleContent from "../../components/ModuleContent.vue";
import Butgroup2 from "../../components/smallCommon/butgroup2.vue";
import Miaoshu from "../../components/smallCommon/miaoshu.vue";
import ModuleContent2 from "../../components/smallCommon/ModuleContent2.vue";
import Web3Title from "../../components/smallCommon/Web3Title.vue";
import CusButton from "../../components/smallCommon/CusButton.vue";
import Butgroup from "../../components/smallCommon/butgroup.vue";
import Web2Title from "../../components/smallCommon/Web2Title.vue";
import Faguang from "../../components/smallCommon/Faguang.vue";
export default {
name: "paifang",
components: {
Faguang,
Web2Title,
Butgroup, CusButton,
Web3Title,
ModuleContent2, Miaoshu, Butgroup2,
ModuleContent,
FlexCol,
SystemTitle,
NewBg,
Map
},
data() {
return {
btns: [
{ title: 'VOC', key: '1' },
{ title: 'CEMS', key: '2' },
],
count: {},
data: [],
gongxu: [],
columns: [
{title: '名词', key: 'name'},
{title: 'NO', key: 'NO'},
{title: 'SO2', key: 'SO2'},
{title: 'TSP', key: 'TSP'},
]
}
},
mounted() {
this.getData(1)
},
methods: {
changeTab ({ key }) {
this.getData(key)
},
getData (deviceType) {
this.$get('/api/Organized/listanddevice', {
organizedType: 1,
deviceType: deviceType
}).then(({data}) => {
this.gongxu = data || []
})
}
}
}
</script>
<style scoped lang="less">
.mt16 {
margin-top: 16px;
}
.gongxu-wrapper {
width: 132px;
max-height: 500px;
margin-top: 16px;
}
.gongxu-box {
height: calc(100% - 48px);
overflow-y: auto;
.gongxu-item {
cursor: pointer;
color: #fff;
border-bottom: 1px solid rgba(238, 238, 238, 0.54);
width: 132px;
height: 48px;
opacity: 1;
background: rgba(0, 128, 247, 0.5);
box-sizing: border-box;
margin-top: 16px;
line-height: 48px;
/** 文本1 */
font-size: 18px;
font-weight: 400;
letter-spacing: 0px;
color: rgba(255, 255, 255, 1);
text-align: center;
vertical-align: top;
&.selected, &:hover {
background: rgba(7, 65, 119, 0.98);
font-weight: 500;
color: rgba(45, 205, 255, 1);
}
}
}
</style>

View File

@ -0,0 +1,52 @@
<template>
<new-bg>
<flex-col>
<system-title show-back />
<ModuleContent padding="0px 20px 20px">
<web2-title>有组织排放统计</web2-title>
<split num="16"></split>
<a-tabs default-active-key="1" class="custom-tab">
<a-tab-pane key="1" tab="总体排放">
<a-table :columns="columns" :data-source="data"/>
</a-tab-pane>
<a-tab-pane key="2" tab="VOC">
<a-table :columns="columns" :data-source="data"/>
</a-tab-pane>
<a-tab-pane key="3" tab="CEMS" force-render>
<a-table :columns="columns" :data-source="data"/>
</a-tab-pane>
</a-tabs>
</ModuleContent>
</flex-col>
</new-bg>
</template>
<script>
import FlexCol from "../../components/FlexCol.vue";
import SystemTitle from "../../components/smallCommon/SystemTitle.vue";
import NewBg from "../../components/NewBg.vue";
import ModuleContent from "../../components/ModuleContent.vue";
import Web2Title from "../../components/smallCommon/Web2Title.vue";
import Web3Title from "../../components/smallCommon/Web3Title.vue";
import Split from "../../components/Split.vue";
export default {
name: "paifangtongji",
components: {Split, Web3Title, Web2Title, ModuleContent, NewBg, SystemTitle, FlexCol},
data() {
return {
data: [],
columns: [
{title: '名词', key: 'name'},
{title: 'NO', key: 'NO'},
{title: 'SO2', key: 'SO2'},
{title: 'TSP', key: 'TSP'},
]
}
}
}
</script>
<style scoped lang="less">
</style>

View File

@ -1,10 +1,11 @@
import axios from 'axios' //引用axios
import { message } from 'ant-design-vue';
import Vue from 'vue'
import checkTypes from "../utils/checkTypes";
axios.defaults.withcredentials =true
// create an axios instance
const service = axios.create({
baseURL: process.env.NODE_ENV === 'development' ? '' : 'http://101.43.201.20', // 所有异步请求都加上/api,nginx转发到后端Springboot
baseURL: process.env.NODE_ENV === 'development' ? '' : 'http://101.43.201.20:5000', // 所有异步请求都加上/api,nginx转发到后端Springboot
timeout: 5000 // request timeout
})
@ -23,7 +24,9 @@ service.interceptors.request.use(
service.interceptors.response.use(
response => {
const res = response.data //res is my own data
if (!checkTypes.isObject(res)) {
return { data: res }
}
if (`${res.code}` === '0') {
return res
} else {

View File

@ -1,5 +1,3 @@
import Vue from 'vue'
Vue.prototype.$evBus = new Vue()

View File

@ -1,6 +1,6 @@
export const state = {
title: '',
info: {}
info: null
}
export const mutations = {
@ -15,8 +15,10 @@ export const mutations = {
export const actions = {
setTitle ({ commit }, title) {
commit('setTitle', title)
document.title = title
},
setInfo ({ commit }, info) {
setInfo ({ commit, dispatch }, info) {
commit('setInfo', info)
dispatch('setTitle', info.home?.title || '')
}
}

20
store/user.js Normal file
View File

@ -0,0 +1,20 @@
export const state = {
isLogin: false,
userInfo: {}
}
export const mutations = {
setUserInfo (state, userInfo) {
state.userInfo = userInfo
}
}
export const actions = {
setUserInfo (state, userInfo) {
state.isLogin = true
state.userInfo = userInfo
localStorage.setItem('userInfo', JSON.stringify(userInfo))
}
}

View File

@ -1,9 +1,4 @@
/**
* @Description: 工具类
* @ComponentName: tools
* @Author: wangzhigang11
* @Date: 2022-08-08 14:30
*/
// 开始动画
export const raf =
window.requestAnimationFrame ||

9
webpack.config.js Normal file
View File

@ -0,0 +1,9 @@
const path = require('path');
module.exports = {
resolve: {
alias: {
'@': path.resolve(__dirname, './'),
}
}
};