This commit is contained in:
GGJ
2023-12-29 16:25:34 +08:00
18 changed files with 579 additions and 170 deletions

View File

@@ -10,6 +10,7 @@
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"@fortawesome/fontawesome-free": "^6.5.1",
"@vueuse/core": "^10.7.0",
"axios": "^1.6.2",
"crypto-js": "^4.2.0",

9
pnpm-lock.yaml generated
View File

@@ -4,6 +4,9 @@ dependencies:
'@element-plus/icons-vue':
specifier: ^2.3.1
version: 2.3.1(vue@3.3.13)
'@fortawesome/fontawesome-free':
specifier: ^6.5.1
version: 6.5.1
'@vueuse/core':
specifier: ^10.7.0
version: 10.7.0(vue@3.3.13)
@@ -586,6 +589,12 @@ packages:
resolution: {integrity: sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==, tarball: https://registry.npmmirror.com/@floating-ui/utils/-/utils-0.1.6.tgz}
dev: false
/@fortawesome/fontawesome-free@6.5.1:
resolution: {integrity: sha512-CNy5vSwN3fsUStPRLX7fUYojyuzoEMSXPl7zSLJ8TgtRfjv24LOnOWKT2zYwaHZCJGkdyRnTmstR0P+Ah503Gw==}
engines: {node: '>=6'}
requiresBuild: true
dev: false
/@jridgewell/gen-mapping@0.3.3:
resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==}
engines: {node: '>=6.0.0'}

View File

@@ -1,22 +1,19 @@
<template>
<el-config-provider :locale="zhCn">
<el-config-provider :locale='zhCn'>
<router-view></router-view>
</el-config-provider>
</template>
<script lang="ts" setup>
<script lang='ts' setup>
import { computed, ref } from 'vue'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import { useConfig } from '@/stores/config'
import { useElementPlusTheme } from "use-element-plus-theme"
import { useElementPlusTheme } from 'use-element-plus-theme'
const configStore = useConfig()
useElementPlusTheme(configStore.getColorVal('elementUiPrimary'))
// document.documentElement.style.setProperty('--el-color-primary', configStore.getColorVal('elementUiPrimary'));
</script>
<style lang="scss">
// $primaryColor: v-bind('configStore.getColorVal("elementUiPrimary")');
// :root {
// --el-color-primary: $primaryColor !important;
// }
<style lang='scss'>
</style>

View File

@@ -1,55 +1,53 @@
<template>
<el-popover
:placement="placement"
trigger="focus"
:hide-after="0"
:width="state.selectorWidth"
:visible="state.popoverVisible"
:placement='placement'
trigger='focus'
:hide-after='0'
:width='state.selectorWidth'
:visible='state.popoverVisible'
>
<div
@mouseover.stop="state.iconSelectorMouseover = true"
@mouseout.stop="state.iconSelectorMouseover = false"
class="icon-selector"
@mouseover.stop='state.iconSelectorMouseover = true'
@mouseout.stop='state.iconSelectorMouseover = false'
class='icon-selector'
>
<transition name="el-zoom-in-center">
<div class="icon-selector-box">
<div class="selector-header">
<div class="selector-title">{{ title ? title : '请选择图标' }}</div>
<!-- <div class="selector-tab">
<transition name='el-zoom-in-center'>
<div class='icon-selector-box'>
<div class='selector-header'>
<div class='selector-title'>{{ title ? title : '请选择图标' }}</div>
<div class='selector-tab'>
<span
:title="'Element Puls ' + 'utils.Icon'"
@click="onChangeTab('ele')"
:class="state.iconType == 'ele' ? 'active' : ''"
>ele</span
>
>ele</span>
<span
:title="'Font Awesome ' + 'utils.Icon'"
@click="onChangeTab('awe')"
:class="state.iconType == 'awe' ? 'active' : ''"
>awe</span
>
<span :title="'utils.Ali iconcont Icon'" @click="onChangeTab('ali')" :class="state.iconType == 'ali' ? 'active' : ''"
>ali</span
>
<span
:title="'utils.Local icon title'"
@click="onChangeTab('local')"
:class="state.iconType == 'local' ? 'active' : ''"
>local</span
>
</div> -->
>awe</span>
<!-- <span :title="'utils.Ali iconcont Icon'" @click="onChangeTab('ali')"-->
<!-- :class="state.iconType == 'ali' ? 'active' : ''"-->
<!-- >ali</span>-->
<!-- <span-->
<!-- :title="'utils.Local icon title'"-->
<!-- @click="onChangeTab('local')"-->
<!-- :class="state.iconType == 'local' ? 'active' : ''"-->
<!-- >local</span-->
<!-- >-->
</div>
<div class="selector-body">
<el-scrollbar ref="selectorScrollbarRef">
<div v-if="renderFontIconNames.length > 0">
</div>
<div class='selector-body'>
<el-scrollbar ref='selectorScrollbarRef'>
<div v-if='renderFontIconNames.length > 0'>
<div
class="icon-selector-item"
:title="item"
@click="onIcon(item)"
v-for="(item, key) in renderFontIconNames"
:key="key"
class='icon-selector-item'
:title='item'
@click='onIcon(item)'
v-for='(item, key) in renderFontIconNames'
:key='key'
>
<Icon :name="item" />
<Icon :name='item' />
</div>
</div>
</el-scrollbar>
@@ -59,37 +57,37 @@
</div>
<template #reference>
<el-input
v-model="state.inputValue"
:size="size"
:disabled="disabled"
placeholder="搜索图标"
ref="selectorInput"
@focus="onInputFocus"
@blur="onInputBlur"
v-model='state.inputValue'
:size='size'
:disabled='disabled'
placeholder='搜索图标'
ref='selectorInput'
@focus='onInputFocus'
@blur='onInputBlur'
:class="'size-' + size"
>
<template #prepend>
<div class="icon-prepend">
<div class='icon-prepend'>
<Icon
:key="'icon' + state.iconKey"
:name="state.prependIcon ? state.prependIcon : state.defaultModelValue"
:name='state.prependIcon ? state.prependIcon : state.defaultModelValue'
/>
<div v-if="showIconName" class="name">
<div v-if='showIconName' class='name'>
{{ state.prependIcon ? state.prependIcon : state.defaultModelValue }}
</div>
</div>
</template>
<template #append>
<Icon @click="onInputRefresh" name="el-icon-RefreshRight" />
<Icon @click='onInputRefresh' name='el-icon-RefreshRight' />
</template>
</el-input>
</template>
</el-popover>
</template>
<script setup lang="ts">
<script setup lang='ts'>
import { reactive, ref, onMounted, nextTick, watch, computed } from 'vue'
import { getElementPlusIconfontNames } from '@/utils/iconfont'
import { getElementPlusIconfontNames,getAwesomeIconfontNames } from '@/utils/iconfont'
import { useEventListener } from '@vueuse/core'
import type { Placement } from 'element-plus'
@@ -104,6 +102,7 @@ interface Props {
modelValue?: string
showIconName?: boolean
}
const props = withDefaults(defineProps<Props>(), {
size: 'default',
disabled: false,
@@ -111,7 +110,7 @@ const props = withDefaults(defineProps<Props>(), {
type: 'ele',
placement: 'bottom',
modelValue: '',
showIconName: false,
showIconName: false
})
const emits = defineEmits<{
@@ -142,7 +141,7 @@ const state: {
inputValue: '',
prependIcon: props.modelValue,
defaultModelValue: props.modelValue || 'fa fa-circle-o',
iconKey: 0, // 给icon标签准备个key以随时使用 h 函数重新生成元素
iconKey: 0 // 给icon标签准备个key以随时使用 h 函数重新生成元素
})
const onInputFocus = () => {
@@ -158,27 +157,27 @@ const onInputRefresh = () => {
state.inputValue = ''
emits('update:modelValue', state.defaultModelValue)
emits('change', state.defaultModelValue)
// }
// const onChangeTab = (name: IconType) => {
// state.iconType = name
// state.fontIconNames = []
// if (name == 'ele') {
// getElementPlusIconfontNames().then((res) => {
// state.fontIconNames = res
// })
// } else if (name == 'awe') {
// getAwesomeIconfontNames().then((res) => {
// state.fontIconNames = res.map((name) => `fa ${name}`)
// })
// } else if (name == 'ali') {
// getIconfontNames().then((res) => {
// state.fontIconNames = res.map((name) => `iconfont ${name}`)
// })
// } else if (name == 'local') {
// getLocalIconfontNames().then((res) => {
// state.fontIconNames = res
// })
// }
}
const onChangeTab = (name: IconType) => {
state.iconType = name
state.fontIconNames = []
if (name == 'ele') {
getElementPlusIconfontNames().then((res) => {
state.fontIconNames = res
})
} else if (name == 'awe') {
getAwesomeIconfontNames().then((res) => {
state.fontIconNames = res.map((name) => `fa ${name}`)
})
} else if (name == 'ali') {
getIconfontNames().then((res) => {
state.fontIconNames = res.map((name) => `iconfont ${name}`)
})
} else if (name == 'local') {
getLocalIconfontNames().then((res) => {
state.fontIconNames = res
})
}
}
const onIcon = (icon: string) => {
state.iconSelectorMouseover = state.popoverVisible = false
@@ -232,35 +231,43 @@ onMounted(() => {
})
</script>
<style scoped lang="scss">
<style scoped lang='scss'>
.size-small {
height: 24px;
}
.size-large {
height: 40px;
}
.size-default {
height: 32px;
}
.icon-prepend {
display: flex;
align-items: center;
justify-content: center;
.name {
padding-left: 5px;
}
}
.selector-header {
display: flex;
align-items: center;
margin-bottom: 12px;
}
.selector-tab {
margin-left: auto;
span {
padding: 0 5px;
cursor: pointer;
user-select: none;
&.active,
&:hover {
color: var(--el-color-primary);
@@ -268,9 +275,11 @@ onMounted(() => {
}
}
}
.selector-body {
height: 250px;
}
.icon-selector-item {
display: inline-block;
padding: 10px 10px 6px 10px;
@@ -279,17 +288,21 @@ onMounted(() => {
border-radius: var(--el-border-radius-base);
cursor: pointer;
font-size: 18px;
.icon {
height: 18px;
width: 18px;
}
&:hover {
border: 1px solid var(--el-color-primary);
}
}
:deep(.el-input-group__prepend) {
padding: 0 10px;
}
:deep(.el-input-group__append) {
padding: 0 10px;
}

View File

@@ -14,7 +14,7 @@ const cascaderProps = {
label: 'name',
value: 'id',
checkStrictly: true,
showAllLevels: false
emitPath: false
}
const dictData = useDictData()
const options = dictData.state.area

View File

@@ -13,6 +13,7 @@ export default defineComponent({
},
setup(props, { slots }) {
const attr = reactive(props.attr)
attr['align'] = attr['align'] ? attr['align'] : 'center'
attr['column-key'] = attr['column-key'] ? attr['column-key'] : attr.prop || uuid()
return () => {
return createVNode(Column, attr, slots.default)

View File

@@ -31,7 +31,7 @@
<!-- datetime -->
<div v-if="field.render == 'datetime'">
{{ !fieldValue ? '-' : timeFormat(fieldValue, field.timeFormat ?? undefined) }}
{{ !fieldValue ? '/' : timeFormat(fieldValue, field.timeFormat ?? undefined) }}
</div>
<!-- color -->

View File

@@ -15,7 +15,7 @@
</div>
</transition>
<div class='table-header ba-scroll-style'>
<div class='table-header ba-scroll-style' v-if='showOperation'>
<slot name='operation'></slot>
<!-- 右侧搜索框和工具按钮 -->
<div class='table-search' v-if='$slots.select'>
@@ -39,11 +39,14 @@ const date = ref([window.XEUtils.toDateString(new Date(), 'yyyy-MM-dd'), window.
interface Props {
// 默认展开
showSelect?: boolean
showOperation?: boolean // 是否显示operation
datePicker?: boolean
}
const props = withDefaults(defineProps<Props>(), {
showSelect: true,
showOperation: true,
datePicker: false
})
if (props.datePicker) {

View File

@@ -1,61 +1,88 @@
<template>
<vxe-table
ref="tableRef"
class="ba-data-table w100"
header-cell-class-name="table-header-cell"
:data="tableStore.table.data"
:border="true"
v-loading="tableStore.table.loading"
ref='tableRef'
class='ba-data-table w100'
header-cell-class-name='table-header-cell'
:data='tableStore.table.data'
:border='true'
v-loading='tableStore.table.loading'
stripe
size="small"
@checkbox-change="onSelectionChange"
v-bind="$attrs"
:column-config="{resizable: true}"
:tree-config="{}"
size='small'
@checkbox-change='onSelectionChange'
v-bind='$attrs'
:column-config='{resizable: true}'
:tree-config='{}'
:row-config='{isCurrent: true, isHover: true}'
>
<!-- Column 组件内部是 el-table-column -->
<template v-if='isGroup'>
<vxe-table-colgroup
v-if='isGroup'
v-for='(item, index) in tableStore.table.column'
:field='item.field'
:title='item.title'
:key='index'
:min-width='item.width'
show-overflow
align='center'
>
<Column
:attr="item"
:attr='child'
:key="key + '-column'"
v-for="(item, key) in tableStore.table.column"
:tree-node='item.treeNode'
v-for='(child, key) in item.children'
:tree-node='child.treeNode'
>
<!-- tableStore 预设的列 render 方案 -->
<template v-if="item.render" #default="scope">
<template v-if='child.render' #default='scope'>
<FieldRender
:field="item"
:row="scope.row"
:column="scope.column"
:index="scope.rowIndex"
:key="
key +
'-' +
scope.rowIndex +
'-' +
item.render +
'-' +
(item.field ? '-' + item.field + '-' + scope.row[item.field] : '')
"
:field='child'
:row='scope.row'
:column='scope.column'
:index='scope.rowIndex'
:key='child.field+scope.rowIndex'
/>
</template>
</Column>
</vxe-table-colgroup>
</template>
<template v-else>
<Column
:attr='item'
:key="key + '-column'"
v-for='(item, key) in tableStore.table.column'
:tree-node='item.treeNode'
>
<!-- tableStore 预设的列 render 方案 -->
<template v-if='item.render' #default='scope'>
<FieldRender
:field='item'
:row='scope.row'
:column='scope.column'
:index='scope.rowIndex'
:key='item.field+scope.rowIndex'
/>
</template>
</Column>
</template>
</vxe-table>
<div v-if="props.pagination" class="table-pagination">
<div v-if='props.pagination' class='table-pagination'>
<el-pagination
:currentPage="tableStore.table.params!.pageNum"
:page-size="tableStore.table.params!.pageSize"
:page-sizes="pageSizes"
:currentPage='tableStore.table.params!.pageNum'
:page-size='tableStore.table.params!.pageSize'
:page-sizes='pageSizes'
background
:layout="config.layout.shrink ? 'prev, next, jumper' : 'sizes,total, ->, prev, pager, next, jumper'"
:total="tableStore.table.total"
@size-change="onTableSizeChange"
@current-change="onTableCurrentChange"
:total='tableStore.table.total'
@size-change='onTableSizeChange'
@current-change='onTableCurrentChange'
></el-pagination>
</div>
<slot name="footer"></slot>
<slot name='footer'></slot>
</template>
<script setup lang="ts">
<script setup lang='ts'>
import { ref, nextTick, inject, computed } from 'vue'
import type { ElTable, TableInstance } from 'element-plus'
import FieldRender from '@/components/table/fieldRender/index.vue'
@@ -69,9 +96,12 @@ const tableStore = inject('tableStore') as TableStoreClass
interface Props extends /* @vue-ignore */ Partial<InstanceType<typeof ElTable>> {
pagination?: boolean
isGroup?: boolean
}
const props = withDefaults(defineProps<Props>(), {
pagination: true
pagination: true,
isGroup: false
})
const onTableSizeChange = (val: number) => {
@@ -109,16 +139,18 @@ defineExpose({
})
</script>
<style scoped lang="scss">
<style scoped lang='scss'>
.ba-data-table :deep(.el-button + .el-button) {
margin-left: 6px;
}
.ba-data-table :deep(.table-header-cell) .cell {
color: var(--el-text-color-primary);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.table-pagination {
box-sizing: border-box;
width: 100%;

View File

@@ -54,7 +54,7 @@
<Icon
:color="configStore.getColorVal('headerBarTabColor')"
class="nav-menu-icon"
name="el-icon-Setting"
name="fa fa-cogs"
size="18"
/>
</div>

View File

@@ -69,7 +69,7 @@ const init = async () => {
title: '控制台',
name: 'dashboard',
path: 'dashboard',
icon: 'el-icon-Platform',
icon: 'fa fa-dashboard',
menu_type: 'tab',
url: '',
component: '/src/views/dashboard/index.vue',
@@ -111,32 +111,59 @@ const init = async () => {
{
id: 3,
pid: 0,
type: 'menu',
type: 'menu_dir',
title: '电压暂降',
name: 'voltage/sags',
path: 'voltage/sags',
icon: 'el-icon-BellFilled',
menu_type: 'tab',
url: '',
component: '/src/views/dashboard/test.vue',
keepalive: 'voltage/sags',
extend: 'none',
children: [
{
id: 1,
pid: 3,
type: 'menu_dir',
title: '运行管理',
name: 'voltage/sags/operationsManagement',
path: 'voltage/sags/operationsManagement',
icon: 'fa-solid fa-bars-progress',
menu_type: 'tab',
url: '',
extend: 'none',
children: [
{
id: 1,
pid: 3,
type: 'menu',
title: '运行管理',
name: 'voltage/sags/operationsManagement',
path: 'voltage/sags/operationsManagement',
icon: 'el-icon-Management',
title: '终端运行管理',
name: 'voltage/sags/operationsManagement/index',
path: 'voltage/sags/operationsManagement/index',
icon: 'fa-solid fa-recycle',
menu_type: 'tab',
url: '',
component: '/src/views/voltage/sags/operationsManagement/index.vue',
keepalive: 'voltage/sags/operationsManagement',
keepalive: 'voltage/sags/operationsManagement/index',
extend: 'none',
children: []
},
{
id: 1,
pid: 3,
type: 'menu',
title: '监测点台账信息',
name: 'voltage/sags/operationsManagement/point',
path: 'voltage/sags/operationsManagement/point',
icon: 'fa-brands fa-square-pinterest',
menu_type: 'tab',
url: '',
component: '/src/views/voltage/sags/operationsManagement/point.vue',
keepalive: 'voltage/sags/operationsManagement/point',
extend: 'none',
children: []
}
]
},
{
id: 2,
pid: 3,
@@ -161,7 +188,7 @@ const init = async () => {
title: '权限管理',
name: 'auth',
path: 'auth',
icon: 'el-icon-Tools',
icon: 'fa fa-group',
menu_type: null,
url: '',
component: '',

View File

@@ -10,7 +10,7 @@ import 'vxe-table/lib/style.css'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import 'element-plus/theme-chalk/display.css'
// modules import mark, Please do not remove.
import '@fortawesome/fontawesome-free/css/all.css'
import '@/styles/index.scss'
import '@/assets/font/iconfont.css'

View File

@@ -29,4 +29,8 @@ $border-color: map.merge(
@include set-css-var-value('color-primary-light', $primary-light);
@include set-component-css-var('bg-color', $bg-color);
@include set-component-css-var('border-color', $border-color);
--vxe-table-row-current-background-color: var(--el-color-primary-light-7);
--vxe-table-row-hover-background-color: var(--el-color-primary-light-9);
--vxe-table-row-hover-current-background-color: var(--el-color-primary-light-7);
--vxe-table-row-hover-striped-background-color: var(--el-color-primary-light-9);
}

View File

@@ -1,5 +1,7 @@
import { nextTick } from 'vue'
import * as elIcons from '@element-plus/icons-vue'
import { getUrl } from '@/utils/request'
/*
* 获取element plus 自带的图标
*/
@@ -19,3 +21,65 @@ export function getElementPlusIconfontNames() {
})
})
}
/**
* 获取Vite开发服务/编译后的样式表内容
* @param devID style 标签的 viteDevId只开发服务有
*/
function getStylesFromVite(devId: string) {
const sheets = []
const styles: StyleSheetList = document.styleSheets
if (import.meta.env.MODE == 'production') {
const url = getUrl()
for (const key in styles) {
if (styles[key].href && styles[key].href?.indexOf(url) === 0) {
sheets.push(styles[key])
}
}
return sheets
}
for (const key in styles) {
const ownerNode = styles[key].ownerNode as HTMLMapElement
if (ownerNode && ownerNode.dataset?.viteDevId && ownerNode.dataset.viteDevId!.indexOf(devId) > -1) {
sheets.push(styles[key])
}
}
return sheets
}
/*
* 获取 Awesome-Iconfont 的 name 列表
*/
export function getAwesomeIconfontNames() {
return new Promise<string[]>((resolve, reject) => {
nextTick(() => {
const iconfonts = []
const sheets = getStylesFromVite('all.css')
console.log(sheets)
for (const key in sheets) {
const rules: any = sheets[key].cssRules
for (const k in rules) {
if (!rules[k].selectorText || rules[k].selectorText.indexOf('.fa-') !== 0) {
continue
}
if (/^\.fa-(.*)::before$/g.test(rules[k].selectorText)) {
if (rules[k].selectorText.indexOf(', ') > -1) {
const iconNames = rules[k].selectorText.split(', ')
iconfonts.push(`${iconNames[0].substring(1, iconNames[0].length).replace(/\:\:before/gi, '')}`)
} else {
iconfonts.push(`${rules[k].selectorText.substring(1, rules[k].selectorText.length).replace(/\:\:before/gi, '')}`)
}
}
}
}
if (iconfonts.length > 0) {
resolve(iconfonts)
} else {
reject('没有样式表')
}
})
})
}

View File

@@ -10,6 +10,8 @@ interface TableStoreParams {
params?: anyObj
method?: Method
isWebPaging?: boolean // 是否前端分页
resetCallback?: () => void
loadCallback?: () => void
}
export default class TableStore {
@@ -29,7 +31,9 @@ export default class TableStore {
pageSize: 20
},
loading: true,
column: []
column: [],
loadCallback: null,
resetCallback: null
})
constructor(public options: TableStoreParams) {
@@ -38,6 +42,8 @@ export default class TableStore {
this.isWebPaging = options.isWebPaging || false
this.method = options.method || 'GET'
this.table.column = options.column
this.table.resetCallback = options.resetCallback || null
this.table.loadCallback = options.loadCallback || null
Object.assign(this.table.params, options.params)
}
@@ -61,6 +67,7 @@ export default class TableStore {
this.table.webPagingData = window.XEUtils.chunk(this.table.data, this.table.params.pageSize)
this.table.data = this.table.webPagingData[this.table.params.pageNum - 1]
}
this.table.loadCallback && this.table.loadCallback()
this.table.loading = false
})
}
@@ -85,6 +92,7 @@ export default class TableStore {
delete this.initData.pageSize
Object.assign(this.table.params, this.initData)
this.index()
this.table.resetCallback && this.table.resetCallback()
}
],
[

View File

@@ -1,12 +1,12 @@
<template>
<div class='default-main'>
<TableHeader date-picker>
<TableHeader date-picker :showOperation='false'>
<template v-slot:select>
<el-form-item label='区域'>
<Area v-model='tableStore.table.params.deptIndex' />
</el-form-item>
<el-form-item label='终端状态'>
<el-select v-model='tableStore.table.params.runFlag'
<el-select multiple clearable collapse-tags v-model='tableStore.table.params.runFlag'
placeholder='请选择'>
<el-option label='投运' value='0' />
<el-option label='热备用' value='1' />
@@ -14,16 +14,15 @@
</el-select>
</el-form-item>
<el-form-item label='通讯状态'>
<el-select v-model='tableStore.table.params.comFlag'
<el-select multiple clearable collapse-tags v-model='tableStore.table.params.comFlag'
placeholder='请选择'>
<el-option label='正常' value='1' />
<el-option label='中断' value='0' />
</el-select>
</el-form-item>
<el-form-item label='厂家'>
<el-select v-model='tableStore.table.params.manufacturer'
placeholder='请选择'
>
<el-select multiple clearable collapse-tags v-model='manufacturerForm' placeholder='请选择'
@change='onManufacturerChange'>
<el-option
v-for='item in manufacturer'
:key='item.id'
@@ -33,7 +32,8 @@
</el-select>
</el-form-item>
<el-form-item label='筛选数据'>
<el-input v-model='tableStore.table.params.searchValue' placeholder='请输入' />
<el-input v-model='tableStore.table.params.searchValue'
placeholder='根据变电站,终端编号,型号或网络参数查询' style='width:300px' />
</el-form-item>
</template>
</TableHeader>
@@ -41,7 +41,7 @@
</div>
</template>
<script setup lang='tsx'>
import { ref, onMounted, provide } from 'vue'
import { ref, onMounted, provide, reactive } from 'vue'
import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue'
@@ -53,6 +53,7 @@ defineOptions({
})
const dictData = useDictData()
const manufacturer = dictData.getBasicData('Dev_Manufacturers')
const manufacturerForm = ref<string[]>([])
const tableStore = new TableStore({
isWebPaging: true,
url: '/device-boot/runManage/getRuntimeData',
@@ -101,12 +102,17 @@ const tableStore = new TableStore({
}
}
}
]
],
resetCallback: () => {
manufacturerForm.value = []
}
})
tableStore.table.params.deptIndex = '5699e5916a18a6381e1ac92da5bd2628'
tableStore.table.params.deptIndex = dictData.state.area[0].id
tableStore.table.params.runFlag = []
tableStore.table.params.comFlag = []
tableStore.table.params.manufacturer = []
tableStore.table.params.statisticalType = {}
tableStore.table.params.serverName = 'event-boot'
tableStore.table.params.searchValue = ''
provide('tableStore', tableStore)
@@ -114,6 +120,15 @@ onMounted(() => {
tableStore.index()
})
const addMenu = () => {
const onManufacturerChange = () => {
tableStore.table.params.manufacturer = manufacturer.filter(item => {
return manufacturerForm.value.includes(item.id)
}).map(item => {
return {
...item,
label: item.name,
value: item.id
}
})
}
</script>

View File

@@ -0,0 +1,232 @@
<template>
<div class='default-main'>
<TableHeader date-picker :showOperation='false'>
<template v-slot:select>
<el-form-item label='区域'>
<Area v-model='tableStore.table.params.deptIndex' />
</el-form-item>
<el-form-item label='干扰源类型'>
<el-select multiple clearable collapse-tags v-model='interferenceSourceForm' placeholder='请选择'
@change='onLoadTypeChange'>
<el-option
v-for='item in interferenceSource'
:key='item.id'
:label='item.name'
:value='item.id'
/>
</el-select>
</el-form-item>
<el-form-item label='电压等级'>
<el-select multiple clearable collapse-tags v-model='scaleForm' placeholder='请选择'
@change='onScaleChange'
>
<el-option
v-for='item in level'
:key='item.id'
:label='item.name'
:value='item.id'
/>
</el-select>
</el-form-item>
<el-form-item label='通讯状态'>
<el-select multiple clearable collapse-tags v-model='tableStore.table.params.comFlag'
placeholder='请选择'>
<el-option label='正常' value='1' />
<el-option label='中断' value='0' />
</el-select>
</el-form-item>
<el-form-item label='筛选数据'>
<el-input v-model='tableStore.table.params.searchValue'
placeholder='根据变电站,终端编号,型号或网络参数查询' style='width:300px' />
</el-form-item>
</template>
</TableHeader>
<Table isGroup ref='tableRef' />
</div>
</template>
<script setup lang='tsx'>
import { ref, onMounted, provide, reactive } from 'vue'
import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue'
import { useDictData } from '@/stores/dictData'
import Area from '@/components/form/area/index.vue'
defineOptions({
name: 'comptroller/list'
})
const dictData = useDictData()
const interferenceSource = dictData.getBasicData('Interference_Source')
const level = dictData.getBasicData('Dev_Voltage_Stand')
const interferenceSourceForm = ref<string[]>([])
const scaleForm = ref<string[]>([])
const tableStore = new TableStore({
isWebPaging: true,
url: '/device-boot/runManage/getLineLedger',
method: 'POST',
column: [
{ field: 'areaName', title: '省公司', width: 120 },
{ field: 'gdName', title: '市公司', width: 120 },
{ field: 'scale', title: '监测点电压等级', width: 150 },
{ field: 'lineName', title: '监测点名称', width: 120 },
{ field: 'bdName', title: '所属变电站', width: 120 },
{ field: 'loadType', title: '干扰源类型', width: 120 },
{ field: 'objName', title: '监测对象名称', width: 180 },
{
field: 'shortCapacity', title: '最小短路容量(MVA)', width: 190
},
{
field: 'devCapacity', title: '供电设备容量(MVA )', width: 190
},
{
field: 'dealCapacity', title: '用户协议容量(MVA)', width: 190
},
{ field: 'comFlag', title: '通讯状态 ', width: 120 },
{ field: 'id', title: '监测点序号', width: 120 },
{ field: 'devName', title: '监测终端编号 ', width: 140 },
{ field: 'ptType', title: '监测终端接线方式', width: 160 },
{
field: 'voltageDev', title: '电压偏差上限(%)', width: 160
},
{
field: 'uvoltageDev', title: '电压偏差下限(%)', width: 160
},
{
field: 'limitValue',
title: '限值',
children: [{ field: 'freqDev', title: '频率(Hz)', width: 120 }, {
field: 'ubalance',
title: '三相电压不平衡度(%)',
width: 190
}, { field: 'ineg', title: '负序电流(A)', width: 120 }, {
field: 'flicker',
title: '长时间闪变',
width: 120
}, {
field: 'uaberrance', title: '电压总谐波畸变率(%)', width: 190
},
{
field: 'oddHarm',
title: '奇数次谐波电压(%)',
width: 180
},
{
field: 'evenHarm',
title: '偶数次谐波电压(%)',
width: 180
}
]
},
{
field: 'evaluate',
title: '电流限值',
children: [
{ field: 'iharm2', title: '2次谐波(A)', width: 120 },
{ field: 'iharm3', title: '3次谐波(A)', width: 120 },
{ field: 'iharm4', title: '4次谐波(A)', width: 120 },
{ field: 'iharm5', title: '5次谐波(A)', width: 120 },
{ field: 'iharm6', title: '6次谐波(A)', width: 120 },
{ field: 'iharm7', title: '7次谐波(A)', width: 120 },
{ field: 'iharm8', title: '8次谐波(A)', width: 120 },
{ field: 'iharm9', title: '9次谐波(A)', width: 120 },
{ field: 'iharm10', title: '10次谐波(A)', width: 140 },
{
field: 'iharm11', title: '11次谐波(A)', width: 140
},
{
field: 'iharm12', title: '12次谐波(A)', width: 140
},
{
field: 'iharm13', title: '13次谐波(A)', width: 140
},
{
field: 'iharm14', title: '14次谐波(A)', width: 140
},
{
field: 'iharm15', title: '15次谐波(A)', width: 140
},
{
field: 'iharm16', title: '16次谐波(A)', width: 140
},
{
field: 'iharm17', title: '17次谐波(A)', width: 140
},
{
field: 'iharm18', title: '18次谐波(A)', width: 140
},
{
field: 'iharm19', title: '19次谐波(A)', width: 140
},
{
field: 'iharm10', title: '20次谐波(A)', width: 140
},
{
field: 'iharm21', title: '21次谐波(A)', width: 140
},
{
field: 'iharm22', title: '22次谐波(A)', width: 140
},
{
field: 'iharm23', title: '23次谐波(A)', width: 140
},
{
field: 'iharm24', title: '24次谐波(A)', width: 140
},
{
field: 'iharm25', title: '25次谐波(A)', width: 140
},
{
field: 'inUharm', title: '0.5-1.5次间谐波(A)', width: 180
},
{
field: 'inUharm16', title: '2.5-15.5次间谐波(A)', width: 190
}
]
}
],
resetCallback: () => {
interferenceSourceForm.value = []
scaleForm.value = []
}
})
tableStore.table.params.deptIndex = dictData.state.area[0].id
tableStore.table.params.scale = []
tableStore.table.params.comFlag = []
tableStore.table.params.loadType = []
tableStore.table.params.statisticalType = {}
tableStore.table.params.serverName = 'event-boot'
tableStore.table.params.searchValue = ''
provide('tableStore', tableStore)
onMounted(() => {
tableStore.index()
})
const onLoadTypeChange = () => {
tableStore.table.params.loadType = interferenceSource.filter(item => {
return interferenceSourceForm.value.includes(item.id)
}).map(item => {
return {
...item,
label: item.name,
value: item.id
}
})
}
const onScaleChange = () => {
tableStore.table.params.scale = level.filter(item => {
return scaleForm.value.includes(item.id)
}).map(item => {
return {
...item,
label: item.name,
value: item.id
}
})
}
</script>

3
types/table.d.ts vendored
View File

@@ -23,6 +23,8 @@ declare global {
pageSize: number
[key: string]: any
}
loadCallback: (() => void )| null
resetCallback: (() => void)| null
}
/* 表格行 */
@@ -65,6 +67,7 @@ declare global {
column: VxeColumnProps,
index: number
) => string
children?: TableColumn[]
}
/* 表格右侧操作按钮 */