首页基础完善

This commit is contained in:
BianLzhaoMin 2025-08-08 10:18:07 +08:00
parent b06a8a696b
commit 033efb8a09
11 changed files with 2023 additions and 234 deletions

9
jsconfig.json Normal file
View File

@ -0,0 +1,9 @@
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
},
"exclude": ["node_modules"]
}

View File

@ -203,3 +203,8 @@ aside {
.mt-10 {
margin-top: 10px;
}
.cursor-blue {
color: #409EFF;
cursor: pointer;
}

View File

@ -24,6 +24,10 @@
v-if="dialogConfig.innerVisible"
:before-close="handleCloseInner"
:visible.sync="dialogConfig.innerVisible"
:style="{
'--el-dialog-min-height': dialogConfig.minHeight,
'--el-dialog-max-height': dialogConfig.maxHeight,
}"
>
<!-- 内层弹框内容 -->
<slot name="innerContent"></slot>
@ -67,12 +71,14 @@ export default {
top: 50% !important;
left: 50% !important;
transform: translate(-50%, -50%) !important;
max-height: var(--el-dialog-max-height) !important;
height: var(--el-dialog-max-height) !important;
min-height: var(--el-dialog-min-height) !important;
max-height: var(--el-dialog-max-height) !important;
.el-dialog__body {
flex: 1 !important;
overflow-y: scroll !important;
padding: 10px 20px !important;
padding: 20px 20px !important;
box-sizing: border-box !important;
}
}
</style>

View File

@ -0,0 +1,595 @@
<template>
<!-- 过滤查询组件 -->
<div class="filter-query-model">
<el-row
type="flex"
:gutter="10"
:key="item.label"
justify="space-between"
class="filter-query-item"
v-for="(item, index) in filterQueryList"
>
<el-col :span="2" class="col-left-right">
<div> {{ item.label }}: </div>
</el-col>
<el-col :span="20">
<el-radio-group
size="mini"
v-model="item.value"
@change="onHandleQuery"
:ref="`radioGroup${index}`"
>
<el-radio-button
:key="tag.value"
:label="tag.label"
v-for="tag in item.valueList"
/>
</el-radio-group>
</el-col>
<el-col :span="2">
<div
v-if="item.radioGroupHeight > item.radioGroupShowHeight"
class="is-expand"
@click="toggleExpand(index)"
>
<span>{{ item.isExpand ? '收起' : '展开' }}</span>
<i
:class="
item.isExpand
? 'el-icon-caret-top'
: 'el-icon-caret-bottom'
"
></i>
</div>
</el-col>
</el-row>
<el-row :gutter="10" class="filter-query-item-2" style="padding: 8px 0">
<el-col :span="2">
<div> 已选条件: </div>
</el-col>
<el-col :span="22">
<div>
<el-tag
closable
size="small"
effect="plain"
:key="tag.value"
:type="tag.type"
@close="onHandleClear(tag)"
v-for="tag in selectList"
style="margin-right: 10px"
>
{{ tag.label }}
</el-tag>
<el-button
type="text"
size="small"
@click="onHandleClearAll"
v-if="selectList.length > 0"
>
清除选项
</el-button>
</div>
</el-col>
</el-row>
</div>
</template>
<script>
export default {
name: 'FilterQueryModel',
props: {
isPersonFilter: {
type: Boolean,
default: false,
},
},
data() {
return {
filterQueryListTemp: [
{
label: '分公司',
value: '全部',
queryKey: 'companyId',
isPersonFilter: 'all',
radioGroupHeight: 0,
radioGroupShowHeight: 38,
isExpand: false,
valueList: [
{
label: '全部',
value: '全部',
},
{
label: '分公司1',
value: '分公司1',
},
{
label: '分公司2',
value: '分公司2',
},
{
label: '分公司3',
value: '分公司3',
},
{
label: '红灯超三天',
value: '分公司5',
},
],
},
{
label: '工程状态',
value: '全部',
queryKey: 'workStatus',
isPersonFilter: false,
radioGroupHeight: 0,
radioGroupShowHeight: 38,
isExpand: false,
valueList: [
{
label: '全部',
value: '全部',
},
{
label: '在建',
value: '在建',
},
{
label: '完工',
value: '完工',
},
{
label: '筹建',
value: '筹建',
},
{
label: '停工',
value: '停工',
},
{
label: '遗留收尾',
value: '遗留收尾',
},
],
},
{
label: '电压等级',
value: '全部',
queryKey: 'voltageLevel',
isPersonFilter: false,
radioGroupHeight: 0,
radioGroupShowHeight: 38,
isExpand: false,
valueList: [
{
label: '全部',
value: '全部',
},
{
label: '110kV',
value: '110kV',
},
{
label: '220kV',
value: '220kV',
},
{
label: '500kV',
value: '500kV',
},
{
label: '±800kV',
value: '±800kV',
},
{
label: '1000kV及以上',
value: '1000kV及以上',
},
{
label: '其它',
value: '其它',
},
],
},
{
label: '工程类型',
value: '全部',
queryKey: 'projectType',
isPersonFilter: false,
radioGroupHeight: 0,
radioGroupShowHeight: 38,
isExpand: false,
valueList: [
{
label: '全部',
value: '全部',
},
{
label: '基建线路',
value: '基建线路',
},
{
label: '基建变电',
value: '基建变电',
},
{
label: '生产线路',
value: '生产线路',
},
{
label: '生产变电',
value: '生产变电',
},
{
label: '变电改扩建',
value: '变电改扩建',
},
{
label: '其它',
value: '其它',
},
],
},
{
label: '红绿灯状态',
value: '全部',
queryKey: 'redLightStatus',
isPersonFilter: true,
radioGroupHeight: 0,
radioGroupShowHeight: 38,
isExpand: false,
valueList: [
{
label: '全部',
value: '全部',
},
{
label: '绿灯',
value: '绿灯',
},
{
label: '黄灯',
value: '黄灯',
},
{
label: '红灯',
value: '红灯',
},
{
label: '红灯超三天',
value: '红灯超三天',
},
],
},
{
label: '用工类型',
value: '全部',
queryKey: 'workType',
isPersonFilter: true,
radioGroupHeight: 0,
radioGroupShowHeight: 38,
isExpand: false,
valueList: [
{
label: '全部',
value: '全部',
},
{
label: '固定用工',
value: '固定用工',
},
{
label: '临时用工',
value: '临时用工',
},
],
},
{
label: '年龄分布',
value: '全部',
queryKey: 'ageRange',
isPersonFilter: true,
radioGroupHeight: 0,
radioGroupShowHeight: 38,
isExpand: false,
valueList: [
{
label: '全部',
value: '全部',
},
{
label: '<20',
value: '<20',
},
{
label: '20-30',
value: '20-30',
},
{
label: '30-40',
value: '30-40',
},
{
label: '40-50',
value: '40-50',
},
{
label: '50-60',
value: '50-60',
},
],
},
{
label: '性别',
value: '全部',
queryKey: 'sex',
isPersonFilter: true,
radioGroupHeight: 0,
radioGroupShowHeight: 38,
isExpand: false,
valueList: [
{
label: '全部',
value: '全部',
},
{
label: '男',
value: '男',
},
{
label: '女',
value: '女',
},
],
},
{
label: '考勤状态',
value: '全部',
queryKey: 'attendanceStatus',
isPersonFilter: true,
radioGroupHeight: 0,
radioGroupShowHeight: 38,
isExpand: false,
valueList: [
{
label: '全部',
value: '全部',
},
{
label: '已考勤',
value: '已考勤',
},
{
label: '未考勤',
value: '未考勤',
},
],
},
{
label: '作业打卡',
value: '全部',
queryKey: 'jobClock',
isPersonFilter: true,
radioGroupHeight: 0,
radioGroupShowHeight: 38,
isExpand: false,
valueList: [
{
label: '全部',
value: '全部',
},
{
label: '日计划打卡',
value: '日计划打卡',
},
{
label: '非日计划打卡',
value: '非日计划打卡',
},
],
},
{
label: '工种',
value: '全部',
queryKey: 'jobType',
isPersonFilter: true,
radioGroupHeight: 0,
radioGroupShowHeight: 38,
isExpand: false,
valueList: [
{
label: '全部',
value: '全部',
},
{
label: '项目经理(专业分包)',
value: '项目经理(专业分包)',
},
{
label: '项目总工(专业分包)',
value: '项目总工(专业分包)',
},
{
label: '专职安全员(专业分包)',
value: '专职安全员(专业分包)',
},
{
label: '专职质检员(专业分包)',
value: '专职质检员(专业分包)',
},
{
label: '项目总共(专业分包)',
value: '项目总共(专业分包)',
},
{
label: '项目总共(专业分包)',
value: '项目总共(专业分包)',
},
{
label: '项目总共(专业分包)',
value: '项目总共(专业分包)',
},
{
label: '项目总共(专业分包)',
value: '项目总共(专业分包)',
},
{
label: '项目总共(专业分包)',
value: '项目总共(专业分包)',
},
],
},
],
}
},
mounted() {
this.$nextTick(() => {
this.onHandleExpand()
})
},
methods: {
//
onHandleClear(tag) {
this.filterQueryList.forEach((item) => {
if (item.label === tag.label) {
item.value = '全部'
}
})
this.onHandleQuery()
},
//
onHandleClearAll() {
this.filterQueryList.forEach((item) => {
item.value = '全部'
})
this.onHandleQuery()
},
//
onHandleQuery() {
const query = {}
this.filterQueryList.forEach((item) => {
query[item.queryKey] = item.value
})
// 使
this.$emit('handelSettingQuery', query)
},
// /
onHandleExpand() {
this.filterQueryList.forEach((item, index) => {
const radioGroup = this.$refs[`radioGroup${index}`]
// radioGroup
const radioGroupHeight = radioGroup[0].$el.offsetHeight
item.radioGroupHeight = radioGroupHeight
item.isExpand = false
// 38px
radioGroup[0].$el.style.height = '38px'
radioGroup[0].$el.style.overflow = 'hidden'
})
},
// /
toggleExpand(index) {
const item = this.filterQueryList[index]
item.isExpand = !item.isExpand
const radioGroup = this.$refs[`radioGroup${index}`][0].$el
if (item.isExpand) {
// -
radioGroup.style.height = item.radioGroupHeight + 'px'
} else {
// - 38px
radioGroup.style.height = '38px'
}
radioGroup.style.overflow = 'hidden'
},
},
computed: {
//
filterQueryList() {
if (this.isPersonFilter) {
return this.filterQueryListTemp.filter(
(item) =>
item.isPersonFilter === true ||
item.isPersonFilter === 'all',
)
}
return this.filterQueryListTemp.filter(
(item) =>
item.isPersonFilter === false ||
item.isPersonFilter === 'all',
)
},
selectList() {
return this.filterQueryList
.filter((item) => item.value !== '全部')
.map((item) => {
return {
label: item.label,
value: item.value,
}
})
},
},
}
</script>
<style lang="scss" scoped>
.filter-query-model {
margin-bottom: 10px;
}
.filter-query-item {
border-bottom: 1px solid #e5e5e5;
padding-bottom: 8px;
}
.filter-query-item-2 {
display: flex;
align-items: center;
border-bottom: 1px solid #e5e5e5;
}
.el-radio-button {
margin-right: 10px;
}
::v-deep .el-radio-button__inner {
margin-top: 8px;
height: 30px !important;
line-height: 30px !important;
padding: 0 20px !important;
border-left: 1px solid #dcdfe6;
}
::v-deep .el-radio-button--mini .el-radio-button__inner {
padding: 0;
}
::v-deep .el-radio-group {
transition: height 0.3s ease;
}
.col-left-right {
display: flex;
align-items: center;
}
.is-expand {
margin-top: 8px;
height: 30px;
line-height: 30px;
cursor: pointer;
background-color: #f5f7fa;
text-align: center;
}
</style>

View File

@ -52,7 +52,7 @@
handleCasAdd(
$event,
item.f_model,
cascaderFunc,
cascadeFunc,
extraTableProp,
)
"
@ -98,7 +98,6 @@
type="primary"
icon="el-icon-search"
@click="handleQuery"
v-if="showSearchBtn"
>
查询
</el-button>
@ -204,83 +203,64 @@ 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,
},
sendId: {
type: Number,
default: () => null,
},
/** 是否显示查询按钮 */
showSearchBtn: {
type: Boolean,
default: true,
},
//
showBtnCrews: {
type: Boolean,
default: true,
},
cascaderFunc: {
//
cascadeFunc: {
type: Function,
default: () => null,
},
//
extraTableProp: {
type: Object,
default: () => null,
},
/** 是否显示操作列 */
//
showOperation: {
type: Boolean,
default: true,
default: false,
},
/** 是否显示右侧工具栏 */
//
showRightTools: {
type: Boolean,
default: true,
default: false,
},
//
selectable: {
type: Function,
default: () => {
return true
},
},
selSingle: {
//
isSelectShow: {
type: Boolean,
default: false,
},
showIndex: {
type: Boolean,
default: true,
},
//
isSelectShow: {
type: Boolean,
default: true,
},
// 使
// 使
testTableList: {
type: Array,
default: () => [],

View File

@ -8,8 +8,12 @@ import cache from '@/plugins/cache'
import { saveAs } from 'file-saver'
import { decryptWithSM4, encryptWithSM4, hashWithSM3AndSalt } from '@/utils/sm'
const systemConfig = JSON.parse(localStorage.getItem('systemConfig')) || {
requestConfig: { encryptRequest: false, checkIntegrity: false, encryptResponse: false }
};
requestConfig: {
encryptRequest: false,
checkIntegrity: false,
encryptResponse: false,
},
}
let downloadLoadingInstance
// 是否显示重新登录
@ -19,169 +23,224 @@ axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
// axios中请求配置有baseURL选项表示请求URL公共部分
baseURL: process.env.VUE_APP_BASE_API,
// 超时
timeout: 10000
// axios中请求配置有baseURL选项表示请求URL公共部分
baseURL: process.env.VUE_APP_BASE_API,
// 超时
timeout: 100,
})
// request 拦截器
service.interceptors.request.use(config => {
// 提取 headers 和方法
const headers = config.headers || {}
const {
isToken = true,
encryptRequest = true,
checkIntegrity = true,
encryptResponse = true,
repeatSubmit = false
} = headers
service.interceptors.request.use(
(config) => {
// 提取 headers 和方法
const headers = config.headers || {}
const {
isToken = true,
encryptRequest = true,
checkIntegrity = true,
encryptResponse = true,
repeatSubmit = false,
} = headers
// 设置请求头
//入参加密
config.headers['encryptRequest'] = systemConfig.requestConfig.encryptRequest && encryptRequest ? 'true' : 'false'
// 数据完整性校验
config.headers['checkIntegrity'] = systemConfig.requestConfig.checkIntegrity && checkIntegrity ? 'true' : 'false'
//回参是否加密
config.headers['encryptResponse'] = systemConfig.requestConfig.encryptResponse && encryptResponse ? 'true' : 'false'
// 设置请求头
//入参加密
config.headers['encryptRequest'] =
systemConfig.requestConfig.encryptRequest && encryptRequest
? 'true'
: 'false'
// 数据完整性校验
config.headers['checkIntegrity'] =
systemConfig.requestConfig.checkIntegrity && checkIntegrity
? 'true'
: 'false'
//回参是否加密
config.headers['encryptResponse'] =
systemConfig.requestConfig.encryptResponse && encryptResponse
? 'true'
: 'false'
const isRepeatSubmit = repeatSubmit
// 处理 Token
if (getToken() && isToken) {
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义 token
}
const isRepeatSubmit = repeatSubmit
// 处理 Token
if (getToken() && isToken) {
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义 token
}
// get请求映射params参数
if (config.method === 'get' && config.params) {
let url = config.url + '?' + tansParams(config.params);
url = url.slice(0, -1);
config.params = {};
config.url = url;
}
// get请求映射params参数
if (config.method === 'get' && config.params) {
let url = config.url + '?' + tansParams(config.params)
url = url.slice(0, -1)
config.params = {}
config.url = url
}
if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
let data = typeof config.data === 'object' ? JSON.stringify(config.data) : config.data
let contentType = config.headers['Content-Type']
if (contentType.includes('application/json') && typeof data !== 'undefined') {
// 加密数据
if (systemConfig.requestConfig.encryptRequest && encryptRequest) {
console.log(data);
console.log(hashWithSM3AndSalt(data));
config.data = encryptWithSM4(data+"|"+hashWithSM3AndSalt(data))
}
}
// 检查请求数据大小
const requestSize = JSON.stringify({ url: config.url, data: data, time: Date.now() }).length
const limitSize = 1000 * 1024 * 1024 // 限制存放数据 5MB
if (
!isRepeatSubmit &&
(config.method === 'post' || config.method === 'put')
) {
let data =
typeof config.data === 'object'
? JSON.stringify(config.data)
: config.data
let contentType = config.headers['Content-Type']
if (
contentType.includes('application/json') &&
typeof data !== 'undefined'
) {
// 加密数据
if (
systemConfig.requestConfig.encryptRequest &&
encryptRequest
) {
console.log(data)
console.log(hashWithSM3AndSalt(data))
config.data = encryptWithSM4(
data + '|' + hashWithSM3AndSalt(data),
)
}
}
// 检查请求数据大小
const requestSize = JSON.stringify({
url: config.url,
data: data,
time: Date.now(),
}).length
const limitSize = 1000 * 1024 * 1024 // 限制存放数据 5MB
if (requestSize >= limitSize) {
console.warn(`[${config.url}]: 请求数据大小超出允许的5MB限制无法进行防重复提交验证。`)
return config
}
// 防止重复提交
const sessionObj = cache.session.getJSON('sessionObj') || {}
const requestObj = { url: config.url, data: data, time: Date.now() }
if (requestSize >= limitSize) {
console.warn(
`[${config.url}]: 请求数据大小超出允许的5MB限制无法进行防重复提交验证。`,
)
return config
}
// 防止重复提交
const sessionObj = cache.session.getJSON('sessionObj') || {}
const requestObj = { url: config.url, data: data, time: Date.now() }
if (sessionObj.data === requestObj.data && requestObj.time - sessionObj.time < 0 && sessionObj.url === requestObj.url) {
console.warn(`[${sessionObj.url}]: 数据正在处理,请勿重复提交`)
return Promise.reject(new Error('数据正在处理,请勿重复提交'))
}
cache.session.setJSON('sessionObj', requestObj)
}
return config
}, error => {
console.error(error)
return Promise.reject(error)
})
if (
sessionObj.data === requestObj.data &&
requestObj.time - sessionObj.time < 0 &&
sessionObj.url === requestObj.url
) {
console.warn(`[${sessionObj.url}]: 数据正在处理,请勿重复提交`)
return Promise.reject(new Error('数据正在处理,请勿重复提交'))
}
cache.session.setJSON('sessionObj', requestObj)
}
return config
},
(error) => {
console.error(error)
return Promise.reject(error)
},
)
// 响应拦截器
service.interceptors.response.use(res => {
if (res.headers.encryptresponse && !res.data.hasOwnProperty('code')) {
res.data = JSON.parse(decryptWithSM4(res.data))
}
// 未设置状态码则默认成功状态
const code = res.data.code || 200
// 获取错误信息
const msg = errorCode[code] || res.data.msg || errorCode['default']
// 二进制数据则直接返回
if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
return res.data
}
if (code === 401) {
if (!isRelogin.show) {
isRelogin.show = true
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
isRelogin.show = false
store.dispatch('LogOut').then(() => {
location.href = '/index'
})
}).catch(() => {
isRelogin.show = false
})
}
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
} else if (code === 500) {
Message({ message: msg, type: 'error' })
return Promise.reject(new Error(msg))
} else if (code === 601) {
Message({ message: msg, type: 'warning' })
return Promise.reject('error')
} else if (code !== 200) {
Notification.error({ title: msg })
return Promise.reject('error')
} else {
return res.data
}
},
error => {
let { message } = error
if (message == 'Network Error') {
message = '后端接口连接异常'
} else if (message.includes('timeout')) {
message = '系统接口请求超时'
} else if (message.includes('Request failed with status code')) {
message = '系统接口' + message.substr(message.length - 3) + '异常'
}
Message({ message: message, type: 'error', duration: 5 * 1000 })
return Promise.reject(error)
}
service.interceptors.response.use(
(res) => {
if (res.headers.encryptresponse && !res.data.hasOwnProperty('code')) {
res.data = JSON.parse(decryptWithSM4(res.data))
}
// 未设置状态码则默认成功状态
const code = res.data.code || 200
// 获取错误信息
const msg = errorCode[code] || res.data.msg || errorCode['default']
// 二进制数据则直接返回
if (
res.request.responseType === 'blob' ||
res.request.responseType === 'arraybuffer'
) {
return res.data
}
if (code === 401) {
if (!isRelogin.show) {
isRelogin.show = true
MessageBox.confirm(
'登录状态已过期,您可以继续留在该页面,或者重新登录',
'系统提示',
{
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning',
},
)
.then(() => {
isRelogin.show = false
store.dispatch('LogOut').then(() => {
location.href = '/index'
})
})
.catch(() => {
isRelogin.show = false
})
}
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
} else if (code === 500) {
Message({ message: msg, type: 'error' })
return Promise.reject(new Error(msg))
} else if (code === 601) {
Message({ message: msg, type: 'warning' })
return Promise.reject('error')
} else if (code !== 200) {
Notification.error({ title: msg })
return Promise.reject('error')
} else {
return res.data
}
},
(error) => {
let { message } = error
if (message == 'Network Error') {
message = '后端接口连接异常'
} else if (message.includes('timeout')) {
message = '系统接口请求超时'
} else if (message.includes('Request failed with status code')) {
message = '系统接口' + message.substr(message.length - 3) + '异常'
}
Message({ message: message, type: 'error', duration: 5 * 1000 })
return Promise.reject(error)
},
)
// 通用下载方法
export function download(url, params, filename, config) {
downloadLoadingInstance = Loading.service({
text: '正在下载数据,请稍候',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
return service.post(url, params, {
transformRequest: [(params) => {
return tansParams(params)
}],
headers: { 'Content-Type': 'application/x-www-form-urlencoded', encryptResponse: false},
responseType: 'blob',
...config
}).then(async(data) => {
const isBlob = blobValidate(data)
if (isBlob) {
const blob = new Blob([data])
saveAs(blob, filename)
} else {
const resText = await data.text()
const rspObj = JSON.parse(resText)
const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
Message.error(errMsg)
}
downloadLoadingInstance.close()
}).catch((r) => {
console.error(r)
Message.error('下载文件出现错误,请联系管理员!')
downloadLoadingInstance.close()
})
downloadLoadingInstance = Loading.service({
text: '正在下载数据,请稍候',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)',
})
return service
.post(url, params, {
transformRequest: [
(params) => {
return tansParams(params)
},
],
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
encryptResponse: false,
},
responseType: 'blob',
...config,
})
.then(async (data) => {
const isBlob = blobValidate(data)
if (isBlob) {
const blob = new Blob([data])
saveAs(blob, filename)
} else {
const resText = await data.text()
const rspObj = JSON.parse(resText)
const errMsg =
errorCode[rspObj.code] || rspObj.msg || errorCode['default']
Message.error(errMsg)
}
downloadLoadingInstance.close()
})
.catch((r) => {
console.error(r)
Message.error('下载文件出现错误,请联系管理员!')
downloadLoadingInstance.close()
})
}
export default service

View File

@ -0,0 +1,55 @@
<template>
<!-- 人数展示 公共组件 -->
<div>
<!-- 在场固定临时数量 -->
<template v-if="slotName === 'onSiteCount'">
<span
class="cursor-blue"
@click="onHandleCheckPersonCount(rowData)"
>
{{ rowData.line }} /{{ rowData.fixed }} /{{ rowData.temporary }}
</span>
</template>
<!-- 今日考勤人数 -->
<template v-else-if="slotName === 'todayAttendanceCount'">
<span
class="cursor-blue"
@click="onHandleCheckPersonCount(rowData)"
>
{{ rowData.todayAttendanceCount }}
</span>
</template>
<!-- 红绿灯人员 -->
<template v-else-if="slotName === 'redLightCount'">
<span style="color: #f56c6c"> {{ rowData.redCount }}</span>
<br />
<span style="color: #e6a23c"> {{ rowData.yellowCount }}</span>
<br />
<span style="color: #67c23a">绿 {{ rowData.greenCount }}</span>
</template>
</div>
</template>
<script>
export default {
name: 'PersonCount',
props: {
slotName: {
type: String,
required: true,
},
rowData: {
type: Object,
required: true,
},
},
methods: {
onHandleCheckPersonCount(data) {
console.log('查看人员数量', data)
this.$emit('handleCheckPersonCount', data)
},
},
}
</script>

View File

@ -0,0 +1,329 @@
// 总工程列表子项目概况列表上方查询条件
// 总工程列表和分包信息列表公共字段
const commonColumnsList = [
{
t_props: 'onSiteCount',
t_label: '在场/固定/临时人数',
t_slot: 'onSiteCount',
},
{
t_props: 'todayAttendanceCount',
t_label: '今日考勤人数',
t_slot: 'todayAttendanceCount',
},
{
t_props: 'redLightCount',
t_label: '红绿灯人员',
t_slot: 'redLightCount',
},
]
// 总工程列表和分包信息列表公共字段
const commonColumnsListTwo = [
{ t_props: 'projectCount', t_label: '所在工程' },
{ t_props: 'projectCount', t_label: '所属分公司' },
]
export const allProjectFormLabel = [
{
f_label: '工程名称',
f_model: 'projectName',
f_type: 'ipt',
isShow: false, // 是否展示label
},
]
// 总工程列表字段
export const allProjectColumnsList = [
{ t_props: 'projectName', t_label: '总工程名称' },
{
t_props: 'projectCount',
t_label: '标段工程数量',
t_slot: 'projectCount',
},
]
// 子项目概况列表字段
export const childColumnsList = [
{ t_props: 'projectName', t_label: '分公司' },
{ t_props: 'projectCount', t_label: '工程名称' },
{
t_props: 'subCount',
t_label: '分包数量',
t_slot: 'subCount',
},
{
t_props: 'teamCount',
t_label: '班组数量',
t_slot: 'teamCount',
},
...commonColumnsList,
{ t_props: 'projectCount', t_label: '电压等级' },
{ t_props: 'projectCount', t_label: '工程类型' },
{ t_props: 'projectCount', t_label: '工程状态' },
]
// 分包信息列表上方查询条件
export const subFormLabel = [
{
f_label: '分包名称',
f_model: 'projectName',
f_type: 'ipt',
isShow: false, // 是否展示label
},
{
f_label: '工程名称',
f_model: 'projectName',
f_type: 'ipt',
isShow: false, // 是否展示label
},
{
f_label: '分公司名称',
f_model: 'projectName',
f_type: 'ipt',
isShow: false, // 是否展示label
},
]
// 分包信息列表字段
export const subColumnsList = [
{ t_props: 'projectName', t_label: '分包名称' },
{
t_props: 'teamCount',
t_label: '在场班组数量',
t_slot: 'teamCount',
},
...commonColumnsList,
...commonColumnsListTwo,
]
// 班组信息列表上方查询条件
export const teamFormLabel = [
{
f_label: '班组名称',
f_model: 'projectName',
f_type: 'ipt',
isShow: false, // 是否展示label
},
{
f_label: '分包名称',
f_model: 'projectName',
f_type: 'ipt',
isShow: false, // 是否展示label
},
{
f_label: '工程名称',
f_model: 'projectName',
f_type: 'ipt',
isShow: false, // 是否展示label
},
{
f_label: '分公司名称',
f_model: 'projectName',
f_type: 'ipt',
isShow: false, // 是否展示label
},
]
// 班组信息列表字段
export const teamColumnsList = [
{ t_props: 'projectName', t_label: '班组名称' },
...commonColumnsList,
{ t_props: 'projectCount', t_label: '所属分包商' },
...commonColumnsListTwo,
]
// 人员信息列表上方查询条件
export const personFormLabel = [
{
f_label: '姓名',
f_model: 'projectName',
f_type: 'ipt',
isShow: false, // 是否展示label
},
{
f_label: '分包工程',
f_model: 'projectName',
f_type: 'ipt',
isShow: false, // 是否展示label
},
{
f_label: '工程名称',
f_model: 'projectName',
f_type: 'ipt',
isShow: false, // 是否展示label
},
]
// 人员信息列表字段
export const personColumnsList = [
{ t_props: 'userName', t_label: '姓名', t_slot: 'userName' },
{ t_props: 'projectName', t_label: '工种' },
{
t_props: 'redLightStatus',
t_label: '红绿灯状态',
t_slot: 'redLightStatus',
},
{ t_props: 'projectName', t_label: '考勤状态' },
{ t_props: 'projectName', t_label: '性别' },
{ t_props: 'projectName', t_label: '年龄' },
{ t_props: 'projectName', t_label: '联系方式' },
{ t_props: 'projectName', t_label: '所属分包' },
{ t_props: 'projectName', t_label: '所属工程' },
]
// 弹框公共配置
const dialogCommonConfig = {
outerVisible: false,
outerTitle: '',
minHeight: '90vh',
maxHeight: '90vh',
}
// 子项目概况弹框配置
export const dialogConfig = {
outerWidth: '90%',
...dialogCommonConfig,
}
// 分包弹框配置
export const dialogConfigTwo = {
outerWidth: '80%',
...dialogCommonConfig,
}
// 班组弹框配置
export const dialogConfigThree = {
outerWidth: '80%',
...dialogCommonConfig,
}
// 人员弹框配置
export const dialogConfigFour = {
outerWidth: '80%',
...dialogCommonConfig,
}
// 人员详情弹框配置
export const dialogConfigFive = {
outerWidth: '75%',
...dialogCommonConfig,
}
// 总工程列表测试数据
export const allProjectTestTableList = [
{
projectName: '测试工程1',
projectCount: 10,
},
{
projectName: '测试工程2',
projectCount: 20,
},
{
projectName: '测试工程3',
projectCount: 20,
},
]
// 子项目概况列表测试数据
export const childTestTableList = [
{
projectName: '测试工程1',
projectCount: 10,
subCount: 10,
teamCount: 10,
onSiteCount: 10,
todayAttendanceCount: 10,
redLightCount: 10,
line: 12,
fixed: 13,
temporary: 14,
redCount: 15,
yellowCount: 16,
greenCount: 17,
},
{
projectName: '测试工程2',
projectCount: 10,
subCount: 10,
teamCount: 10,
onSiteCount: 10,
todayAttendanceCount: 10,
redLightCount: 10,
line: 12,
fixed: 13,
temporary: 14,
redCount: 15,
yellowCount: 16,
greenCount: 17,
},
]
// 分包信息列表测试数据
export const subTestTableList = [
{
projectName: '测试工程1',
projectCount: 10,
teamCount: 10,
onSiteCount: 10,
todayAttendanceCount: 10,
redLightCount: 10,
line: 12,
fixed: 13,
temporary: 14,
redCount: 15,
yellowCount: 16,
greenCount: 17,
},
]
// 班组信息列表测试数据
export const teamTestTableList = [
{
projectName: '测试工程1',
projectCount: 10,
teamCount: 10,
onSiteCount: 10,
todayAttendanceCount: 10,
redLightCount: 10,
line: 12,
fixed: 13,
temporary: 14,
redCount: 15,
yellowCount: 16,
greenCount: 17,
},
]
// 人员信息列表测试数据
export const personTestTableList = [
{
userName: '张三',
redLightStatus: '红灯',
projectCount: 10,
teamCount: 10,
onSiteCount: 10,
todayAttendanceCount: 10,
redLightCount: 10,
line: 12,
fixed: 13,
temporary: 14,
redCount: 15,
yellowCount: 16,
greenCount: 17,
},
{
userName: '李思思',
redLightStatus: '绿灯',
projectCount: 10,
teamCount: 10,
onSiteCount: 10,
todayAttendanceCount: 10,
redLightCount: 10,
line: 12,
fixed: 13,
temporary: 14,
redCount: 15,
yellowCount: 16,
greenCount: 17,
},
]

View File

@ -2,14 +2,11 @@
<!-- item1 总工程信息 -->
<div class="item-one">
<TableModel
ref="tableRef"
:isSelectShow="false"
:showRightTools="false"
:showOperation="false"
:formLabel="formLabel"
:columnsList="columnsList"
:testTableList="testTableList"
ref="allProjectTableRef"
:formLabel="allProjectFormLabel"
:columnsList="allProjectColumnsList"
:request-api="getAllProjectListAPI"
:testTableList="allProjectTestTableList"
>
<template slot="btn" slot-scope="{ queryParams }">
<el-button
@ -23,70 +20,325 @@
<!-- 工程数量 -->
<template slot="projectCount" slot-scope="{ data }">
<span
style="cursor: pointer; color: #409eff"
class="cursor-blue"
@click="onHandleCheckProjectCount(data)"
>
{{ data.projectCount }}
</span>
</template>
</TableModel>
<!-- 子项目概况弹框-->
<DialogModel
:dialogConfig="dialogConfig"
@closeDialogOuter="handleCloseDialogOuter"
>
<!-- 外层弹框 -->
<template slot="outerContent">
<FilterQueryModel @handelSettingQuery="handelSettingQuery" />
<TableModel
ref="tableRef"
:formLabel="allProjectFormLabel"
:columnsList="childColumnsList"
:testTableList="childTestTableList"
:request-api="getAllProjectListAPI"
>
<!-- 分包数量 -->
<template slot="subCount" slot-scope="{ data }">
<span
class="cursor-blue"
@click="onHandleCheckSubCount(data)"
>
{{ data.projectCount }}
</span>
</template>
<!-- 班组数量 -->
<template slot="teamCount" slot-scope="{ data }">
<span class="cursor-blue">
{{ data.teamCount }}
</span>
</template>
<template
:slot="item"
slot-scope="{ data }"
v-for="item in commonSlots"
>
<CommonTableSlots
:key="item"
:rowData="data"
:slotName="item"
@handleCheckPersonCount="handleCheckPersonCount"
/>
</template>
</TableModel>
</template>
</DialogModel>
<!-- 分包信息弹框 -->
<DialogModel
:dialogConfig="dialogConfigTwo"
@closeDialogOuter="handleCloseDialogOuterTwo"
>
<!-- 外层弹框 -->
<template slot="outerContent">
<TableModel
ref="subTableRef"
:formLabel="subFormLabel"
:columnsList="subColumnsList"
:testTableList="subTestTableList"
:request-api="getAllProjectListAPI"
>
<!-- 在场班组数量 -->
<template slot="teamCount" slot-scope="{ data }">
<span
class="cursor-blue"
@click="onHandleCheckTeamCount(data)"
>
{{ data.teamCount }}
</span>
</template>
<template
:slot="item"
slot-scope="{ data }"
v-for="item in commonSlots"
>
<CommonTableSlots
:key="item"
:rowData="data"
:slotName="item"
@handleCheckPersonCount="handleCheckPersonCount"
/>
</template>
</TableModel>
</template>
</DialogModel>
<!-- 从班组信息弹框 -->
<DialogModel
:dialogConfig="dialogConfigThree"
@closeDialogOuter="handleCloseDialogOuterThree"
>
<template slot="outerContent">
<TableModel
ref="teamTableRef"
:formLabel="teamFormLabel"
:columnsList="teamColumnsList"
:testTableList="teamTestTableList"
:request-api="getAllProjectListAPI"
>
<template
:slot="item"
slot-scope="{ data }"
v-for="item in commonSlots"
>
<CommonTableSlots
:key="item"
:rowData="data"
:slotName="item"
@handleCheckPersonCount="handleCheckPersonCount"
/>
</template>
</TableModel>
</template>
</DialogModel>
<!-- 人员信息弹框 -->
<DialogModel
:dialogConfig="dialogConfigFour"
@closeDialogOuter="handleCloseDialogOuterFour"
>
<template slot="outerContent">
<FilterQueryModel
:isPersonFilter="true"
@handelSettingQuery="handelSettingQuery"
/>
<TableModel
ref="personTableRef"
:formLabel="personFormLabel"
:columnsList="personColumnsList"
:testTableList="personTestTableList"
:request-api="getAllProjectListAPI"
>
<!-- 人员姓名 -->
<template slot="userName" slot-scope="{ data }">
<span
class="cursor-blue"
@click="onHandleCheckUserName(data)"
>
{{ data.userName }}
</span>
</template>
<!-- 红绿灯状态 -->
<template slot="redLightStatus" slot-scope="{ data }">
<span
style="
color: #ff0000;
font-size: 14px;
cursor: pointer;
"
>
红灯
</span>
</template>
</TableModel>
</template>
</DialogModel>
<!-- 人员详情弹框 -->
<DialogModel
:dialogConfig="dialogConfigFive"
@closeDialogOuter="handleCloseDialogOuterFive"
>
<template slot="outerContent">
<PersonDetails />
</template>
</DialogModel>
</div>
</template>
<script>
import TableModel from '@/components/TableModel'
import DialogModel from '@/components/DialogModel'
import FilterQueryModel from '@/components/FilterQueryModel'
import CommonTableSlots from './common-table-slots'
import PersonDetails from './person-details'
import { getAllProjectListAPI } from '@/api/home-index/dataOverviewProject' //
import {
//
allProjectFormLabel,
allProjectColumnsList,
allProjectTestTableList,
//
childColumnsList,
childTestTableList,
//
subFormLabel,
subColumnsList,
subTestTableList,
//
teamFormLabel,
teamColumnsList,
teamTestTableList,
//
personFormLabel,
personColumnsList,
personTestTableList,
//
dialogConfig,
dialogConfigTwo,
dialogConfigThree,
dialogConfigFour,
dialogConfigFive,
} from './config'
export default {
name: 'ItemOne',
components: {
TableModel,
DialogModel,
FilterQueryModel,
CommonTableSlots,
PersonDetails,
},
data() {
return {
formLabel: [
{
f_label: '工程名称',
f_model: 'projectName',
f_type: 'ipt',
isShow: false, // label
},
],
columnsList: [
{ t_props: 'projectName', t_label: '总工程名称' },
{
t_props: 'projectCount',
t_label: '标段工程数量',
t_slot: 'projectCount',
},
],
testTableList: [
{
projectName: '测试工程1',
projectCount: 10,
},
{
projectName: '测试工程2',
projectCount: 20,
},
{
projectName: '测试工程3',
projectCount: 20,
},
],
allProjectFormLabel,
allProjectColumnsList,
allProjectTestTableList,
childColumnsList,
childTestTableList,
subFormLabel,
subColumnsList,
subTestTableList,
teamFormLabel,
teamColumnsList,
teamTestTableList,
personFormLabel,
personColumnsList,
personTestTableList,
dialogConfig,
dialogConfigTwo,
dialogConfigThree,
dialogConfigFour,
dialogConfigFive,
getAllProjectListAPI,
queryParams: {},
commonSlots: [
'onSiteCount',
'todayAttendanceCount',
'redLightCount',
],
}
},
methods: {
//
onHandleCheckProjectCount(data) {
console.log(data)
this.dialogConfig.outerTitle = '工程信息'
this.dialogConfig.outerVisible = true
},
//
handleExport(queryParams) {
console.log('导出', queryParams)
},
//
handleCloseDialogOuter(value) {
this.dialogConfig.outerVisible = value
},
//
handleCloseDialogOuterTwo(value) {
this.dialogConfigTwo.outerVisible = value
},
//
handleCloseDialogOuterThree(value) {
this.dialogConfigThree.outerVisible = value
},
//
handleCloseDialogOuterFour(value) {
this.dialogConfigFour.outerVisible = value
},
//
handleCloseDialogOuterFive(value) {
this.dialogConfigFive.outerVisible = value
},
//
handelSettingQuery(query) {
console.log('筛选条件', query)
this.queryParams = query
},
//
onHandleCheckSubCount(data) {
console.log('查看分包数量', data)
this.dialogConfigTwo.outerTitle = '分包信息'
this.dialogConfigTwo.outerVisible = true
},
//
onHandleCheckTeamCount(data) {
console.log('查看班组数量', data)
this.dialogConfigThree.outerTitle = '班组信息'
this.dialogConfigThree.outerVisible = true
},
//
handleCheckPersonCount(data) {
console.log('查看人员信息', data)
this.dialogConfigFour.outerTitle = '人员信息'
this.dialogConfigFour.outerVisible = true
},
//
onHandleCheckUserName(data) {
console.log('查看人员详情', data)
this.dialogConfigFive.outerTitle = '人员详情'
this.dialogConfigFive.outerVisible = true
},
},
}
</script>
<style></style>

View File

@ -0,0 +1,501 @@
<template>
<!-- 人员详情 -->
<div class="person-details">
<TitleTip :titleText="'基本信息'" />
<el-row class="basic-info" :gutter="10">
<el-col :span="4" style="height: 100%">
<div class="basic-info-item">
<el-image
style="width: 80%; height: 180px"
:src="url"
fit="cover"
/>
</div>
</el-col>
<el-col :span="8" style="height: 100%">
<div class="basic-info-item">
<el-row
:gutter="10"
v-for="item in leftInfoList"
:key="item.label"
>
<el-col :span="5">
<div class="basic-info-item-label">
{{ item.label }}
</div>
</el-col>
<el-col :span="19">
<div class="basic-info-item-value">
{{ item.value }}
</div>
</el-col>
</el-row>
</div>
</el-col>
<el-col :span="10" style="height: 100%">
<div class="basic-info-item">
<el-row
:gutter="10"
v-for="item in rightInfoList"
:key="item.label"
>
<el-col :span="5">
<div class="basic-info-item-label">
{{ item.label }}
</div>
</el-col>
<el-col :span="19">
<div class="basic-info-item-value">
{{ item.value }}
</div>
</el-col>
</el-row>
</div>
</el-col>
<!-- 红绿灯图片 -->
<el-image
fit="cover"
class="light-img"
@click="handleClickLightImg"
style="width: 80px; height: 80px"
src="http://112.29.103.165:1616/bmw/img/work/indexScreen/greenLamp.png"
/>
</el-row>
<TitleTip :titleText="'考勤信息'" />
<div class="attendance-info">
<el-row :gutter="10">
<el-col :span="12">
<div>
<el-row
:gutter="10"
:key="item.label"
class="common-row"
v-for="item in attendanceLeftList"
>
<el-col :span="8">
<div class="basic-info-item-label">
{{ item.label }}
</div>
</el-col>
<el-col :span="16">
<div class="basic-info-item-value">
{{ item.value }}
</div>
</el-col>
</el-row>
</div>
</el-col>
<el-col :span="12">
<div>
<el-row
:gutter="10"
:key="item.label"
class="common-row"
v-for="item in attendanceRightList"
>
<el-col :span="8">
<div class="basic-info-item-label">
{{ item.label }}
</div>
</el-col>
<el-col :span="16">
<div class="basic-info-item-value">
{{ item.value }}
</div>
</el-col>
</el-row>
</div>
</el-col>
</el-row>
</div>
<TitleTip :titleText="'合同信息'" />
<div class="contract-info">
<el-row :gutter="10">
<el-col :span="12">
<div>
<el-row
:gutter="10"
:key="item.label"
class="common-row"
v-for="item in contractLeftList"
>
<el-col :span="8">
<div class="basic-info-item-label">
{{ item.label }}
</div>
</el-col>
<el-col :span="16">
<div
class="basic-info-item-value"
v-if="item.label !== '合同附件'"
>
{{ item.value }}
</div>
<div class="basic-info-item-value" v-else>
<el-button
type="text"
@click="handleClickContractAttachment"
>
{{ item.value }}
</el-button>
</div>
</el-col>
</el-row>
</div>
</el-col>
<el-col :span="12">
<div>
<el-row
:gutter="10"
:key="item.label"
class="common-row"
v-for="item in contractRightList"
>
<el-col :span="8">
<div class="basic-info-item-label">
{{ item.label }}
</div>
</el-col>
<el-col :span="16">
<div class="basic-info-item-value">
{{ item.value }}
</div>
</el-col>
</el-row>
</div>
</el-col>
</el-row>
</div>
<!-- 红绿灯详情弹框 -->
<DialogModel
:dialogConfig="dialogConfig"
@closeDialogOuter="handleCloseDialogOuter"
>
<template slot="outerContent">
<div class="light-img-detail">
<div class="light-1">
<span> 当前状态 </span>
<span :style="{ color: textColor }"> 黄灯 </span>
</div>
<div class="light-2">
<i
class="el-icon-warning"
style="color: #ff3b30; font-size: 32px"
/>
<span> 合同见证 </span>
<span> 未上传 </span>
</div>
<div class="light-2" style="background-color: #e3f7e3">
<i
class="el-icon-warning"
style="color: #67c23a; font-size: 32px"
/>
<span> 工资卡见证 </span>
<span style="background-color: #67c23a; color: #fff">
已上传
</span>
</div>
<div class="light-3">
<div>
1.黄灯状态合同见证工资卡见证未全部上传
</div>
<div> 2.红灯状态合同见证工资卡见证已上传 </div>
</div>
</div>
</template>
</DialogModel>
<!-- 合同附件弹框 -->
<DialogModel
:dialogConfig="dialogConfigTwo"
@closeDialogOuter="handleCloseDialogOuterTwo"
>
<template slot="outerContent">
<div class="contract-attachment-detail">
<div
:key="index"
v-for="(item, index) in contractAttachmentList"
class="contract-attachment-item"
>
<el-image
:src="url"
style="width: 100%; height: 200px"
:preview-src-list="contractAttachmentList"
/>
</div>
</div>
<div class="upload-time"> 上传时间2025-05-06 101010 </div>
</template>
</DialogModel>
</div>
</template>
<script>
import DialogModel from '@/components/DialogModel'
export default {
name: 'PersonDetails',
components: {
DialogModel,
},
data() {
return {
url: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg',
leftInfoList: [
{
label: '姓名',
value: '张三',
},
{
label: '工种',
value: '高空作业人员',
},
{
label: '所在分包',
value: '云南清辉建设有限公司',
},
{
label: '所在工程',
value: '安徽省合肥市蜀山区---xxx110kV工程',
},
],
rightInfoList: [
{
label: '红绿灯状态',
value: '黄灯',
},
{
label: '联系方式',
value: '15656235623',
},
{
label: '所属班组',
value: '云南清辉建设有限公司----李元霸班组',
},
{
label: '入场时间',
value: '2025-05-06 101010',
},
],
attendanceLeftList: [
{
label: '打卡时间',
value: '2025-05-06 101010',
},
{
label: '考勤机编号',
value: 'MMK1234567890',
},
],
attendanceRightList: [
{
label: '考勤机所属工程',
value: '220kV输变电工程',
},
{
label: '考勤机名称',
value: '张三的考勤机',
},
],
contractLeftList: [
{
label: '合同编号',
value: '20250506101010',
},
{
label: '合同签订日期',
value: '2020-12-30',
},
{
label: '工资核定方式',
value: '按天',
},
{
label: '合同附件',
value: '合同附件',
},
],
contractRightList: [
{
label: '合同期限类型',
value: '已完成一定工作为期限的合同',
},
{
label: '合同终止日期',
value: '2020-12-30',
},
{
label: '工资核定标准',
value: '320元',
},
],
dialogConfig: {
outerVisible: false,
outerTitle: '红绿灯详情',
minHeight: '50vh',
maxHeight: '50vh',
},
dialogConfigTwo: {
outerVisible: false,
outerWidth: '70%',
outerTitle: '合同附件',
minHeight: '70vh',
maxHeight: '70vh',
},
lightType: 'yellow',
//
contractAttachmentList: [
'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg',
'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg',
'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg',
'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg',
],
}
},
methods: {
handleClickLightImg() {
this.dialogConfig.outerVisible = true
},
handleCloseDialogOuter() {
this.dialogConfig.outerVisible = false
},
handleClickContractAttachment() {
this.dialogConfigTwo.outerVisible = true
},
handleCloseDialogOuterTwo() {
this.dialogConfigTwo.outerVisible = false
},
},
computed: {
textColor() {
if (this.lightType === 'yellow') {
return '#e6a23c'
} else if (this.lightType === 'red') {
return '#f56c6c'
} else if (this.lightType === 'green') {
return '#67c23a'
}
},
},
}
</script>
<style lang="scss" scoped>
.basic-info {
height: 180px;
position: relative;
.basic-info-item {
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.light-img {
position: absolute;
top: 0;
right: 10px;
cursor: pointer;
}
}
.basic-info-item-label {
font-size: 14px;
color: #999;
text-align: right;
}
.basic-info-item-value {
padding-left: 8px;
font-size: 14px;
color: #000;
text-align: left;
}
.common-row {
padding: 12px 0;
}
.light-img-detail {
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
}
.light-1 {
font-size: 20px;
color: #000;
font-weight: bold;
}
.light-2 {
min-width: 420px;
display: flex;
align-items: center;
font-weight: bold;
background-color: #fae0e3;
padding: 12px 10px;
border-radius: 10px;
& span:nth-child(2) {
margin-left: 10px;
font-size: 18px;
color: #ff3b30;
flex: 1;
}
& span:nth-child(3) {
padding: 6px 12px;
margin-right: 18px;
color: #fff;
background-color: #ff3b30;
border-radius: 4px;
}
}
.light-3 {
width: 100%;
color: #ff3b30;
font-weight: bold;
text-align: left;
& div:last-child {
text-indent: 2em;
}
}
.contract-attachment-detail {
display: flex;
flex-wrap: wrap;
.contract-attachment-item {
width: calc((100% - 30px) / 3);
margin-right: 15px;
height: 200px;
background-color: #f5f7fa;
border-radius: 4px;
margin-bottom: 15px;
}
& .contract-attachment-item:nth-child(3n) {
margin-right: 0;
}
}
.upload-time {
margin-top: 10px;
font-size: 20px;
color: #000;
font-weight: bold;
text-align: center;
}
</style>

View File

@ -2,11 +2,9 @@
<!-- 常用功能 -->
<div class="often-use">
<el-card>
<div>
<TitleTip :titleText="'常用功能'">
<i class="el-icon-setting" @click="onHandleSetting" />
</TitleTip>
</div>
<TitleTip :titleText="'常用功能'">
<i class="el-icon-setting" @click="onHandleSetting" />
</TitleTip>
<div class="often-user-content">
<div
:key="item.name"