增加考勤机管理页面
This commit is contained in:
parent
d8639e758d
commit
7733815782
|
|
@ -0,0 +1,117 @@
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 获取工程和考勤机树形数据
|
||||||
|
export function getProjectAndMacTreeAPI() {
|
||||||
|
return request({
|
||||||
|
url: '/bmw/kqManager/getProKqjTree',
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据考勤机编号获取人员列表
|
||||||
|
export function getPersonListByMacNoAPI(params) {
|
||||||
|
return request({
|
||||||
|
url: '/bmw/kqManager/getWorkerByDeviceId',
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取所有人员列表
|
||||||
|
export function getAllPersonListAPI(params) {
|
||||||
|
return request({
|
||||||
|
url: '/bmw/kqManager/getProDeviceWorker',
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除人员
|
||||||
|
export function deletePersonAPI(data) {
|
||||||
|
return request({
|
||||||
|
url: '/bmw/kqManager/delWorkerByDevice',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量删除人员
|
||||||
|
export function batchDeletePersonAPI(ids) {
|
||||||
|
return request({
|
||||||
|
url: '/system/attMacManage/batchDeletePerson',
|
||||||
|
method: 'post',
|
||||||
|
data: { ids },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下发
|
||||||
|
export function sendDownAPI(data) {
|
||||||
|
return request({
|
||||||
|
url: '/bmw/kqManager/pushWorkerByDevice',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 配置
|
||||||
|
export function configAPI(data) {
|
||||||
|
return request({
|
||||||
|
url: '/system/attMacManage/config',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刷新
|
||||||
|
export function refreshAPI(macNo) {
|
||||||
|
return request({
|
||||||
|
url: '/bmw/kqManager/refreshDevice',
|
||||||
|
method: 'post',
|
||||||
|
data: { deviceCode: macNo },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重启
|
||||||
|
export function restartAPI(macNo) {
|
||||||
|
return request({
|
||||||
|
url: '/bmw/kqManager/restartDevice',
|
||||||
|
method: 'post',
|
||||||
|
data: { deviceCode: macNo },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取任务列表
|
||||||
|
export function getTaskListAPI(params) {
|
||||||
|
return request({
|
||||||
|
url: '/bmw/kqManager/getTaskList',
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除任务
|
||||||
|
export function deleteTaskAPI(data) {
|
||||||
|
return request({
|
||||||
|
url: '/bmw/kqManager/delTaskById',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取任务历史列表
|
||||||
|
export function getTaskHistoryListAPI(params) {
|
||||||
|
return request({
|
||||||
|
url: '/bmw/kqManager/getHisTaskList',
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量删除任务
|
||||||
|
export function batchDeleteTaskAPI(data) {
|
||||||
|
return request({
|
||||||
|
url: '/bmw/kqManager/delHisTaskById',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,234 @@
|
||||||
|
<template>
|
||||||
|
<el-card class="tree-card" shadow="hover">
|
||||||
|
<div class="tree-container">
|
||||||
|
<div class="head-container">
|
||||||
|
<el-input
|
||||||
|
v-model="filterText"
|
||||||
|
placeholder="请输入关键字"
|
||||||
|
clearable
|
||||||
|
size="small"
|
||||||
|
prefix-icon="el-icon-search"
|
||||||
|
style="margin-bottom: 20px"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<el-tree
|
||||||
|
:data="treeData"
|
||||||
|
:props="defaultProps"
|
||||||
|
:expand-on-click-node="false"
|
||||||
|
:filter-node-method="filterNode"
|
||||||
|
ref="tree"
|
||||||
|
node-key="id"
|
||||||
|
default-expand-all
|
||||||
|
highlight-current
|
||||||
|
@node-click="handleNodeClick"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="custom-tree-node"
|
||||||
|
:class="getNodeClass(node.data)"
|
||||||
|
slot-scope="{ node }"
|
||||||
|
>
|
||||||
|
<span class="node-content">
|
||||||
|
<span
|
||||||
|
v-if="node.data.level == 2"
|
||||||
|
class="status-dot"
|
||||||
|
:class="getStatusDotClass(node.data)"
|
||||||
|
>
|
||||||
|
</span>
|
||||||
|
<el-tooltip
|
||||||
|
:content="node.label"
|
||||||
|
placement="top"
|
||||||
|
:disabled="!isTextOverflow(node.label)"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="node-label"
|
||||||
|
:class="getNodeLabelClass(node.data)"
|
||||||
|
>
|
||||||
|
{{ node.label }}
|
||||||
|
</span>
|
||||||
|
</el-tooltip>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</el-tree>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getProjectAndMacTreeAPI } from '@/api/system/attMacManage.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'LeftTree',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
filterText: '',
|
||||||
|
treeData: [],
|
||||||
|
defaultProps: {
|
||||||
|
children: 'children',
|
||||||
|
label: 'name',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
filterText(val) {
|
||||||
|
this.$refs.tree.filter(val)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getTreeData()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 获取树形数据
|
||||||
|
async getTreeData() {
|
||||||
|
try {
|
||||||
|
const res = await getProjectAndMacTreeAPI()
|
||||||
|
if (res.code === 200) {
|
||||||
|
this.treeData = res.data || []
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取树形数据失败:', error)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 树节点过滤
|
||||||
|
filterNode(value, data) {
|
||||||
|
if (!value) return true
|
||||||
|
return data.name.indexOf(value) !== -1
|
||||||
|
},
|
||||||
|
// 树节点点击事件
|
||||||
|
handleNodeClick(data) {
|
||||||
|
this.$emit('node-click', data)
|
||||||
|
},
|
||||||
|
// 获取节点样式类
|
||||||
|
getNodeClass(data) {
|
||||||
|
if (data.level === 2 && data.onLine === 1) {
|
||||||
|
return 'node-online'
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
},
|
||||||
|
// 获取状态点样式类
|
||||||
|
getStatusDotClass(data) {
|
||||||
|
if (data.level == 2) {
|
||||||
|
if (data.onLine == 1) {
|
||||||
|
return 'status-dot-online'
|
||||||
|
} else {
|
||||||
|
return 'status-dot-offline'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
},
|
||||||
|
|
||||||
|
getNodeLabelClass(data) {
|
||||||
|
if (data.level == 2) {
|
||||||
|
if (data.onLine == 1) {
|
||||||
|
return 'node-label-online'
|
||||||
|
} else {
|
||||||
|
return 'node-label-offline'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 判断文本是否溢出
|
||||||
|
* 业务背景:当节点名称过长时,需要显示 tooltip 提示完整名称
|
||||||
|
* 设计决策:通过检查文本长度来判断是否需要显示 tooltip,避免短文本也显示提示
|
||||||
|
* @param {string} text - 节点文本内容
|
||||||
|
* @returns {boolean} 是否溢出
|
||||||
|
*/
|
||||||
|
isTextOverflow(text) {
|
||||||
|
if (!text) return false
|
||||||
|
// 根据实际容器宽度,这里假设超过 20 个字符可能需要省略
|
||||||
|
// 实际项目中可以根据容器宽度动态计算
|
||||||
|
return text.length > 20
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.tree-card {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 0;
|
||||||
|
|
||||||
|
::v-deep .el-card__body {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 20px;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-container {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
min-height: 0;
|
||||||
|
|
||||||
|
.head-container {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-tree {
|
||||||
|
.custom-tree-node {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-size: 14px;
|
||||||
|
padding-right: 8px;
|
||||||
|
|
||||||
|
.node-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-dot {
|
||||||
|
display: inline-block;
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 50%;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-dot-online {
|
||||||
|
background-color: #67c23a;
|
||||||
|
box-shadow: 0 0 4px rgba(103, 194, 58, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-label-online {
|
||||||
|
color: #67c23a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-dot-offline {
|
||||||
|
background-color: #f56c6c;
|
||||||
|
box-shadow: 0 0 4px rgba(245, 108, 108, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-label {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
display: inline-block;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.node-online {
|
||||||
|
.node-label {
|
||||||
|
color: #67c23a;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,833 @@
|
||||||
|
<template>
|
||||||
|
<div style="height: 100%; overflow: hidden">
|
||||||
|
<el-card class="table-card" shadow="hover">
|
||||||
|
<div class="table-container">
|
||||||
|
<TableModel
|
||||||
|
:formLabel="formLabel"
|
||||||
|
:columnsList="columnsList"
|
||||||
|
:request-api="requestApi"
|
||||||
|
:showOperation="true"
|
||||||
|
:isSelectShow="true"
|
||||||
|
:sendParams="sendParams"
|
||||||
|
:isIndexShow="false"
|
||||||
|
ref="tableRef"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
>
|
||||||
|
<template slot="btn">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="danger"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
:disabled="selectedData.length === 0"
|
||||||
|
@click="handleBatchDelete"
|
||||||
|
>
|
||||||
|
批量删除
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="primary"
|
||||||
|
icon="el-icon-download"
|
||||||
|
@click="handleSendDown"
|
||||||
|
>
|
||||||
|
下发
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="primary"
|
||||||
|
icon="el-icon-setting"
|
||||||
|
@click="handleConfig"
|
||||||
|
>
|
||||||
|
配置
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="success"
|
||||||
|
icon="el-icon-refresh"
|
||||||
|
:disabled="refreshCountdown > 0"
|
||||||
|
@click="handleRefresh"
|
||||||
|
>
|
||||||
|
{{
|
||||||
|
refreshCountdown > 0
|
||||||
|
? `刷新(${refreshCountdown}s)`
|
||||||
|
: '刷新'
|
||||||
|
}}
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="warning"
|
||||||
|
icon="el-icon-switch-button"
|
||||||
|
:disabled="restartCountdown > 0"
|
||||||
|
@click="handleRestart"
|
||||||
|
>
|
||||||
|
{{
|
||||||
|
restartCountdown > 0
|
||||||
|
? `重启(${restartCountdown}s)`
|
||||||
|
: '重启'
|
||||||
|
}}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
<template slot="handle" slot-scope="{ data }">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="danger"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
@click="handleDelete(data)"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template slot="faceImage" slot-scope="{ data }">
|
||||||
|
<ImagePreview
|
||||||
|
:src="data.faceImage"
|
||||||
|
height="60px"
|
||||||
|
width="60px"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template slot="isOnDataBase" slot-scope="{ data }">
|
||||||
|
<el-tag
|
||||||
|
v-if="data.isOnDataBase == 1"
|
||||||
|
size="mini"
|
||||||
|
type="success"
|
||||||
|
>
|
||||||
|
在库
|
||||||
|
</el-tag>
|
||||||
|
<el-tag
|
||||||
|
v-if="data.isOnDataBase == 0"
|
||||||
|
size="mini"
|
||||||
|
type="danger"
|
||||||
|
>
|
||||||
|
不在库
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</TableModel>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 下发弹框 -->
|
||||||
|
<DialogModel
|
||||||
|
:dialogConfig="sendDownDialogConfig"
|
||||||
|
@closeDialogOuter="handleCloseSendDownDialog"
|
||||||
|
>
|
||||||
|
<template slot="outerContent">
|
||||||
|
<el-form
|
||||||
|
ref="sendDownFormRef"
|
||||||
|
:model="sendDownFormData"
|
||||||
|
:rules="sendDownFormRules"
|
||||||
|
label-width="120px"
|
||||||
|
>
|
||||||
|
<el-form-item
|
||||||
|
:label="
|
||||||
|
sendDownFormData.allSelect ? '取消全选' : '全选'
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<el-checkbox
|
||||||
|
v-model="allSelect"
|
||||||
|
@change="handleAllSelectChange"
|
||||||
|
>
|
||||||
|
{{ `${allSelect ? '取消全选' : '全选'}` }}
|
||||||
|
</el-checkbox>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="未下发人员:" prop="unSendPersonIds">
|
||||||
|
<el-checkbox-group
|
||||||
|
v-model="sendDownFormData.unSendPersonIds"
|
||||||
|
@change="handleUnSendPersonChange"
|
||||||
|
>
|
||||||
|
<el-checkbox
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.id"
|
||||||
|
v-for="item in unSendPersonList"
|
||||||
|
>
|
||||||
|
{{ item.name }}
|
||||||
|
</el-checkbox>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="已下发人员:" prop="sentPersonIds">
|
||||||
|
<el-checkbox-group
|
||||||
|
v-model="sendDownFormData.sentPersonIds"
|
||||||
|
@change="handleSentPersonChange"
|
||||||
|
>
|
||||||
|
<el-checkbox
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.id"
|
||||||
|
v-for="item in sentPersonList"
|
||||||
|
>
|
||||||
|
{{ item.name }}
|
||||||
|
</el-checkbox>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-row class="dialog-footer-btn">
|
||||||
|
<el-button size="medium" @click="handleCloseSendDownDialog">
|
||||||
|
取消
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
size="medium"
|
||||||
|
type="primary"
|
||||||
|
@click="handleSendDownSubmit"
|
||||||
|
>
|
||||||
|
确定
|
||||||
|
</el-button>
|
||||||
|
</el-row>
|
||||||
|
</template>
|
||||||
|
</DialogModel>
|
||||||
|
|
||||||
|
<!-- 配置弹框 -->
|
||||||
|
<DialogModel
|
||||||
|
:dialogConfig="configDialogConfig"
|
||||||
|
@closeDialogOuter="handleCloseConfigDialog"
|
||||||
|
>
|
||||||
|
<template slot="outerContent">
|
||||||
|
<el-form
|
||||||
|
ref="configFormRef"
|
||||||
|
:model="configFormData"
|
||||||
|
:rules="configFormRules"
|
||||||
|
label-width="120px"
|
||||||
|
>
|
||||||
|
<el-form-item label="选择人员:" prop="workerIds">
|
||||||
|
<el-select
|
||||||
|
v-model="configFormData.workerIds"
|
||||||
|
multiple
|
||||||
|
filterable
|
||||||
|
placeholder="请选择人员"
|
||||||
|
style="width: 100%"
|
||||||
|
:loading="personListLoading"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in personList"
|
||||||
|
:key="item.id"
|
||||||
|
:label="`${item.name}(${item.idNumber})`"
|
||||||
|
:value="item.id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="配置项:" prop="configItem">
|
||||||
|
<el-input
|
||||||
|
v-model="configFormData.configItem"
|
||||||
|
type="textarea"
|
||||||
|
:autosize="{ minRows: 4, maxRows: 8 }"
|
||||||
|
placeholder="请输入配置项"
|
||||||
|
clearable
|
||||||
|
maxlength="500"
|
||||||
|
show-word-limit
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-row class="dialog-footer-btn">
|
||||||
|
<el-button size="medium" @click="handleCloseConfigDialog">
|
||||||
|
取消
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
size="medium"
|
||||||
|
type="primary"
|
||||||
|
@click="handleConfigSubmit"
|
||||||
|
>
|
||||||
|
确定
|
||||||
|
</el-button>
|
||||||
|
</el-row>
|
||||||
|
</template>
|
||||||
|
</DialogModel>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import TableModel from '@/components/TableModel'
|
||||||
|
import DialogModel from '@/components/DialogModel'
|
||||||
|
import {
|
||||||
|
getPersonListByMacNoAPI,
|
||||||
|
getAllPersonListAPI,
|
||||||
|
deletePersonAPI,
|
||||||
|
batchDeletePersonAPI,
|
||||||
|
refreshAPI,
|
||||||
|
restartAPI,
|
||||||
|
sendDownAPI,
|
||||||
|
configAPI,
|
||||||
|
} from '@/api/system/attMacManage.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'RightTable',
|
||||||
|
components: {
|
||||||
|
TableModel,
|
||||||
|
DialogModel,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
macNo: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
proId: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
subId: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
teamId: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 查询表单配置
|
||||||
|
formLabel: [
|
||||||
|
{
|
||||||
|
f_label: '关键字',
|
||||||
|
f_model: 'keyWord',
|
||||||
|
f_type: 'ipt',
|
||||||
|
f_width: '180px',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
f_label: '人员编号',
|
||||||
|
f_model: 'userId',
|
||||||
|
f_type: 'ipt',
|
||||||
|
f_width: '180px',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
f_label: '是否在库',
|
||||||
|
f_model: 'isOnDataBase',
|
||||||
|
f_type: 'sel',
|
||||||
|
f_width: '180px',
|
||||||
|
f_selList: [
|
||||||
|
{
|
||||||
|
label: '在库',
|
||||||
|
value: '1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '不在库',
|
||||||
|
value: '0',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
// 表格列配置
|
||||||
|
columnsList: [
|
||||||
|
{
|
||||||
|
t_label: '人员编号',
|
||||||
|
t_props: 'userId',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
t_label: '姓名',
|
||||||
|
t_props: 'userName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
t_label: '考勤机编号',
|
||||||
|
t_props: 'devCode',
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
t_label: '人脸图片',
|
||||||
|
t_slot: 'faceImage',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
t_label: '是否在库',
|
||||||
|
t_slot: 'isOnDataBase',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
t_label: '更新时间',
|
||||||
|
t_props: 'updateTime',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
// 下发弹框配置
|
||||||
|
sendDownDialogConfig: {
|
||||||
|
outerVisible: false,
|
||||||
|
outerTitle: '下发',
|
||||||
|
outerWidth: '50%',
|
||||||
|
maxHeight: '80vh',
|
||||||
|
},
|
||||||
|
// 配置弹框配置
|
||||||
|
configDialogConfig: {
|
||||||
|
outerVisible: false,
|
||||||
|
outerTitle: '配置',
|
||||||
|
outerWidth: '50%',
|
||||||
|
maxHeight: '80vh',
|
||||||
|
},
|
||||||
|
// 下发表单数据
|
||||||
|
sendDownFormData: {
|
||||||
|
workerIds: [],
|
||||||
|
|
||||||
|
// 未下发人员
|
||||||
|
unSendPersonIds: [],
|
||||||
|
// 已下发人员
|
||||||
|
sentPersonIds: [],
|
||||||
|
},
|
||||||
|
// 配置表单数据
|
||||||
|
configFormData: {
|
||||||
|
workerIds: [],
|
||||||
|
configItem: '',
|
||||||
|
},
|
||||||
|
// 下发表单校验规则
|
||||||
|
sendDownFormRules: {
|
||||||
|
unSendPersonIds: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择人员',
|
||||||
|
trigger: 'change',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// 配置表单校验规则
|
||||||
|
configFormRules: {
|
||||||
|
unSendPersonList: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择人员',
|
||||||
|
trigger: 'change',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
configItem: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入配置项',
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// 人员列表
|
||||||
|
personList: [],
|
||||||
|
personListLoading: false,
|
||||||
|
allSelect: false,
|
||||||
|
selectedData: [],
|
||||||
|
// 未下发人员
|
||||||
|
unSendPersonList: [],
|
||||||
|
// 已下发人员
|
||||||
|
sentPersonList: [],
|
||||||
|
// 刷新倒计时(秒)
|
||||||
|
refreshCountdown: 0,
|
||||||
|
// 刷新倒计时定时器
|
||||||
|
refreshTimer: null,
|
||||||
|
// 重启倒计时(秒)
|
||||||
|
restartCountdown: 0,
|
||||||
|
// 重启倒计时定时器
|
||||||
|
restartTimer: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 根据是否有考勤机编号决定使用哪个API
|
||||||
|
requestApi() {
|
||||||
|
return this.macNo
|
||||||
|
? getPersonListByMacNoAPI
|
||||||
|
: getPersonListByMacNoAPI
|
||||||
|
},
|
||||||
|
// 传递给表格的查询参数
|
||||||
|
sendParams() {
|
||||||
|
return {
|
||||||
|
deviceCode: this.macNo || '',
|
||||||
|
proId: this.proId || '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
macNo: {
|
||||||
|
handler() {
|
||||||
|
// 当考勤机编号变化时,刷新表格
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.tableRef) {
|
||||||
|
this.$refs.tableRef.getTableList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
immediate: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 组件销毁前清理定时器
|
||||||
|
* 业务背景:避免组件销毁后定时器仍在运行导致的内存泄漏
|
||||||
|
* 设计决策:在组件销毁前清除所有定时器
|
||||||
|
*/
|
||||||
|
beforeDestroy() {
|
||||||
|
if (this.refreshTimer) {
|
||||||
|
clearInterval(this.refreshTimer)
|
||||||
|
this.refreshTimer = null
|
||||||
|
}
|
||||||
|
if (this.restartTimer) {
|
||||||
|
clearInterval(this.restartTimer)
|
||||||
|
this.restartTimer = null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 获取表格列表(供父组件调用)
|
||||||
|
getTableList() {
|
||||||
|
if (this.$refs.tableRef) {
|
||||||
|
this.$refs.tableRef.getTableList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 删除
|
||||||
|
handleDelete(row) {
|
||||||
|
this.$modal
|
||||||
|
.confirm('确定要删除该人员吗?')
|
||||||
|
.then(() => {
|
||||||
|
deletePersonAPI({
|
||||||
|
deviceCode: this.macNo,
|
||||||
|
workerIds: [row.userId],
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
this.$modal.msgSuccess('删除成功')
|
||||||
|
// 刷新考勤机
|
||||||
|
this.handleRefresh()
|
||||||
|
this.getTableList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
},
|
||||||
|
// 批量删除
|
||||||
|
handleBatchDelete() {
|
||||||
|
if (this.selectedData.length === 0) {
|
||||||
|
this.$modal.msgWarning('请选择要删除的数据')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$modal
|
||||||
|
.confirm(
|
||||||
|
'确定要删除选中的 ' +
|
||||||
|
this.selectedData.length +
|
||||||
|
' 条数据吗?',
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
const ids = this.selectedData.map((item) => item.userId)
|
||||||
|
deletePersonAPI({
|
||||||
|
deviceCode: this.macNo,
|
||||||
|
workerIds: ids,
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
this.$modal.msgSuccess('批量删除成功')
|
||||||
|
this.handleRefresh()
|
||||||
|
this.getTableList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
},
|
||||||
|
// 下发
|
||||||
|
handleSendDown() {
|
||||||
|
if (!this.macNo) {
|
||||||
|
this.$modal.msgWarning('请先选择考勤机')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.sendDownDialogConfig.outerVisible = true
|
||||||
|
this.resetSendDownForm()
|
||||||
|
this.getPersonList()
|
||||||
|
},
|
||||||
|
// 配置
|
||||||
|
handleConfig() {
|
||||||
|
if (!this.macNo) {
|
||||||
|
this.$modal.msgWarning('请先选择考勤机')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.configDialogConfig.outerVisible = true
|
||||||
|
this.resetConfigForm()
|
||||||
|
this.getPersonList()
|
||||||
|
},
|
||||||
|
// 获取人员列表
|
||||||
|
async getPersonList() {
|
||||||
|
this.personListLoading = true
|
||||||
|
try {
|
||||||
|
const res = await getAllPersonListAPI({
|
||||||
|
proId: this.proId,
|
||||||
|
deviceCode: this.macNo,
|
||||||
|
subId: this.subId,
|
||||||
|
teamId: this.teamId,
|
||||||
|
})
|
||||||
|
if (res.code === 200) {
|
||||||
|
// this.unSendPersonList = res?.data.map((item) => ({
|
||||||
|
// id: item.workerId,
|
||||||
|
// name: item.workerName,
|
||||||
|
// isSelected: false,
|
||||||
|
// }))
|
||||||
|
|
||||||
|
this.unSendPersonList = res?.data
|
||||||
|
.filter((item) => item.isIssue == 0)
|
||||||
|
.map((item) => ({
|
||||||
|
id: item.workerId,
|
||||||
|
name: item.workerName,
|
||||||
|
isSelected: false,
|
||||||
|
}))
|
||||||
|
|
||||||
|
this.sentPersonList = res?.data
|
||||||
|
.filter((item) => item.isIssue == 1)
|
||||||
|
.map((item) => ({
|
||||||
|
id: item.workerId,
|
||||||
|
name: item.workerName,
|
||||||
|
isSelected: false,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取人员列表失败:', error)
|
||||||
|
} finally {
|
||||||
|
this.personListLoading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 关闭下发弹框
|
||||||
|
handleCloseSendDownDialog() {
|
||||||
|
this.sendDownDialogConfig.outerVisible = false
|
||||||
|
this.resetSendDownForm()
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 重置下发表单
|
||||||
|
* 业务背景:关闭弹框或重新打开时需要清空表单数据
|
||||||
|
* 设计决策:需要重置所有表单字段,包括未下发和已下发人员ID数组,避免 undefined 导致的错误
|
||||||
|
*/
|
||||||
|
resetSendDownForm() {
|
||||||
|
this.sendDownFormData = {
|
||||||
|
workerIds: [],
|
||||||
|
// 未下发人员
|
||||||
|
unSendPersonIds: [],
|
||||||
|
// 已下发人员
|
||||||
|
sentPersonIds: [],
|
||||||
|
}
|
||||||
|
this.allSelect = false
|
||||||
|
if (this.$refs.sendDownFormRef) {
|
||||||
|
this.$refs.sendDownFormRef.resetFields()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 提交下发表单
|
||||||
|
* 业务背景:将选中的未下发人员下发到考勤机
|
||||||
|
* 设计决策:使用 unSendPersonIds 作为提交参数,因为表单绑定的是该字段
|
||||||
|
*/
|
||||||
|
handleSendDownSubmit() {
|
||||||
|
this.$refs.sendDownFormRef.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
const params = {
|
||||||
|
deviceCode: this.macNo,
|
||||||
|
workerIds: this.sendDownFormData.unSendPersonIds,
|
||||||
|
}
|
||||||
|
sendDownAPI(params)
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
this.$modal.msgSuccess('下发成功')
|
||||||
|
this.handleCloseSendDownDialog()
|
||||||
|
this.handleRefresh()
|
||||||
|
this.getTableList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 关闭配置弹框
|
||||||
|
handleCloseConfigDialog() {
|
||||||
|
this.configDialogConfig.outerVisible = false
|
||||||
|
this.resetConfigForm()
|
||||||
|
},
|
||||||
|
// 重置配置表单
|
||||||
|
resetConfigForm() {
|
||||||
|
this.configFormData = {
|
||||||
|
workerIds: [],
|
||||||
|
configItem: '',
|
||||||
|
}
|
||||||
|
if (this.$refs.configFormRef) {
|
||||||
|
this.$refs.configFormRef.resetFields()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 提交配置表单
|
||||||
|
handleConfigSubmit() {
|
||||||
|
this.$refs.configFormRef.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
const params = {
|
||||||
|
macNo: this.macNo,
|
||||||
|
workerIds: this.configFormData.workerIds,
|
||||||
|
configItem: this.configFormData.configItem,
|
||||||
|
}
|
||||||
|
configAPI(params)
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
this.$modal.msgSuccess('配置成功')
|
||||||
|
this.handleCloseConfigDialog()
|
||||||
|
this.getTableList()
|
||||||
|
this.$emit('refresh-tree')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 刷新考勤机
|
||||||
|
* 业务背景:刷新考勤机数据,获取最新的人员信息
|
||||||
|
* 设计决策:刷新成功后启动10秒倒计时,防止频繁刷新对服务器造成压力
|
||||||
|
*/
|
||||||
|
handleRefresh() {
|
||||||
|
if (!this.macNo) {
|
||||||
|
this.$modal.msgWarning('请先选择考勤机')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 如果正在倒计时,不允许刷新
|
||||||
|
if (this.refreshCountdown > 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
refreshAPI(this.macNo)
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
this.$modal.msgSuccess('刷新成功')
|
||||||
|
this.getTableList()
|
||||||
|
// 启动倒计时
|
||||||
|
this.startRefreshCountdown()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 启动刷新倒计时
|
||||||
|
* 业务背景:刷新成功后需要等待10秒才能再次刷新
|
||||||
|
* 设计决策:使用定时器每秒更新倒计时,倒计时结束后清除定时器
|
||||||
|
*/
|
||||||
|
startRefreshCountdown() {
|
||||||
|
// 清除之前的定时器
|
||||||
|
if (this.refreshTimer) {
|
||||||
|
clearInterval(this.refreshTimer)
|
||||||
|
this.refreshTimer = null
|
||||||
|
}
|
||||||
|
// 设置倒计时为10秒
|
||||||
|
this.refreshCountdown = 10
|
||||||
|
// 启动定时器,每秒减1
|
||||||
|
this.refreshTimer = setInterval(() => {
|
||||||
|
this.refreshCountdown--
|
||||||
|
if (this.refreshCountdown <= 0) {
|
||||||
|
// 倒计时结束,清除定时器
|
||||||
|
clearInterval(this.refreshTimer)
|
||||||
|
this.refreshTimer = null
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 重启考勤机
|
||||||
|
* 业务背景:重启考勤机设备,恢复设备状态
|
||||||
|
* 设计决策:重启成功后启动10秒倒计时,防止频繁重启对设备造成损害
|
||||||
|
*/
|
||||||
|
handleRestart() {
|
||||||
|
if (!this.macNo) {
|
||||||
|
this.$modal.msgWarning('请先选择考勤机')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 如果正在倒计时,不允许重启
|
||||||
|
if (this.restartCountdown > 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$modal
|
||||||
|
.confirm('确定要重启该考勤机吗?')
|
||||||
|
.then(() => {
|
||||||
|
restartAPI(this.macNo)
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
this.$modal.msgSuccess('重启成功')
|
||||||
|
// 启动倒计时
|
||||||
|
this.startRestartCountdown()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 启动重启倒计时
|
||||||
|
* 业务背景:重启成功后需要等待10秒才能再次重启
|
||||||
|
* 设计决策:使用定时器每秒更新倒计时,倒计时结束后清除定时器
|
||||||
|
*/
|
||||||
|
startRestartCountdown() {
|
||||||
|
// 清除之前的定时器
|
||||||
|
if (this.restartTimer) {
|
||||||
|
clearInterval(this.restartTimer)
|
||||||
|
this.restartTimer = null
|
||||||
|
}
|
||||||
|
// 设置倒计时为10秒
|
||||||
|
this.restartCountdown = 10
|
||||||
|
// 启动定时器,每秒减1
|
||||||
|
this.restartTimer = setInterval(() => {
|
||||||
|
this.restartCountdown--
|
||||||
|
if (this.restartCountdown <= 0) {
|
||||||
|
// 倒计时结束,清除定时器
|
||||||
|
clearInterval(this.restartTimer)
|
||||||
|
this.restartTimer = null
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 全选
|
||||||
|
handleAllSelectChange(val) {
|
||||||
|
if (val) {
|
||||||
|
this.sendDownFormData.unSendPersonIds =
|
||||||
|
this.unSendPersonList.map((item) => item.id)
|
||||||
|
|
||||||
|
this.sendDownFormData.sentPersonIds = this.sentPersonList.map(
|
||||||
|
(item) => item.id,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
this.sendDownFormData.unSendPersonIds = []
|
||||||
|
this.sendDownFormData.sentPersonIds = []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 未下发人员选择
|
||||||
|
handleUnSendPersonChange(value) {
|
||||||
|
if (
|
||||||
|
value.length == this.unSendPersonList.length &&
|
||||||
|
this.sendDownFormData.sentPersonIds.length ==
|
||||||
|
this.sentPersonList.length
|
||||||
|
) {
|
||||||
|
this.allSelect = true
|
||||||
|
} else {
|
||||||
|
this.allSelect = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 已下发人员选择
|
||||||
|
handleSentPersonChange(value) {
|
||||||
|
if (
|
||||||
|
value.length == this.sentPersonList.length &&
|
||||||
|
this.sendDownFormData.unSendPersonIds.length ==
|
||||||
|
this.unSendPersonList.length
|
||||||
|
) {
|
||||||
|
this.allSelect = true
|
||||||
|
} else {
|
||||||
|
this.allSelect = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSelectionChange(e) {
|
||||||
|
this.selectedData = e
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.table-card {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 0;
|
||||||
|
|
||||||
|
::v-deep .el-card__body {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 20px;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
min-height: 0;
|
||||||
|
height: 0; // 关键:配合 flex: 1 使用,确保可以滚动
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-footer-btn {
|
||||||
|
text-align: right;
|
||||||
|
padding-top: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,274 @@
|
||||||
|
<template>
|
||||||
|
<div style="height: 100%; overflow: hidden">
|
||||||
|
<el-card class="table-card" shadow="hover">
|
||||||
|
<div class="table-container">
|
||||||
|
<TableModel
|
||||||
|
:formLabel="formLabel"
|
||||||
|
:columnsList="columnsList"
|
||||||
|
:request-api="requestApi"
|
||||||
|
:showOperation="false"
|
||||||
|
:isSelectShow="true"
|
||||||
|
:sendParams="sendParams"
|
||||||
|
:isIndexShow="false"
|
||||||
|
ref="tableRef"
|
||||||
|
:pageSizes="[100, 200, 500]"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
>
|
||||||
|
<template slot="btn">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="danger"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
:disabled="selectedData.length === 0"
|
||||||
|
@click="handleBatchDelete"
|
||||||
|
>
|
||||||
|
批量删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
<template slot="transStatus" slot-scope="{ data }">
|
||||||
|
<el-tag
|
||||||
|
size="mini"
|
||||||
|
type="info"
|
||||||
|
v-if="data.transStatus == 0"
|
||||||
|
>
|
||||||
|
待执行
|
||||||
|
</el-tag>
|
||||||
|
<el-tag
|
||||||
|
size="mini"
|
||||||
|
type="primary"
|
||||||
|
v-if="data.transStatus == 1"
|
||||||
|
>
|
||||||
|
执行中
|
||||||
|
</el-tag>
|
||||||
|
<el-tag
|
||||||
|
size="mini"
|
||||||
|
type="success"
|
||||||
|
v-if="data.transStatus == 2"
|
||||||
|
>
|
||||||
|
已完成
|
||||||
|
</el-tag>
|
||||||
|
<el-tag
|
||||||
|
size="mini"
|
||||||
|
type="danger"
|
||||||
|
v-if="data.transStatus == 3"
|
||||||
|
>
|
||||||
|
任务繁忙-人员占用
|
||||||
|
</el-tag>
|
||||||
|
<el-tag
|
||||||
|
size="mini"
|
||||||
|
type="danger"
|
||||||
|
v-if="
|
||||||
|
data.transStatus == 4 || data.transStatus == 5
|
||||||
|
"
|
||||||
|
>
|
||||||
|
失败
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</TableModel>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import TableModel from '@/components/TableModel'
|
||||||
|
import {
|
||||||
|
getTaskHistoryListAPI,
|
||||||
|
batchDeleteTaskAPI,
|
||||||
|
} from '@/api/system/attMacManage.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'TaskHistoryList',
|
||||||
|
components: {
|
||||||
|
TableModel,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
macNo: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
proId: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 查询表单配置
|
||||||
|
formLabel: [
|
||||||
|
{
|
||||||
|
f_label: '任务编码',
|
||||||
|
f_model: 'cmdCode',
|
||||||
|
f_type: 'ipt',
|
||||||
|
f_width: '180px',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
f_label: '任务名称',
|
||||||
|
f_model: 'cmdName',
|
||||||
|
f_type: 'ipt',
|
||||||
|
f_width: '180px',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
f_label: '执行状态',
|
||||||
|
f_model: 'transStatus',
|
||||||
|
f_type: 'sel',
|
||||||
|
f_width: '180px',
|
||||||
|
f_selList: [
|
||||||
|
{
|
||||||
|
label: '待执行',
|
||||||
|
value: '0',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '执行中',
|
||||||
|
value: '1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '已完成',
|
||||||
|
value: '2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '任务繁忙-人员占用',
|
||||||
|
value: '3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '失败',
|
||||||
|
value: '4',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
// 表格列配置
|
||||||
|
columnsList: [
|
||||||
|
{
|
||||||
|
t_label: '任务ID',
|
||||||
|
t_props: 'taskId',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
t_label: '任务编号',
|
||||||
|
t_props: 'cmdCode',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
t_label: '任务名称',
|
||||||
|
t_props: 'cmdName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
t_label: '请求参数',
|
||||||
|
t_props: 'cmdParam',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
t_label: '执行时间',
|
||||||
|
t_props: 'exeTime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
t_label: '创建时间',
|
||||||
|
t_props: 'createTime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
t_label: '状态',
|
||||||
|
t_slot: 'transStatus',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
t_label: '异常内容',
|
||||||
|
t_props: 'msg',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
selectedData: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// API接口
|
||||||
|
requestApi() {
|
||||||
|
return getTaskHistoryListAPI
|
||||||
|
},
|
||||||
|
// 传递给表格的查询参数
|
||||||
|
sendParams() {
|
||||||
|
return {
|
||||||
|
deviceCode: this.macNo || '',
|
||||||
|
pageSize: 100,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
macNo: {
|
||||||
|
handler() {
|
||||||
|
// 当考勤机编号变化时,刷新表格
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.tableRef) {
|
||||||
|
this.$refs.tableRef.getTableList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
immediate: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 获取表格列表(供父组件调用)
|
||||||
|
getTableList() {
|
||||||
|
if (this.$refs.tableRef) {
|
||||||
|
this.$refs.tableRef.getTableList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSelectionChange(val) {
|
||||||
|
this.selectedData = val
|
||||||
|
},
|
||||||
|
handleBatchDelete() {
|
||||||
|
if (this.selectedData.length === 0) {
|
||||||
|
this.$modal.msgWarning('请选择要删除的数据')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$modal
|
||||||
|
.confirm(
|
||||||
|
'确定要删除选中的 ' +
|
||||||
|
this.selectedData.length +
|
||||||
|
' 条数据吗?',
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
const ids = this.selectedData.map((item) => item.taskId)
|
||||||
|
batchDeleteTaskAPI({
|
||||||
|
taskId: ids.join(','),
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
this.$modal.msgSuccess('批量删除成功')
|
||||||
|
this.$refs.tableRef.getTableList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.table-card {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 0;
|
||||||
|
|
||||||
|
::v-deep .el-card__body {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 20px;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
min-height: 0;
|
||||||
|
height: 0; // 关键:配合 flex: 1 使用,确保可以滚动
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,271 @@
|
||||||
|
<template>
|
||||||
|
<div style="height: 100%; overflow: hidden">
|
||||||
|
<el-card class="table-card" shadow="hover">
|
||||||
|
<div class="table-container">
|
||||||
|
<TableModel
|
||||||
|
:formLabel="formLabel"
|
||||||
|
:columnsList="columnsList"
|
||||||
|
:request-api="requestApi"
|
||||||
|
:showOperation="false"
|
||||||
|
:isSelectShow="true"
|
||||||
|
:isIndexShow="false"
|
||||||
|
:sendParams="sendParams"
|
||||||
|
:pageSizes="[100, 200, 500]"
|
||||||
|
ref="tableRef"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
>
|
||||||
|
<template slot="btn">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="danger"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
:disabled="selectedData.length === 0"
|
||||||
|
@click="handleBatchDelete"
|
||||||
|
>
|
||||||
|
批量删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
<template slot="transStatus" slot-scope="{ data }">
|
||||||
|
<el-tag
|
||||||
|
size="mini"
|
||||||
|
type="info"
|
||||||
|
v-if="data.transStatus == 0"
|
||||||
|
>
|
||||||
|
待执行
|
||||||
|
</el-tag>
|
||||||
|
<el-tag
|
||||||
|
size="mini"
|
||||||
|
type="primary"
|
||||||
|
v-if="data.transStatus == 1"
|
||||||
|
>
|
||||||
|
执行中
|
||||||
|
</el-tag>
|
||||||
|
<el-tag
|
||||||
|
size="mini"
|
||||||
|
type="success"
|
||||||
|
v-if="data.transStatus == 2"
|
||||||
|
>
|
||||||
|
已完成
|
||||||
|
</el-tag>
|
||||||
|
<el-tag
|
||||||
|
size="mini"
|
||||||
|
type="danger"
|
||||||
|
v-if="data.transStatus == 3"
|
||||||
|
>
|
||||||
|
任务繁忙-人员占用
|
||||||
|
</el-tag>
|
||||||
|
<el-tag
|
||||||
|
size="mini"
|
||||||
|
type="danger"
|
||||||
|
v-if="
|
||||||
|
data.transStatus == 4 || data.transStatus == 5
|
||||||
|
"
|
||||||
|
>
|
||||||
|
失败
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</TableModel>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import TableModel from '@/components/TableModel'
|
||||||
|
import { getTaskListAPI, deleteTaskAPI } from '@/api/system/attMacManage.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'TaskHistoryList',
|
||||||
|
components: {
|
||||||
|
TableModel,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
macNo: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
proId: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 查询表单配置
|
||||||
|
formLabel: [
|
||||||
|
{
|
||||||
|
f_label: '任务编码',
|
||||||
|
f_model: 'cmdCode',
|
||||||
|
f_type: 'ipt',
|
||||||
|
f_width: '180px',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
f_label: '任务名称',
|
||||||
|
f_model: 'cmdName',
|
||||||
|
f_type: 'ipt',
|
||||||
|
f_width: '180px',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
f_label: '执行状态',
|
||||||
|
f_model: 'transStatus',
|
||||||
|
f_type: 'sel',
|
||||||
|
f_width: '180px',
|
||||||
|
f_selList: [
|
||||||
|
{
|
||||||
|
label: '待执行',
|
||||||
|
value: '0',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '执行中',
|
||||||
|
value: '1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '已完成',
|
||||||
|
value: '2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '任务繁忙-人员占用',
|
||||||
|
value: '3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '失败',
|
||||||
|
value: '4',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
// 表格列配置
|
||||||
|
columnsList: [
|
||||||
|
{
|
||||||
|
t_label: '任务ID',
|
||||||
|
t_props: 'taskId',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
t_label: '任务编号',
|
||||||
|
t_props: 'cmdCode',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
t_label: '任务名称',
|
||||||
|
t_props: 'cmdName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
t_label: '请求参数',
|
||||||
|
t_props: 'cmdParam',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
t_label: '执行时间',
|
||||||
|
t_props: 'exeTime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
t_label: '创建时间',
|
||||||
|
t_props: 'createTime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
t_label: '状态',
|
||||||
|
t_slot: 'transStatus',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
t_label: '异常内容',
|
||||||
|
t_props: 'msg',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
selectedData: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// API接口
|
||||||
|
requestApi() {
|
||||||
|
return getTaskListAPI
|
||||||
|
},
|
||||||
|
// 传递给表格的查询参数
|
||||||
|
sendParams() {
|
||||||
|
return {
|
||||||
|
deviceCode: this.macNo || '',
|
||||||
|
pageSize: 100,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
macNo: {
|
||||||
|
handler() {
|
||||||
|
// 当考勤机编号变化时,刷新表格
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.tableRef) {
|
||||||
|
this.$refs.tableRef.getTableList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
immediate: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 获取表格列表(供父组件调用)
|
||||||
|
getTableList() {
|
||||||
|
if (this.$refs.tableRef) {
|
||||||
|
this.$refs.tableRef.getTableList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleSelectionChange(val) {
|
||||||
|
this.selectedData = val
|
||||||
|
},
|
||||||
|
handleBatchDelete() {
|
||||||
|
// console.log(this.selectedData)
|
||||||
|
if (this.selectedData.length === 0) {
|
||||||
|
this.$modal.msgWarning('请选择要删除的数据')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$modal
|
||||||
|
.confirm(
|
||||||
|
'确定要删除选中的 ' +
|
||||||
|
this.selectedData.length +
|
||||||
|
' 条数据吗?',
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
const ids = this.selectedData.map((item) => item.taskId)
|
||||||
|
deleteTaskAPI({
|
||||||
|
taskId: ids.join(','),
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
this.$modal.msgSuccess('批量删除成功')
|
||||||
|
this.$refs.tableRef.getTableList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.table-card {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 0;
|
||||||
|
|
||||||
|
::v-deep .el-card__body {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 20px;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
min-height: 0;
|
||||||
|
height: 0; // 关键:配合 flex: 1 使用,确保可以滚动
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,228 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-row :gutter="10">
|
||||||
|
<!-- 左侧树形组件 -->
|
||||||
|
<el-col :span="6" :xs="24">
|
||||||
|
<leftTree ref="leftTreeRef" @node-click="handleNodeClick" />
|
||||||
|
</el-col>
|
||||||
|
<!-- 右侧表格组件 -->
|
||||||
|
<el-col :span="18" :xs="24">
|
||||||
|
<div class="right-content">
|
||||||
|
<!-- 切换按钮 -->
|
||||||
|
<div class="tab-switch">
|
||||||
|
<div class="tab-switch-left">
|
||||||
|
<el-radio-group v-model="activeTab" size="medium">
|
||||||
|
<el-radio-button label="person"
|
||||||
|
>人员列表</el-radio-button
|
||||||
|
>
|
||||||
|
<el-radio-button label="task"
|
||||||
|
>任务列表</el-radio-button
|
||||||
|
>
|
||||||
|
<el-radio-button label="taskHistory"
|
||||||
|
>任务历史</el-radio-button
|
||||||
|
>
|
||||||
|
</el-radio-group>
|
||||||
|
</div>
|
||||||
|
<div class="tab-switch-right">
|
||||||
|
<div class="selected-node-info">
|
||||||
|
<i class="el-icon-location-outline"></i>
|
||||||
|
<span class="label">当前节点:</span>
|
||||||
|
<span class="value">{{
|
||||||
|
selectedNodeName || '未选择'
|
||||||
|
}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="right-content-table">
|
||||||
|
<component
|
||||||
|
:is="currentComponent"
|
||||||
|
ref="currentTableRef"
|
||||||
|
:mac-no="selectedMacNo"
|
||||||
|
:pro-id="selectedProId"
|
||||||
|
:sub-id="selectedSubId"
|
||||||
|
:team-id="selectedTeamId"
|
||||||
|
@refresh-tree="handleRefreshTree"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import leftTree from './components/leftTree.vue'
|
||||||
|
import rightTable from './components/rightTable.vue'
|
||||||
|
import taskList from './components/taskList.vue'
|
||||||
|
import taskHistoryList from './components/taskHistoryList.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'AttMacManage',
|
||||||
|
components: {
|
||||||
|
leftTree,
|
||||||
|
rightTable,
|
||||||
|
taskList,
|
||||||
|
taskHistoryList,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
selectedMacNo: '', // 选中的考勤机编号
|
||||||
|
selectedProId: '', // 选中的工程id
|
||||||
|
selectedSubId: '', // 选中的分包id
|
||||||
|
selectedTeamId: '', // 选中的班组id
|
||||||
|
selectedNodeName: '', // 选中的节点名称
|
||||||
|
activeTab: 'person', // 当前激活的标签页
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 当前组件名称
|
||||||
|
currentComponent() {
|
||||||
|
const componentMap = {
|
||||||
|
person: 'rightTable',
|
||||||
|
task: 'taskList',
|
||||||
|
taskHistory: 'taskHistoryList',
|
||||||
|
}
|
||||||
|
return componentMap[this.activeTab] || 'rightTable'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 树节点点击事件
|
||||||
|
handleNodeClick(data) {
|
||||||
|
console.log('data选择的节点', data)
|
||||||
|
|
||||||
|
this.selectedMacNo = data.id
|
||||||
|
this.selectedProId = data.proId
|
||||||
|
this.selectedSubId = data.subId
|
||||||
|
this.selectedTeamId = data.teamId
|
||||||
|
|
||||||
|
this.selectedNodeName = data.name
|
||||||
|
// if (data.level === 2) {
|
||||||
|
// // 二级节点(考勤机)
|
||||||
|
// this.selectedMacNo = data.id
|
||||||
|
// } else {
|
||||||
|
// // 一级节点(工程)或根节点,显示所有人员
|
||||||
|
// this.selectedMacNo = ''
|
||||||
|
// }
|
||||||
|
// 刷新右侧表格
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.refreshCurrentTable()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 刷新当前表格
|
||||||
|
refreshCurrentTable() {
|
||||||
|
const ref = this.$refs.currentTableRef
|
||||||
|
if (ref && ref.getTableList) {
|
||||||
|
ref.getTableList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 标签页切换
|
||||||
|
handleTabChange(val) {
|
||||||
|
console.log('val', val)
|
||||||
|
// 切换标签页后刷新当前表格
|
||||||
|
// this.$nextTick(() => {
|
||||||
|
// this.refreshCurrentTable()
|
||||||
|
// })
|
||||||
|
},
|
||||||
|
// 刷新左侧树
|
||||||
|
handleRefreshTree() {
|
||||||
|
if (this.$refs.leftTreeRef) {
|
||||||
|
this.$refs.leftTreeRef.getTreeData()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.app-container {
|
||||||
|
// height: calc(100vh - 120px);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-row {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-col {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-switch {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 12px 20px;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-switch-left {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-switch-right {
|
||||||
|
margin-left: 20px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected-node-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 6px 16px;
|
||||||
|
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
||||||
|
border-radius: 20px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #606266;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #409eff;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: #909399;
|
||||||
|
margin-right: 4px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
color: #303133;
|
||||||
|
font-weight: 600;
|
||||||
|
max-width: 200px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-content-table {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-radio-group {
|
||||||
|
.el-radio-button__inner {
|
||||||
|
padding: 10px 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
Reference in New Issue