基础组件封装,工程管理,往来单位管理基本页面搭建

This commit is contained in:
BianLzhaoMin 2024-08-07 15:52:51 +08:00
parent ef97374758
commit 949a04de73
15 changed files with 904 additions and 150 deletions

View File

@ -5,6 +5,7 @@
transition: margin-left .28s;
margin-left: $base-sidebar-width;
position: relative;
overflow: hidden;
}
.sidebarHide {

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

@ -76,15 +76,40 @@
</el-form-item>
</el-form>
<!-- 按钮集群 -->
<el-row>
<slot name="btn" :pageParams="pageParams"></slot>
<RightToolbar
<el-row class="btn-container">
<div class="btn-handler">
<slot name="btn" :pageParams="queryParams"></slot>
</div>
<ToolbarModel
:showSearch.sync="showSearch"
:indexNumShow.sync="indexNumShow"
:selectionShow.sync="selectionShow"
:handleShow.sync="handleShow"
:columns="columCheckList"
@queryTable="getTableList"
:columns="tableColumCheckProps"
/>
</el-row>
<!-- 表格 -->
<el-table
:data="tableList"
border
ref="tableRef"
select-on-indeterminate
>
<el-table-column
type="selection"
width="45"
align="center"
v-if="selectionShow"
/>
<el-table-column
width="55"
align="center"
label="序号"
type="index"
v-if="indexNumShow"
/>
<el-table-column
v-for="(item, v) in tableColumCheckProps"
:key="v"
@ -104,42 +129,19 @@
</template>
</template>
</el-table-column>
<el-table-column
align="center"
label="操作"
v-if="config.handleColShow"
:width="config.handleWidth"
>
<el-table-column align="center" label="操作" v-show="handleShow">
<template slot-scope="{ row }">
<slot :data="row" name="handle"></slot>
</template>
<!-- 增加筛选列显示隐藏操作 -->
<template slot="header">
<el-popover
placement="bottom"
title="筛选列"
width="200"
trigger="click"
>
<span slot="reference" class="handel-text">操作</span>
<div>
<el-checkbox
v-for="(check, index) in columCheckList"
v-show="check.t_label != '序号'"
:key="index"
v-model="check.checked"
>{{ check.t_label }}</el-checkbox
>
</div>
</el-popover>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import ToolbarModel from '../ToolbarModel'
export default {
components: { ToolbarModel },
props: {
/** 表单查询条件 */
formLabel: {
@ -153,7 +155,7 @@ export default {
},
/* 列表配置项 */
columnsList: {
type: Object,
type: Array,
default: () => [],
},
},
@ -172,6 +174,14 @@ export default {
queryParams: {},
//
showSearch: true,
//
selectionShow: true,
//
indexNumShow: true,
//
handleShow: true,
columCheckList: [],
tableList: [],
}
},
@ -200,11 +210,28 @@ export default {
},
/** 重置按钮 */
resetQuery() {
this.$refs.queryFormRef.resetFields()
// this.$refs.queryFormRef.resetFields()
this.getTableList()
},
/** 筛选列 */
checkboxChange(list) {
this.columCheckList = list
},
},
}
</script>
<style></style>
<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;
}
}
</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

@ -10,7 +10,7 @@
</template>
<script>
import iframeToggle from "./IframeToggle/index"
import iframeToggle from './IframeToggle/index'
export default {
name: 'AppMain',
@ -21,18 +21,19 @@ export default {
},
key() {
return this.$route.path
}
}
},
},
}
</script>
<style lang="scss" scoped>
.app-main {
/* 50= navbar 50 */
min-height: calc(100vh - 50px);
// min-height: calc(100vh - 50px);
height: calc(100vh - 50px);
width: 100%;
position: relative;
overflow: hidden;
overflow: auto;
}
.fixed-header + .app-main {

View File

@ -40,6 +40,8 @@ import DictData from '@/components/DictData'
// 表格组件
import TableModel from '@/components/TableModel'
// 弹框组件
import DialogModel from '@/components/DialogModel'
// 全局方法挂载
Vue.prototype.getDicts = getDicts
@ -61,6 +63,7 @@ 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)

12
src/mixins/common.js Normal file
View File

@ -0,0 +1,12 @@
export const commonMixin = {
methods: {
/** 关闭外侧弹框 */
closeDialogOuter() {
this.dialogConfig.outerVisible = false
},
/** 关闭内侧弹框 */
closeDialogInner() {
this.dialogConfig.innerVisible = false
},
}
}

View File

@ -12,46 +12,47 @@ const whiteList = ['/login', '/register']
router.beforeEach((to, from, next) => {
NProgress.start()
if (getToken()) {
console.log(getToken())
to.meta.title && store.dispatch('settings/setTitle', to.meta.title)
/* has token*/
if (to.path === '/login') {
next({ path: '/' })
NProgress.done()
} else if (whiteList.indexOf(to.path) !== -1) {
next()
} else {
if (store.getters.roles.length === 0) {
isRelogin.show = true
// 判断当前用户是否已拉取完user_info信息
store.dispatch('GetInfo').then(() => {
isRelogin.show = false
store.dispatch('GenerateRoutes').then(accessRoutes => {
// 根据roles权限生成可访问的路由表
router.addRoutes(accessRoutes) // 动态添加可访问路由表
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
})
}).catch(err => {
store.dispatch('LogOut').then(() => {
Message.error(err)
next({ path: '/' })
})
})
} else {
next()
}
}
} else {
// 没有token
if (whiteList.indexOf(to.path) !== -1) {
// 在免登录白名单,直接进入
next()
} else {
next(`/login?redirect=${encodeURIComponent(to.fullPath)}`) // 否则全部重定向到登录页
NProgress.done()
}
}
// if (getToken()) {
// console.log(getToken())
// to.meta.title && store.dispatch('settings/setTitle', to.meta.title)
// /* has token*/
// if (to.path === '/login') {
// next({ path: '/' })
// NProgress.done()
// } else if (whiteList.indexOf(to.path) !== -1) {
// next()
// } else {
// if (store.getters.roles.length === 0) {
// isRelogin.show = true
// // 判断当前用户是否已拉取完user_info信息
// store.dispatch('GetInfo').then(() => {
// isRelogin.show = false
// store.dispatch('GenerateRoutes').then(accessRoutes => {
// // 根据roles权限生成可访问的路由表
// router.addRoutes(accessRoutes) // 动态添加可访问路由表
// next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
// })
// }).catch(err => {
// store.dispatch('LogOut').then(() => {
// Message.error(err)
// next({ path: '/' })
// })
// })
// } else {
// next()
// }
// }
// } else {
// // 没有token
// if (whiteList.indexOf(to.path) !== -1) {
// // 在免登录白名单,直接进入
// next()
// } else {
// next(`/login?redirect=${encodeURIComponent(to.fullPath)}`) // 否则全部重定向到登录页
// NProgress.done()
// }
// }
})
router.afterEach(() => {

View File

@ -71,6 +71,18 @@ export const constantRoutes = [
component: () => import('@/views/index'),
name: 'Index',
meta: { title: '首页', icon: 'dashboard', affix: true }
},
{
path: 'ProjectManage',
component: () => import('@/views/BasicManage/ProjectManage'),
name: 'ProjectManage',
meta: { title: '工程管理', icon: 'dashboard', affix: true }
},
{
path: 'ContactUnits',
component: () => import('@/views/BasicManage/ContactUnits'),
name: 'ContactUnits',
meta: { title: '往来单位', icon: 'dashboard', affix: true }
}
]
},

View File

@ -0,0 +1,121 @@
<template>
<div>
<el-form
label-width="100px"
size="medium"
ref="contactUnitsParamsRef"
:model="contactUnitsParams"
:rules="contactUnitsParamsRules"
>
<el-form-item label="单位名称" prop="pro_name">
<el-input v-model="contactUnitsParams.pro_name" />
</el-form-item>
<el-form-item label="单位类型" prop="pro_type_of">
<el-select v-model="contactUnitsParams.pro_type_of"></el-select>
</el-form-item>
<el-form-item label="所属分公司" prop="pro_unit">
<el-select v-model="contactUnitsParams.pro_unit"></el-select>
</el-form-item>
<el-form-item label="联系人" prop="pro_user">
<el-input v-model="contactUnitsParams.pro_user" />
</el-form-item>
<el-form-item label="联系电话" prop="pro_phone">
<el-input v-model="contactUnitsParams.pro_phone" />
</el-form-item>
<el-form-item label="启用状态" prop="pro_type">
<el-switch
active-text="启用"
inactive-text="禁用"
v-model="contactUnitsParams.pro_type"
></el-switch>
</el-form-item>
<el-form-item>
<el-button @click="onSubmit">确定</el-button>
<el-button
@click="
() => {
this.$emit('closeDialog')
}
"
>取消</el-button
>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data() {
return {
contactUnitsParams: {
pro_name: '',
pro_code: '',
pro_unit: '',
pro_type_of: '',
pro_type: '',
pro_nature: '',
pro_user: '',
pro_phone: '',
},
//
contactUnitsParamsRules: {
pro_name: [
{
required: true,
message: '请输入工程名称',
trigger: 'blur',
},
],
pro_unit: [
{
required: true,
message: '请选择施工单位',
trigger: 'blur',
},
],
pro_type_of: [
{
required: true,
message: '请选择工程类型',
trigger: 'blur',
},
],
pro_type: [
{
required: true,
message: '请选择工程状态',
trigger: 'blur',
},
],
pro_nature: [
{
required: true,
message: '请选择工程性质',
trigger: 'blur',
},
],
},
}
},
methods: {
/** 确认按钮 */
onSubmit() {
this.$refs.contactUnitsParamsRef.validate((valid) => {
if (valid) {
console.log('校验通过')
// 1. Api
// 2.
this.$emit('closeDialog')
}
})
},
},
}
</script>
<style scoped>
::v-deep .el-select {
width: 100%;
}
</style>

View File

@ -0,0 +1,18 @@
export const formLabel = [
{ f_label: '分公司名称', f_model: 'keyWords', f_type: 'ipt' },
]
export const columnsList = [
{ t_props: 'scrapNum', t_label: '单位名称', },
{ t_props: '', t_label: '单位类型' },
{ t_props: 'repairNum', t_label: '所属分公司' },
{ t_props: 'unitName', t_label: '联系人', },
{ t_props: 'projectName', t_label: '联系电话', },
{ t_props: 'itemType', t_label: '状态', },
]
export const dialogConfig = {
outerWidth: '40%',
outerTitle: '',
outerVisible: false,
}

View File

@ -1,10 +1,51 @@
<template>
<!-- 往来单位 -->
<div> 往来单位 </div>
<div class="app-container">
<TableModel :formLabel="formLabel" :columnsList="columnsList">
<template slot="btn">
<el-button type="primary" @click="addContactUnits()"
>新建</el-button
>
<el-button>导入</el-button>
<el-button>导出</el-button>
</template>
</TableModel>
<DialogModel
:dialogConfig="dialogConfig"
@closeDialogOuter="closeDialogOuter"
>
<template slot="outerContent">
<FormContactUnits @closeDialog="closeDialog" />
</template>
</DialogModel>
</div>
</template>
<script>
export default {}
import { formLabel, columnsList, dialogConfig } from './config'
import { commonMixin } from '@/mixins/common.js'
import FormContactUnits from './components/form-contact-units.vue'
export default {
mixins: [commonMixin], //
components: { FormContactUnits },
data() {
return {
formLabel,
columnsList,
dialogConfig,
}
},
methods: {
/** 新建往来单位 */
addContactUnits() {
this.dialogConfig.outerTitle = '新建往来单位'
this.dialogConfig.outerVisible = true
},
/** 关闭弹框 */
closeDialog() {
this.dialogConfig.outerVisible = false
},
},
}
</script>
<style></style>

View File

@ -0,0 +1,185 @@
<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="pro_name">
<el-input v-model="projectParams.pro_name" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工程编号" prop="pro_code">
<el-input v-model="projectParams.pro_code" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="12">
<el-form-item label="实施单位" prop="pro_unit">
<el-select v-model="projectParams.pro_unit"></el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工程类型" prop="pro_type_of">
<el-select
v-model="projectParams.pro_type_of"
></el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="12">
<el-form-item label="工程状态" prop="pro_type">
<el-select v-model="projectParams.pro_type"></el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工程性质" prop="pro_nature">
<el-select
v-model="projectParams.pro_nature"
></el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="12">
<el-form-item label="项目经理" prop="pro_user">
<el-input v-model="projectParams.pro_user" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系电话" prop="pro_phone">
<el-input v-model="projectParams.pro_phone" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="12">
<el-form-item label="合同主体单位">
<el-input />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所属项目中心">
<el-input />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="12">
<el-form-item label="i8工程ID">
<el-input />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="关联i8工程">
<el-input />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="12">
<el-form-item label="备注">
<el-input type="textarea" :rows="6" />
</el-form-item>
</el-col>
<el-col :span="12"> </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>
export default {
data() {
return {
projectParams: {
pro_name: '',
pro_code: '',
pro_unit: '',
pro_type_of: '',
pro_type: '',
pro_nature: '',
pro_user: '',
pro_phone: '',
},
//
projectParamsRules: {
pro_name: [
{
required: true,
message: '请输入工程名称',
trigger: 'blur',
},
],
pro_unit: [
{
required: true,
message: '请选择施工单位',
trigger: 'blur',
},
],
pro_type_of: [
{
required: true,
message: '请选择工程类型',
trigger: 'blur',
},
],
pro_type: [
{
required: true,
message: '请选择工程状态',
trigger: 'blur',
},
],
pro_nature: [
{
required: true,
message: '请选择工程性质',
trigger: 'blur',
},
],
},
}
},
methods: {
/** 确认按钮 */
onSubmit() {
this.$refs.projectParamsRef.validate((valid) => {
if (valid) {
console.log('校验通过')
// 1. Api
// 2.
this.$emit('closeDialog')
}
})
},
},
}
</script>
<style scoped>
::v-deep .el-select {
width: 100%;
}
</style>

View File

@ -3,11 +3,22 @@ export const formLabel = [
{ f_label: '分公司名称', f_model: 'keywords', f_type: 'ipt' },
]
export const columnsList = [
// { t_width: '55px', t_props: '', t_label: '序号' },
{ t_width: '', t_props: 'scrapNum', t_label: '单位名称', },
{ t_width: '', t_props: '', t_label: '单位类型' },
{ t_width: '', t_props: 'repairNum', t_label: '所属分公司' },
{ t_width: '', t_props: 'unitName', t_label: '联系人', },
{ t_width: '', t_props: 'projectName', t_label: '联系电话', },
{ t_width: '', t_props: 'itemType', t_label: '状态', },
{ t_props: 'scrapNum', t_label: '工程项目名称', },
{ t_props: '', t_label: '实施单位' },
{ t_props: 'repairNum', t_label: '工程类型' },
{ t_props: 'unitName', t_label: 'i8工程编码', },
{ t_props: 'projectName', t_label: '是否匹配i8工程', },
{ t_props: 'itemType', t_label: '合同主体', },
{ t_props: 'itemType', t_label: '项目经理', },
{ t_props: 'itemType', t_label: '联系电话', },
{ t_props: 'itemType', t_label: '工程状态', },
]
export const dialogConfig = {
outerWidth: '70%',
outerTitle: '',
outerVisible: false,
innerWidth: '50%',
innerTitle: '',
innerVisible: false,
}

View File

@ -1,18 +1,57 @@
<template>
<!-- 工程管理 -->
<div>
<TableModel :formLabel="formLabel" :columnsList="columnsList" />
<div class="app-container">
<!-- 表格 -->
<TableModel :formLabel="formLabel" :columnsList="columnsList">
<template slot="btn">
<el-button type="primary" @click="addProject()">新建</el-button>
<el-button>导入</el-button>
<el-button>导出</el-button>
</template>
</TableModel>
<!-- 新增弹框 -->
<DialogModel
:dialogConfig="dialogConfig"
@closeDialogOuter="closeDialogOuter"
>
<template slot="outerContent">
<FormProject @closeDialog="closeDialog" />
</template>
</DialogModel>
</div>
</template>
<script>
import { formLabel, columnsList } from './config'
import { formLabel, columnsList, dialogConfig } from './config'
import { commonMixin } from '@/mixins/common.js'
import FormProject from './components/form-project'
export default {
mixins: [commonMixin], //
components: {
FormProject,
},
data() {
return {
//
formLabel,
//
columnsList,
//
dialogConfig,
}
},
methods: {
/** 新建工程 */
addProject() {
this.dialogConfig.outerTitle = '新建工程'
this.dialogConfig.outerVisible = true
},
/** 关闭弹框 */
closeDialog() {
this.dialogConfig.outerVisible = false
},
},
}
</script>