预警后台初始化-部分模块搭建及调试

This commit is contained in:
FrancisHu 2024-09-11 17:49:46 +08:00
parent 831572bf6f
commit 215f18f41d
20 changed files with 2219 additions and 5 deletions

47
src/api/base/proj.js Normal file
View File

@ -0,0 +1,47 @@
/**
* 工程管理页面 API
*/
import request from '@/utils/request'
/** 工程列表查询 */
export const queryProjListApi = (data) => {
return request.get('/base/tbProject/list', {
params: data
})
}
/** 工程名称查询 */
export const queryProjNameApi = (data) => {
return request.get('/base/tbProject/getList', {
params: data
})
}
/** 电压等级查询 */
export const queryVolLevelApi = (data) => {
return request.get('/base/tbProDepart/getDataList', {
params: data
})
}
/** 所属项目部查询 */
export const queryDeptApi = (data) => {
return request.get('/base/tbProDepart/list', {
params: data
})
}
/** 新增工程 */
export const addProjApi = (data) => {
return request.post('/base/tbProject', data)
}
/** 修改工程 */
export const editProjApi = (data) => {
return request.put('/base/tbProject', data)
}
/** 删除工程 */
export const deleteProjApi = (id) => {
return request.delete(`/base/tbProject/${id}`)
}

47
src/api/base/projDept.js Normal file
View File

@ -0,0 +1,47 @@
/**
* 项目部管理页面 API
*/
import request from '@/utils/request'
/** 项目部列表查询 */
export const queryProjDeptListApi = (data) => {
return request.get('/base/tbProDepart/list', {
params: data
})
}
/** 项目部名称查询 */
export const queryProjDeptNameApi = (data) => {
return request.get('/base/tbProDepart/getList', {
params: data
})
}
/** 项目部类型查询 */
export const queryProjDeptTypeApi = (data) => {
return request.get('/base/tbProDepart/getDataList', {
params: data
})
}
/** 各省份查询 */
export const queryProvincesApi = (data) => {
return request.get('/base/tbProDepart/getAreaList', {
params: data
})
}
/** 新增项目部 */
export const addProjDeptApi = (data) => {
return request.post('/base/tbProDepart', data)
}
/** 修改项目部 */
export const editProjDeptApi = (data) => {
return request.put('/base/tbProDepart', data)
}
/** 删除项目部 */
export const deleteProjDeptApi = (id) => {
return request.delete(`/base/tbProDepart/${id}`)
}

View File

@ -6,4 +6,4 @@ export const getRouters = () => {
url: '/system/menu/getRouters',
method: 'get'
})
}
}

View File

@ -0,0 +1,55 @@
<template>
<!-- 弹框组件 -->
<div>
<el-dialog
:title="dialogConfig.outerTitle"
:width="dialogConfig.outerWidth"
:visible.sync="dialogConfig.outerVisible"
v-if="dialogConfig.outerVisible"
:before-close="handleCloseOuter"
append-to-body
>
<!-- 外层弹框内容 -->
<slot name="outerContent"></slot>
<!-- 内层对话框 -->
<el-dialog
:title="dialogConfig.innerTitle"
:width="dialogConfig.innerWidth"
:visible.sync="dialogConfig.innerVisible"
v-if="dialogConfig.innerVisible"
:before-close="handleCloseInner"
append-to-body
>
<!-- 内层弹框内容 -->
<slot name="innerContent"></slot>
</el-dialog>
</el-dialog>
</div>
</template>
<script>
export default {
props: {
/* 配置项 */
dialogConfig: {
type: Object,
default: () => {
return {}
},
},
},
methods: {
/* 右上角关闭外层 */
handleCloseOuter() {
/* 通知父组件更改弹框显示值 */
this.$emit('closeDialogOuter', false)
},
/* 右上角关闭内层 */
handleCloseInner() {
/* 通知父组件更改弹框显示值 */
this.$emit('closeDialogInner', false)
},
},
}
</script>

View File

@ -0,0 +1,501 @@
<template>
<!-- 表格公共组件 -->
<div>
<!-- 表单搜索 -->
<el-form
:model="queryParams"
ref="queryFormRef"
size="small"
:inline="true"
label-width="100px"
v-show="showSearch"
:rules="formRules"
>
<el-form-item
v-for="(item, v) in formLabel"
:key="v"
:label="item.f_label"
:prop="item.f_model"
>
<el-input
v-if="item.f_type === 'ipt'"
v-model="queryParams[item.f_model]"
:placeholder="`请输入${item.f_label}`"
clearable
style="width: 240px"
/>
<el-select
v-if="item.f_type === 'sel'"
v-model="queryParams[item.f_model]"
clearable
filterable
style="width: 240px"
:placeholder="`请选择${item.f_label}`"
>
<el-option
v-for="(sel, v) in item.f_selList"
:key="v"
:label="sel.label"
:value="sel.value"
/>
</el-select>
<el-cascader
v-if="item.f_type === 'selCasAdd'"
v-model="queryParams[item.f_model]"
:options="item.f_selList"
:props="item.optionProps"
:show-all-levels="false"
clearable
@change="handleCasAdd($event, item.f_model, cascaderFunc, extraTableProp)"
style="width: 240px"
/>
<el-cascader
v-if="item.f_type === 'selCas'"
v-model="queryParams[item.f_model]"
:options="item.f_selList"
:props="item.optionProps"
:show-all-levels="false"
@change="handleCas($event, item.f_model)"
style="width: 240px"
/>
<el-date-picker
v-if="item.f_type === 'date'"
v-model="queryParams[item.f_model]"
style="width: 240px"
value-format="yyyy-MM-dd"
type="date"
/>
<el-date-picker
v-if="item.f_type === 'dateRange'"
v-model="queryParams[item.f_model]"
style="width: 240px"
type="daterange"
value-format="yyyy-MM-dd"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
/>
<el-input-number
v-if="item.f_type === 'num'"
v-model="queryParams[item.f_model]"
:min="0"
style="width: 240px"
></el-input-number>
</el-form-item>
<el-form-item v-if="showBtnCrews">
<el-button
type="primary"
icon="el-icon-search"
size="mini"
@click="handleQuery"
v-if="showSearchBtn"
>查询</el-button
>
<el-button
type="success"
icon="el-icon-edit"
size="mini"
@click="handleFill"
v-if="!showSearchBtn"
>填充</el-button
>
<el-button
type="warning"
icon="el-icon-refresh"
size="mini"
@click="resetQuery"
>重置</el-button
>
</el-form-item>
</el-form>
<!-- 按钮集群 -->
<el-row class="btn-container" v-if="showRightTools">
<div class="btn-handler">
<slot name="btn" :queryParams="queryParams"></slot>
</div>
<ToolbarModel
:showSearch.sync="showSearch"
:indexNumShow.sync="indexNumShow"
:selectionShow.sync="selectionShow"
:handleShow.sync="handleShow"
:columns="columCheckList"
@queryTable="getTableList"
/>
</el-row>
<!-- 表格 -->
<el-table
:data="tableList"
border
ref="tableRef"
select-on-indeterminate
style="width: 100%"
v-loading="loading"
@selection-change="handleSelectionChange">
>
<el-table-column
type="selection"
width="45"
align="center"
v-if="showSel"
:selectable="selectable"
/>
<el-table-column
width="55"
align="center"
label="序号"
type="index"
:index="
indexContinuation(queryParams.pageNum, queryParams.pageSize)
"
v-if="indexNumShow"
/>
<el-table-column
v-for="(item, v) in tableColumCheckProps"
:key="v"
:label="item.t_label"
:prop="item.t_props"
:width="item.t_width"
align="center"
show-overflow-tooltip
>
<template slot-scope="scope">
<!-- 判断当前列数据是否需要使用插槽的数据 -->
<template v-if="item.t_slot">
<slot :data="scope.row" :name="item.t_slot"></slot>
</template>
<template v-else>
{{ scope.row[item.t_props] || '-' }}
</template>
</template>
</el-table-column>
<el-table-column
align="center"
label="操作"
v-if="handleShow && showOperation"
:min-width="dynamicWidth"
>
<template slot-scope="{ row }">
<div class="optionDivRef">
<slot :data="row" name="handle">-</slot>
</div>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<pagination
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getTableList"
/>
</div>
</template>
<script>
import ToolbarModel from '../ToolbarModel'
export default {
components: { ToolbarModel },
props: {
/** 表单查询条件 */
formLabel: {
type: Array,
default: () => [],
},
/** 列表请求接口 */
requestApi: {
type: Function,
default: () => function () {},
},
/** 列表配置项 */
columnsList: {
type: Array,
default: () => [],
},
/** 是否显示选择框 */
showSel: {
type: Boolean,
default: true,
},
/** 传递参数 */
sendParams: {
type: Object,
default: () => null
},
/** 是否显示查询按钮 */
showSearchBtn: {
type: Boolean,
default: true,
},
showBtnCrews: {
type: Boolean,
default: true,
},
cascaderFunc: {
type: Function,
default: () => null
},
extraTableProp: {
type: Object,
default: () => null
},
showOperation: {
type: Boolean,
default: true
},
showRightTools: {
type: Boolean,
default: true
},
selectable: {
type: Function,
default: () => {
return true
}
}
},
computed: {
/* 根据操作栏控制表头是否显示 */
tableColumCheckProps() {
return this.columCheckList.filter(e => {
return e.checked != false
})
},
},
watch: {
handleShow: {
handler(newValue) {
if (!newValue) {
this.dynamicWidth = 0
}
},
},
},
data() {
return {
//
formRules: {
},
loading: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
},
//
tableList: [],
//
msgList: undefined,
//
total: 0,
//
showSearch: true,
//
selectionShow: true,
//
indexNumShow: true,
//
handleShow: true,
// label
columCheckList: [],
//
dynamicWidth: 0,
idCount: 1
}
},
created() {
console.log(this.sendParams, 'table')
this.columCheckList = this.columnsList.map(e => {
this.$set(e, 'checked', true)
return e
})
/* 生成查询参数 */
this.formLabel.map(e => {
this.$set(this.queryParams, e.f_model, '')
//
if(e.f_rule) {
this.$set(this.formRules, e.f_rule, [
{
required: true,
message: `请填写${e.f_label}`,
trigger: 'blur'
}
])
}
})
if(this.sendParams !== null) {
Object.assign(this.queryParams, this.sendParams)
/* for(let key in this.sendParams) {
console.log(key, this.sendParams[key])
this.$set(this.queryParams, key, this.sendParams[key])
} */
}
this.getTableList()
},
updated() {
//
this.dynamicWidth = this.getOperatorWidth()
},
methods: {
/** 获取列表数据 */
async getTableList() {
if(this.queryParams.time && this.queryParams.time.length !== 0) {
this.queryParams.startTime = this.queryParams.time[0]
this.queryParams.endTime = this.queryParams.time[1]
delete this.queryParams.time
}
console.log(this.queryParams)
if(Object.keys(this.formRules).length !== 0) {
this.$refs.queryFormRef.validate(async valid => {
if (valid) {
this.loading = true
const res = await this.requestApi(this.queryParams)
this.loading = false
console.log(res, '列表数据')
if (res.code === 200) {
if (res.data) {
this.tableList = res.data.rows
this.total = res.data.total
} else {
this.tableList = res.rows
this.total = res.total
}
}
}
})
} else {
this.loading = true
const res = await this.requestApi(this.queryParams)
this.loading = false
console.log(res, '列表数据')
if (res.code === 200) {
if (res.data) {
this.tableList = res.data.rows
this.total = res.data.total
} else {
this.tableList = res.rows
this.total = res.total
}
}
}
},
/** 查询按钮 */
handleQuery() {
this.getTableList()
},
/** 填充按钮 */
handleFill() {
/* this.tableList.forEach(obj => {
Object.assign(obj, this.formLabel)
}) */
},
/** 重置按钮 */
resetQuery() {
this.$refs.queryFormRef.resetFields()
this.queryParams.pageNum = 1
this.queryParams.pageSize = 10
this.getTableList()
},
/** 级联选择 */
handleCas(e, val) {
this.queryParams[val] = e[e.length - 1]
},
/** 级联选择只选最后一级 */
handleCasAdd(
e,
val,
func,
prop
) {
if(e.length !== 0) {
this.queryParams[val] = e[e.length - 1]
let setObj = {}
//
if(prop) {
Object.assign(setObj, prop)
}
// id
this.$set(setObj, 'id', this.idCount)
this.idCount++
//
func({
id: e[e.length - 1]
}).then(res => {
this.$set(setObj, 'name', res.data.parentName)
this.$set(setObj, 'unitName', res.data.unitName)
this.$set(setObj, 'typeName', res.data.name)
}).catch(err => {})
for(let key in this.queryParams) {
this.$set(setObj, key, this.queryParams[key])
}
this.tableList.unshift(setObj)
console.log(this.tableList)
}
},
/** 动态设置操作列的列宽 */
getOperatorWidth() {
const operatorColumn =
document.getElementsByClassName('optionDivRef')
//
let width = 100
//
let paddingSpacing = 0
//
let buttonCount = 0
if (operatorColumn.length > 0) {
Array.prototype.forEach.call(operatorColumn, function (item) {
//
width = width > item.offsetWidth ? width : item.offsetWidth
const buttons = item.getElementsByClassName('el-button')
buttonCount = buttons.length
buttonCount =
buttonCount > buttons.length
? buttonCount
: buttons.length
})
return width
}
},
queryTableList(params) {
Object.assign(this.queryParams, params)
this.getTableList()
},
handleSelectionChange(e) {
this.msgList = e
this.$emit('transIdList', this.msgList)
},
},
}
</script>
<style scoped lang="scss">
.btn-container {
margin-bottom: 6px;
display: flex;
align-items: center;
}
::v-deep .btn-handler {
flex: 1;
.el-button {
padding: 6px 18px;
}
}
::v-deep .optionDivRef {
white-space: nowrap;
display: inline-block;
.el-button {
padding: 6px 12px;
}
}
</style>

View File

@ -0,0 +1,227 @@
<template>
<div class="top-right-btn" :style="style">
<el-row>
<el-tooltip
class="item"
effect="dark"
:content="showSearch ? '隐藏搜索' : '显示搜索'"
placement="top"
v-if="search"
>
<el-button
size="mini"
circle
icon="el-icon-search"
@click="toggleSearch()"
/>
</el-tooltip>
<el-tooltip
class="item"
effect="dark"
content="刷新"
placement="top"
>
<el-button
size="mini"
circle
icon="el-icon-refresh"
@click="refresh()"
/>
</el-tooltip>
<el-tooltip
class="item"
effect="dark"
content="列表筛选"
placement="top"
>
<el-dropdown
trigger="click"
:hide-on-click="false"
style="padding-left: 12px"
>
<el-button size="mini" circle icon="el-icon-menu" />
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>
<el-checkbox
:checked="selectionShow"
@change="
() => {
this.$emit(
'update:selectionShow',
!this.selectionShow,
)
}
"
>复选框</el-checkbox
>
</el-dropdown-item>
<el-dropdown-item>
<el-checkbox
:checked="indexNumShow"
@change="
() => {
this.$emit(
'update:indexNumShow',
!this.indexNumShow,
)
}
"
>序号</el-checkbox
>
</el-dropdown-item>
<el-dropdown-item>
<el-checkbox
:checked="handleShow"
@change="
() => {
this.$emit(
'update:handleShow',
!this.handleShow,
)
}
"
>操作</el-checkbox
>
</el-dropdown-item>
<template v-for="(item, index) in columns">
<el-dropdown-item :key="index">
<el-checkbox
:checked="item.checked"
@change="
checkboxChange($event, item.t_label)
"
:label="item.t_label"
>{{ item.t_label }}</el-checkbox
>
</el-dropdown-item>
</template>
</el-dropdown-menu>
</el-dropdown>
</el-tooltip>
</el-row>
</div>
</template>
<script>
export default {
name: 'RightToolbar',
data() {
return {
//
value: [],
//
title: '显示/隐藏',
//
open: false,
}
},
props: {
/* 是否显示检索条件 */
showSearch: {
type: Boolean,
default: true,
},
/* 列表复选框显示 */
selectionShow: {
type: Boolean,
default: true,
},
/* 列表序号显示 */
indexNumShow: {
type: Boolean,
default: true,
},
/* 列表操作列显示 */
handleShow: {
type: Boolean,
default: true,
},
/* 显隐列信息 */
columns: {
type: Array,
},
/* 是否显示检索图标 */
search: {
type: Boolean,
default: true,
},
/* 显隐列类型transfer穿梭框、checkbox复选框 */
showColumnsType: {
type: String,
default: 'checkbox',
},
/* 右外边距 */
gutter: {
type: Number,
default: 10,
},
},
computed: {
style() {
const ret = {}
if (this.gutter) {
ret.marginRight = `${this.gutter / 2}px`
}
return ret
},
},
created() {
if (this.showColumnsType == 'transfer') {
//
for (let item in this.columns) {
if (this.columns[item].visible === false) {
this.value.push(parseInt(item))
}
}
}
},
methods: {
//
toggleSearch() {
this.$emit('update:showSearch', !this.showSearch)
},
// //
// toggleSearch() {
// this.$emit('update:showSearch', !this.showSearch)
// },
//
refresh() {
this.$emit('queryTable')
},
//
dataChange(data) {
for (let item in this.columns) {
const key = this.columns[item].key
this.columns[item].visible = !data.includes(key)
}
},
// dialog
showColumn() {
this.open = true
},
//
checkboxChange(event, label) {
let checkList = this.columns
checkList.forEach((e) => {
if (e.t_label === label) {
e.checked = event
}
})
this.$emit('checkboxChange', checkList)
},
},
}
</script>
<style lang="scss" scoped>
::v-deep .el-transfer__button {
border-radius: 50%;
padding: 12px;
display: block;
margin-left: 0px;
}
::v-deep .el-transfer__button:first-child {
margin-bottom: 10px;
}
</style>

View File

@ -18,7 +18,7 @@ import './assets/icons' // icon
import './permission' // permission control
import { getDicts } from "@/api/system/dict/data";
import { getConfigKey } from "@/api/system/config";
import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/bonus";
import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree, indexContinuation } from "@/utils/bonus";
// 分页组件
import Pagination from "@/components/Pagination";
// 自定义表格工具组件
@ -37,6 +37,10 @@ import DictTag from '@/components/DictTag'
import VueMeta from 'vue-meta'
// 字典数据组件
import DictData from '@/components/DictData'
// 表格组件
import TableModel from '@/components/TableModel'
// 弹框组件
import DialogModel from '@/components/DialogModel'
// 全局方法挂载
Vue.prototype.getDicts = getDicts
@ -48,6 +52,8 @@ Vue.prototype.selectDictLabel = selectDictLabel
Vue.prototype.selectDictLabels = selectDictLabels
Vue.prototype.download = download
Vue.prototype.handleTree = handleTree
Vue.prototype.indexContinuation = indexContinuation
// 全局组件挂载
Vue.component('DictTag', DictTag)
@ -57,6 +63,8 @@ Vue.component('Editor', Editor)
Vue.component('FileUpload', FileUpload)
Vue.component('ImageUpload', ImageUpload)
Vue.component('ImagePreview', ImagePreview)
Vue.component('TableModel', TableModel)
Vue.component('DialogModel', DialogModel)
Vue.use(directive)
Vue.use(plugins)

View File

@ -234,3 +234,8 @@ export function tansParams(params) {
export function blobValidate(data) {
return data.type !== 'application/json'
}
// 解决表格翻页时 index 索引延续问题
export function indexContinuation(num, size) {
return (num - 1) * size + 1
}

View File

@ -43,9 +43,9 @@ const CONFIG = {
IS_CODE_LOGIN: LOGIN_CONFIG.CODE_EMAIL_LOGIN || LOGIN_CONFIG.CODE_PHONE_LOGIN, // 是否开启短信登录
// 数据设置
dataSettings: {
integrityCheck: DATA_SETTINGS.OPEN, // 数据完整性校验true开启false关闭
encryptRequest: DATA_SETTINGS.OPEN, // 数据传输加密true开启false关闭
encryptResponse: DATA_SETTINGS.OPEN // 数据返回解密true开启false关闭
integrityCheck: DATA_SETTINGS.CLOSE, // 数据完整性校验true开启false关闭
encryptRequest: DATA_SETTINGS.CLOSE, // 数据传输加密true开启false关闭
encryptResponse: DATA_SETTINGS.CLOSE // 数据返回解密true开启false关闭
}
}

View File

@ -0,0 +1,73 @@
import { param2Obj } from '@/utils'
export const commonMixin = {
data() {
return {
// 修改时的数据源
editParams: null,
}
},
methods: {
/** 新建 */
handleAddData() {
this.editParams = null
this.dialogConfig.outerTitle = this.addDialogTitle
this.dialogConfig.outerVisible = true
},
/** 删除 */
handleDeleteData(id, method) {
this.$modal.confirm('是否确定删除').then(() => {
method(id).then(res => {
this.$modal.msgSuccess('操作成功!')
this.$refs.tableRef.getTableList()
}).catch(err => {})
})
},
/** 编辑 */
handleEditData(data) {
this.editParams = data
this.dialogConfig.outerTitle = this.editDialogTitle
this.dialogConfig.outerVisible = true
},
/** 导入数据 */
handleImportData() {
console.log('导入--')
},
/** 导出数据 */
handleExportData(data, url, fileName, queryParams) {
this.download(
url,
{
...queryParams,
dataCondition: data
},
`${fileName}_${new Date().getTime()}.xlsx`,
)
},
/** 关闭外侧弹框 */
closeDialogOuter() {
this.dialogConfig.outerVisible = false
},
/** 关闭内侧弹框 */
closeDialogInner() {
this.dialogConfig.innerVisible = false
},
/** 关闭弹框 由表单组件通知父组件关闭弹框的自定义事件 */
closeDialog(type) {
this.dialogConfig.outerVisible = false
if(type) {
this.$refs.tableRef.getTableList()
}
},
/** 手机号脱密处理 */
phoneCrypto(phoneNumber) {
let reg = /^(1[3-9][0-9])\d{4}(\d{4}$)/
let isMobile = reg.test(phoneNumber)
if (isMobile) {
return phoneNumber.replace(reg, "$1****$2")
}
return phoneNumber
}
}
}

View File

@ -0,0 +1,384 @@
<template>
<!-- 工程管理 新增编辑 表单组件 -->
<div>
<el-form
label-width="100px"
size="medium"
ref="projectParamsRef"
:model="projectParams"
:rules="projectParamsRules"
>
<el-row type="flex" justify="space-between" :gutter="24">
<el-col :span="12">
<el-form-item label="工程名称" prop="proName">
<el-select
v-model="projectParams.proName"
allow-create
clearable
filterable
placeholder="请选择"
@change="proNameChange"
>
<el-option
v-for="item in projNameRange"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所属项目部" prop="departId">
<el-select
v-model="projectParams.departId"
clearable
filterable
placeholder="请选择"
>
<el-option
v-for="item in deptRange"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row type="flex" justify="space-between" :gutter="24">
<el-col :span="12">
<el-form-item label="电压等级" prop="relId">
<el-select
v-model="projectParams.relId"
clearable
filterable
allow-create
placeholder="请选择"
>
<el-option
v-for="item in volRange"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="建管单位" prop="areaId">
<el-select
v-model="projectParams.areaId"
clearable
filterable
placeholder="请选择"
>
<el-option
v-for="item in provinceRange"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row type="flex" justify="space-between" :gutter="24">
<el-col :span="12">
<el-form-item label="工程类型" prop="proType">
<el-select
v-model="projectParams.proType"
clearable
filterable
placeholder="请选择"
>
<el-option
v-for="item in projTypeRange"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工程状态" prop="proStatus">
<el-select
v-model="projectParams.proStatus"
clearable
filterable
placeholder="请选择"
>
<el-option
v-for="item in projStatusRange"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row type="flex" justify="space-between" :gutter="24">
<el-col :span="12">
<el-form-item label="经度" prop="lon">
<el-input v-model="projectParams.lon" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="纬度" prop="lat">
<el-input v-model="projectParams.lat" />
</el-form-item>
</el-col>
</el-row>
<el-form-item>
<el-button type="success" @click="onSubmit">确认</el-button>
<el-button
@click="
() => {
this.$emit('closeDialog')
}
"
>取消</el-button
>
</el-form-item>
</el-form>
</div>
</template>
<script>
import {
addProjApi,
editProjApi,
queryProjNameApi,
queryDeptApi,
queryVolLevelApi
} from '@/api/base/proj'
import {
queryProvincesApi
} from '@/api/base/projDept'
export default {
name: 'FormProject',
props: {
editParams: {
type: Object,
default: () => null,
},
},
components: { },
created() {
this.getRanges()
},
mounted() {
console.log(this.editParams)
if (this.editParams) {
Object.assign(this.projectParams, this.editParams)
this.subSort = 2
} else {
this.subSort = 1
}
},
data() {
return {
subSort: '', // 1 / 2
projectParams: {
proName: undefined, //
departId: undefined, //
relId: undefined, //
areaId: undefined, //
proType: undefined, //
proStatus: undefined, //
lon: undefined, //
lat: undefined, //
},
//
projectParamsRules: {
proName: [
{
required: true,
message: '请输入工程名称',
trigger: 'blur',
},
],
departId: [
{
required: true,
message: '请输入所属项目部',
trigger: 'blur',
},
],
relId: [
{
required: true,
message: '请输入电压等级',
trigger: 'blur',
},
],
areaId: [
{
required: true,
message: '请输入建管单位',
trigger: 'blur',
},
],
proType: [
{
required: true,
message: '请输入工程类型',
trigger: 'blur',
},
],
proStatus: [
{
required: true,
message: '请输入工程状态',
trigger: 'blur',
},
],
lon: [
{
required: true,
message: '请输入经度',
trigger: 'blur',
},
],
lat: [
{
required: true,
message: '请输入纬度',
trigger: 'blur',
},
],
},
//
projNameRange: [],
deptRange: [],
volRange: [],
projStatusRange: [
{ label: '施工', value: '0' },
{ label: '暂停', value: '1' },
],
projTypeRange: [
{ label: '变电工程', value: '1' },
{ label: '线路工程', value: '2' },
{ label: '电缆工程', value: '3' },
],
provinceRange: [],
//
phoneReg: /^(?:(?:\+|00)86)?1[3-9]\d{9}$/
}
},
methods: {
/** 获取各类下拉框 */
async getRanges() {
//
let nameRes = await queryProjNameApi()
this.projNameRange = nameRes.data.map(item => {
return {
label: item.proName,
value: item.proName,
departId: item.departId,
relId: item.relName,
areaId: item.areaId,
proType: item.proTypeName,
proStatus: item.proStatusName,
lon: item.lon,
lat: item.lat
}
})
//
let provinceRes = await queryProvincesApi()
this.provinceRange = provinceRes.data.map(item => {
return {
label: item.areaName,
value: item.areaId
}
})
//
let deptRes = await queryDeptApi({
isAll: 0
})
this.deptRange = deptRes.data.map(item => {
return {
label: item.departName,
value: item.id,
}
})
//
let volRes = await queryVolLevelApi({
dictType: 'rel_level'
})
this.volRange = volRes.data.map(item => {
return {
label: item.dictLabel,
value: item.dictCode
}
})
},
/** 改变树结构 */
changeTree(leaf) {
leaf.map(item => {
item.value = item.id
if(item.children) {
this.changeTree(item.children)
}
})
return leaf
},
/** 工程名称改变 */
proNameChange(e) {
this.projNameRange.forEach(item => {
if(e === item.label) {
console.log(e, item)
this.projectParams.departId = item.departId
this.projectParams.relId = item.relId
this.projectParams.areaId = item.areaId
this.projectParams.proType = item.proType
this.projectParams.proStatus = item.proStatus
this.projectParams.lon = item.lon
this.projectParams.lat = item.lat
}
})
},
/** 级联选择器改变 */
handleCas(e) {
this.projectParams.impUnit = e[e.length - 1]
},
/** 确认按钮 */
onSubmit() {
this.$refs.projectParamsRef.validate(valid => {
if (valid) {
console.log('校验通过', this.projectParams, this.subSort)
// 1. Api
if(this.subSort === 1) {
addProjApi(this.projectParams).then(res => {
this.$modal.msgSuccess('操作成功')
// 2.
this.$emit('closeDialog', true)
}).catch(err => {
console.log(err)
})
} else if(this.subSort === 2) {
editProjApi(this.projectParams).then(res => {
this.$modal.msgSuccess('操作成功')
// 2.
this.$emit('closeDialog', true)
}).catch(err => {
console.log(err)
})
}
}
})
},
},
}
</script>
<style scoped>
::v-deep .el-select {
width: 100%;
}
::v-deep .el-form-item__label{
font-weight: normal;
}
</style>

View File

@ -0,0 +1,122 @@
<template>
<!-- 工程管理页面 -->
<div class="app-container">
<el-form
label-width="100px"
size="medium"
ref="towerAddParamsRef"
:model="towerAddParams"
:rules="towerAddParamsRules"
>
<el-form-item label="杆塔名称" prop="name">
<el-input v-model="towerAddParams.name" placeholder="请输入" />
</el-form-item>
<el-form-item label="坐标经度" prop="lon">
<el-input v-model="towerAddParams.lon" placeholder="请输入" />
</el-form-item>
<el-form-item label="坐标纬度" prop="lat">
<el-input v-model="towerAddParams.lat" placeholder="请输入" />
</el-form-item>
<el-form-item>
<el-button type="success" @click="onSubmit">确认</el-button>
<el-button
@click="
() => {
this.$emit('closeAdd')
}
"
>取消</el-button
>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
name: 'towerAdd',
props: {
sendAddData: {
type: Object,
default: null
}
},
methods: {
/** 确认按钮 */
onSubmit() {
this.$refs.towerAddParamsRef.validate(valid => {
if (valid) {
console.log('校验通过', this.towerAddParams, this.subSort)
// 1. Api
/* if(this.subSort === 1) {
addProjDeptApi(this.projectParams).then(res => {
this.$modal.msgSuccess('操作成功')
// 2.
this.$emit('closeDialog', true)
}).catch(err => {
console.log(err)
})
} else if(this.subSort === 2) {
editProjDeptApi(this.projectParams).then(res => {
this.$modal.msgSuccess('操作成功')
// 2.
this.$emit('closeDialog', true)
}).catch(err => {
console.log(err)
})
} */
}
})
},
},
components: {
},
created() {
},
mounted() {
console.log(this.sendAddData, '=======')
if (this.sendAddData) {
Object.assign(this.towerAddParams, this.sendAddData)
this.subSort = 2
} else {
this.subSort = 1
}
},
data() {
return {
subSort: '', // 1 / 2
towerAddParams: {
name: undefined, //
lon: undefined, //
lat: undefined, //
},
//
towerAddParamsRules: {
name: [
{
required: true,
message: '请输入杆塔名称',
trigger: 'blur',
},
],
lon: [
{
required: true,
message: '请输入经度',
trigger: 'blur',
},
],
lat: [
{
required: true,
message: '请输入纬度',
trigger: 'blur',
},
],
},
}
},
}
</script>

View File

@ -0,0 +1,136 @@
<template>
<!-- 工程管理页面 -->
<div class="app-container">
<!-- 表格 -->
<TableModel
:formLabel="formLabelTower"
:columnsList="columnsListTower"
:request-api="queryProjListApi"
ref="tableRef"
@transIdList="getIdList"
>
<template slot="btn" slot-scope="{ queryParams }">
<el-button type="primary" @click="handleAddTower()" icon="el-icon-plus" size="mini"
>新增杆塔</el-button
>
<el-button
@click="handleExportData(
exportList,
'base/tbProject/export',
'工程清单',
queryParams
)"
icon="el-icon-upload2"
size="mini"
>导出数据</el-button
>
<el-button
icon="el-icon-download"
size="mini"
>数据模板下载</el-button
>
<el-button
icon="el-icon-download"
size="mini"
>导入数据</el-button
>
</template>
<template slot="handle" slot-scope="{ data }">
<el-button
type="primary"
size="mini"
@click="handleEditTower(data)"
>编辑</el-button
>
<el-button
type="danger"
size="mini"
@click="handleDeleteData(data.id, deleteProjApi)"
>删除</el-button
>
</template>
</TableModel>
<DialogModel
:dialogConfig="dialogConfigTowerAdd"
@closeDialogOuter="closeDialogTowerAddOuter"
>
<template slot="outerContent">
<!-- 新增以及修改数据的表单组件 -->
<TableTowerAdd
:send-add-data="sendAddData"
@closeAdd="closeAdd"
>
</TableTowerAdd>
</template>
</DialogModel>
</div>
</template>
<script>
import {
queryProjListApi
} from '@/api/base/proj'
import { formLabelTower, columnsListTower, dialogConfigTowerAdd } from '../config-tower'
import { commonMixin } from '../../mixins/common'
import TableTowerAdd from './table-tower-add.vue'
export default {
name: 'tower',
props: {
sendData: {
type: Object,
default: () => null,
},
},
methods: {
queryProjListApi,
handleAddTower() {
this.dialogConfigTowerAdd.outerVisible = true
},
handleEditTower(data) {
this.sendAddData = data
this.dialogConfigTowerAdd.outerVisible = true
},
closeAdd() {
this.dialogConfigTowerAdd.outerVisible = false
},
closeDialogTowerAddOuter() {
this.dialogConfigTowerAdd.outerVisible = false
},
getIdList(idList) {
this.exportList = []
idList.forEach(item => {
this.exportList.push(item.id)
})
},
},
mixins: [commonMixin],
components: {
TableTowerAdd
},
created() {
},
mounted() {
console.log(this.sendData, '-----------')
},
data() {
return {
//
formLabelTower,
// id
exportList: [],
//
columnsListTower,
//
dialogConfigTowerAdd,
//
addDialogTitle: '新建项目部',
//
editDialogTitle: '修改项目部',
sendAddData: undefined
}
},
}
</script>

View File

@ -0,0 +1,20 @@
export const formLabelTower = [
{ f_label: '杆塔名称', f_model: 'name', f_type: 'ipt' },
]
export const columnsListTower = [
{ t_props: 'name', t_label: '杆塔名称', },
{ t_props: 'lon', t_label: '杆塔经度' },
{ t_props: 'lat', t_label: '杆塔纬度' },
]
export const dialogConfigTower = {
outerWidth: '60%',
outerTitle: '杆塔',
outerVisible: false,
}
export const dialogConfigTowerAdd = {
outerWidth: '40%',
outerTitle: '新增杆塔',
outerVisible: false,
}

View File

@ -0,0 +1,55 @@
import {
queryVolLevelApi
} from '@/api/base/proj'
import {
queryProvincesApi
} from '@/api/base/projDept'
export const querySel = () => {
queryVolLevelApi({
dictType: 'rel_level'
}).then(res => {
formLabel[1].f_selList = res.data.map(item => {
return {
label: item.dictLabel,
value: item.dictCode
}
})
})
queryProvincesApi().then(res => {
formLabel[2].f_selList = res.data.map(item => {
return {
label: item.areaName,
value: item.areaId
}
})
})
}
export const formLabel = [
{ f_label: '工程名称', f_model: 'proName', f_type: 'ipt' },
{ f_label: '电压等级', f_model: 'relId', f_type: 'sel', f_selList: [] },
{ f_label: '建管单位', f_model: 'areaId', f_type: 'sel', f_selList: [] },
{ f_label: '工程类型', f_model: 'proType', f_type: 'sel', f_selList: [
{ label: '变电工程', value: '1' },
{ label: '线路工程', value: '2' },
{ label: '电缆工程', value: '3' },
] },
{ f_label: '项目部名称', f_model: 'departId', f_type: 'ipt' },
]
export const columnsList = [
{ t_props: 'departName', t_label: '所属项目部', },
{ t_props: 'proName', t_label: '工程名称' },
{ t_props: 'relName', t_label: '电压等级' },
{ t_props: 'proTypeName', t_label: '工程类型', },
{ t_props: 'proStatusName', t_label: '工程状态', },
{ t_props: 'lon', t_label: '经度', },
{ t_props: 'lat', t_label: '纬度', },
{ t_props: 'powerTotal', t_label: '杆塔', t_slot: 'powerTotal' },
]
export const dialogConfig = {
outerWidth: '60%',
outerTitle: '',
outerVisible: false,
}

View File

@ -0,0 +1,139 @@
<template>
<!-- 工程管理页面 -->
<div class="app-container">
<!-- 表格 -->
<TableModel
:formLabel="formLabel"
:columnsList="columnsList"
:request-api="queryProjListApi"
ref="tableRef"
@transIdList="getIdList"
>
<template slot="btn" slot-scope="{ queryParams }">
<el-button type="primary" @click="handleAddData()" icon="el-icon-plus" size="mini"
>新建工程</el-button
>
<el-button
@click="handleExportData(
exportList,
'base/tbProject/export',
'工程清单',
queryParams
)"
icon="el-icon-upload2"
size="mini"
>导出数据</el-button
>
</template>
<template slot="handle" slot-scope="{ data }">
<el-button
type="primary"
size="mini"
@click="handleEditData(data)"
>编辑</el-button
>
<el-button
type="danger"
size="mini"
@click="handleDeleteData(data.id, deleteProjApi)"
>删除</el-button
>
</template>
<template slot="powerTotal" slot-scope="{ data }">
<span
style="color: #0060EE; font-weight: bold; cursor: pointer"
@click="handleTower(data)"
>
{{ data.powerTotal }}
</span>
</template>
</TableModel>
<!-- 新增以及修改时的弹框 -->
<DialogModel
:dialogConfig="dialogConfig"
@closeDialogOuter="closeDialogOuter"
>
<template slot="outerContent">
<!-- 新增以及修改数据的表单组件 -->
<FormProject
:editParams="editParams"
@closeDialog="closeDialog"
/>
</template>
</DialogModel>
<DialogModel
:dialogConfig="dialogConfigTower"
@closeDialogOuter="closeDialogTowerOuter"
>
<template slot="outerContent">
<!-- 新增以及修改数据的表单组件 -->
<TableTower
:send-data="sendData"
>
</TableTower>
</template>
</DialogModel>
</div>
</template>
<script>
import { formLabel, columnsList, dialogConfig, querySel } from './config'
import { dialogConfigTower } from './config-tower'
import { commonMixin } from '../mixins/common'
import {
queryProjListApi,
deleteProjApi
} from '@/api/base/proj'
import FormProject from './components/form-project'
import TableTower from './components/table-tower'
export default {
name: 'Project',
methods: {
queryProjListApi,
deleteProjApi,
closeDialogTowerOuter() {
this.dialogConfigTower.outerVisible = false
},
getIdList(idList) {
this.exportList = []
idList.forEach(item => {
this.exportList.push(item.id)
})
},
handleTower(v) {
this.sendData = v
this.dialogConfigTower.outerVisible = true
}
},
mixins: [commonMixin],
components: {
FormProject,
TableTower
},
created() {
querySel()
},
data() {
return {
//
formLabel,
// id
exportList: [],
//
columnsList,
//
dialogConfig,
dialogConfigTower,
//
addDialogTitle: '新建工程',
//
editDialogTitle: '修改工程',
sendData: undefined
}
},
}
</script>

View File

@ -0,0 +1,251 @@
<template>
<!-- 工程管理 新增编辑 表单组件 -->
<div>
<el-form
label-width="100px"
size="medium"
ref="projectParamsRef"
:model="projectParams"
:rules="projectParamsRules"
>
<el-form-item label="项目部名称" prop="departName">
<el-select
v-model="projectParams.departName"
allow-create
clearable
filterable
placeholder="请选择"
@change="departNameChange"
>
<el-option
v-for="item in projRange"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="项目部类型" prop="departType">
<el-select
v-model="projectParams.departType"
clearable
filterable
placeholder="请选择"
>
<el-option
v-for="item in typeRange"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="地区" prop="areaId">
<el-select
v-model="projectParams.areaId"
clearable
filterable
placeholder="请选择"
>
<el-option
v-for="item in provinceRange"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="负责人" prop="headUser">
<el-input v-model="projectParams.headUser" placeholder="请输入" />
</el-form-item>
<el-form-item label="负责人电话" prop="headUserPhone">
<el-input v-model="projectParams.headUserPhone" :maxlength="11" placeholder="请输入" />
</el-form-item>
<el-form-item label="备注" prop="remarks">
<el-input v-model="projectParams.remarks" placeholder="请输入" />
</el-form-item>
<el-form-item>
<el-button type="success" @click="onSubmit">确认</el-button>
<el-button
@click="
() => {
this.$emit('closeDialog')
}
"
>取消</el-button
>
</el-form-item>
</el-form>
</div>
</template>
<script>
import {
queryProvincesApi,
queryProjDeptTypeApi,
queryProjDeptNameApi,
addProjDeptApi,
editProjDeptApi
} from '@/api/base/projDept'
export default {
name: 'FormProject',
props: {
editParams: {
type: Object,
default: () => null,
},
},
components: { },
created() {
this.getRanges()
},
mounted() {
console.log(this.editParams)
if (this.editParams) {
Object.assign(this.projectParams, this.editParams)
this.subSort = 2
} else {
this.subSort = 1
}
},
data() {
return {
subSort: '', // 1 / 2
projectParams: {
departName: undefined, //
departType: undefined, //
areaId: undefined, //
headUser: undefined, //
headUserPhone: undefined, //
remarks: undefined, //
},
//
projectParamsRules: {
departName: [
{
required: true,
message: '请输入项目部名称',
trigger: 'blur',
},
],
departType: [
{
required: true,
message: '请输入项目部类型',
trigger: 'blur',
},
],
},
//
projRange: [],
provinceRange: [],
typeRange: [],
//
phoneReg: /^(?:(?:\+|00)86)?1[3-9]\d{9}$/
}
},
methods: {
/** 获取各类下拉框 */
async getRanges() {
//
let provinceRes = await queryProvincesApi()
this.provinceRange = provinceRes.data.map(item => {
return {
label: item.areaName,
value: item.areaId
}
})
//
let typeRes = await queryProjDeptTypeApi({
dictType: 'depar_type'
})
this.typeRange = typeRes.data.map(item => {
return {
label: item.dictLabel,
value: item.dictCode
}
})
//
let projRes = await queryProjDeptNameApi()
this.projRange = projRes.data.map(item => {
return {
label: item.departName,
value: item.departName,
departType: item.departType,
areaName: item.areaName,
headUser: item.headUser,
headUserPhone: item.headUserPhone,
remarks: item.remarks,
}
})
},
/** 改变树结构 */
changeTree(leaf) {
leaf.map(item => {
item.value = item.id
if(item.children) {
this.changeTree(item.children)
}
})
return leaf
},
/** 项目部名称改变 */
departNameChange(e) {
this.projRange.forEach(item => {
if(e === item.label) {
this.projectParams.departType = item.departType
this.projectParams.areaId = item.areaId
this.projectParams.headUser = item.headUser
this.projectParams.headUserPhone = item.headUserPhone
this.projectParams.remarks = item.remarks
}
})
},
/** 级联选择器改变 */
handleCas(e) {
this.projectParams.impUnit = e[e.length - 1]
},
/** 确认按钮 */
onSubmit() {
this.$refs.projectParamsRef.validate(valid => {
if (valid) {
if(this.projectParams.headUserPhone !== undefined && this.projectParams.headUserPhone !== "" && this.projectParams.headUserPhone !== null) {
if(!this.phoneReg.test(this.projectParams.headUserPhone)) {
this.$modal.msgError('请填写正确的联系方式')
return false
}
}
console.log('校验通过', this.projectParams, this.subSort)
// 1. Api
if(this.subSort === 1) {
addProjDeptApi(this.projectParams).then(res => {
this.$modal.msgSuccess('操作成功')
// 2.
this.$emit('closeDialog', true)
}).catch(err => {
console.log(err)
})
} else if(this.subSort === 2) {
editProjDeptApi(this.projectParams).then(res => {
this.$modal.msgSuccess('操作成功')
// 2.
this.$emit('closeDialog', true)
}).catch(err => {
console.log(err)
})
}
}
})
},
},
}
</script>
<style scoped>
::v-deep .el-select {
width: 100%;
}
::v-deep .el-form-item__label{
font-weight: normal;
}
</style>

View File

@ -0,0 +1,34 @@
import {
queryProvincesApi
} from '@/api/base/projDept'
export const queryProvinces = () => {
queryProvincesApi().then(res => {
formLabel[0].f_selList = res.data.map(item => {
return {
label: item.areaName,
value: item.areaId
}
})
}).catch(err => {})
}
export const formLabel = [
{ f_label: '地区', f_model: 'areaId', f_type: 'sel', f_selList: [] },
{ f_label: '项目部名称', f_model: 'departName', f_type: 'ipt' },
{ f_label: '负责人', f_model: 'headUser', f_type: 'ipt' },
]
export const columnsList = [
{ t_props: 'departName', t_label: '项目部名称', },
{ t_props: 'departType', t_label: '项目部类型' },
{ t_props: 'areaName', t_label: '地区' },
{ t_props: 'headUser', t_label: '负责人', },
{ t_props: 'headUserPhone', t_label: '电话', },
{ t_props: 'remarks', t_label: '备注', },
]
export const dialogConfig = {
outerWidth: '40%',
outerTitle: '',
outerVisible: false,
}

View File

@ -0,0 +1,107 @@
<template>
<!-- 工程管理页面 -->
<div class="app-container">
<!-- 表格 -->
<TableModel
:formLabel="formLabel"
:columnsList="columnsList"
:request-api="queryProjDeptListApi"
ref="tableRef"
@transIdList="getIdList"
>
<template slot="btn" slot-scope="{ queryParams }">
<el-button type="primary" @click="handleAddData()" icon="el-icon-plus" size="mini"
>新建项目部</el-button
>
<el-button
@click="handleExportData(
exportList,
'base/tbProDepart/export',
'项目部清单',
queryParams
)"
icon="el-icon-upload2"
size="mini"
>导出数据</el-button
>
</template>
<template slot="handle" slot-scope="{ data }">
<el-button
type="primary"
size="mini"
@click="handleEditData(data)"
>编辑</el-button
>
<el-button
type="danger"
size="mini"
@click="handleDeleteData(data.id, deleteProjDeptApi)"
>删除</el-button
>
</template>
<!-- <template slot="isMatch" slot-scope="{ data }">
{{ data.proId == null ? '不匹配' : '匹配' }}
</template>-->
</TableModel>
<!-- 新增以及修改时的弹框 -->
<DialogModel
:dialogConfig="dialogConfig"
@closeDialogOuter="closeDialogOuter"
>
<template slot="outerContent">
<!-- 新增以及修改数据的表单组件 -->
<FormProject
:editParams="editParams"
@closeDialog="closeDialog"
/>
</template>
</DialogModel>
</div>
</template>
<script>
import { formLabel, columnsList, dialogConfig, queryProvinces } from './config'
import { commonMixin } from '../mixins/common'
import {
queryProjDeptListApi,
deleteProjDeptApi
} from '@/api/base/projDept'
import FormProject from './components/form-project'
export default {
name: 'ProjectDepart',
methods: {
queryProjDeptListApi,
deleteProjDeptApi,
getIdList(idList) {
this.exportList = []
idList.forEach(item => {
this.exportList.push(item.id)
})
}
},
mixins: [commonMixin],
components: {
FormProject
},
created() {
queryProvinces()
},
data() {
return {
//
formLabel,
// id
exportList: [],
//
columnsList,
//
dialogConfig,
//
addDialogTitle: '新建项目部',
//
editDialogTitle: '修改项目部',
}
},
}
</script>

View File

@ -100,6 +100,9 @@ export default {
//
version: "24.7.1",
};
},
mounted() {
},
methods: {
goTarget(href) {