This commit is contained in:
BianLzhaoMin 2025-12-03 11:15:59 +08:00
parent b9bc8db213
commit 8db21030dd
3 changed files with 245 additions and 50 deletions

View File

@ -34,11 +34,18 @@
:class="getStatusDotClass(node.data)" :class="getStatusDotClass(node.data)"
> >
</span> </span>
<el-tooltip
:content="node.label"
placement="top"
:disabled="!isTextOverflow(node.label)"
>
<span <span
class="node-label" class="node-label"
:class="getNodeLabelClass(node.data)" :class="getNodeLabelClass(node.data)"
>{{ node.label }}</span
> >
{{ node.label }}
</span>
</el-tooltip>
</span> </span>
</span> </span>
</el-tree> </el-tree>
@ -119,6 +126,19 @@ export default {
} }
return '' return ''
}, },
/**
* 判断文本是否溢出
* 业务背景当节点名称过长时需要显示 tooltip 提示完整名称
* 设计决策通过检查文本长度来判断是否需要显示 tooltip避免短文本也显示提示
* @param {string} text - 节点文本内容
* @returns {boolean} 是否溢出
*/
isTextOverflow(text) {
if (!text) return false
// 20
//
return text.length > 20
},
}, },
} }
</script> </script>
@ -196,6 +216,11 @@ export default {
.node-label { .node-label {
flex: 1; flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: inline-block;
max-width: 100%;
} }
&.node-online { &.node-online {

View File

@ -43,17 +43,27 @@
size="mini" size="mini"
type="success" type="success"
icon="el-icon-refresh" icon="el-icon-refresh"
:disabled="refreshCountdown > 0"
@click="handleRefresh" @click="handleRefresh"
> >
刷新 {{
refreshCountdown > 0
? `刷新(${refreshCountdown}s)`
: '刷新'
}}
</el-button> </el-button>
<el-button <el-button
size="mini" size="mini"
type="warning" type="warning"
icon="el-icon-switch-button" icon="el-icon-switch-button"
:disabled="restartCountdown > 0"
@click="handleRestart" @click="handleRestart"
> >
重启 {{
restartCountdown > 0
? `重启(${restartCountdown}s)`
: '重启'
}}
</el-button> </el-button>
</template> </template>
<template slot="handle" slot-scope="{ data }"> <template slot="handle" slot-scope="{ data }">
@ -119,31 +129,29 @@
{{ `${allSelect ? '取消全选' : '全选'}` }} {{ `${allSelect ? '取消全选' : '全选'}` }}
</el-checkbox> </el-checkbox>
</el-form-item> </el-form-item>
<el-form-item label="选择人员:" prop="workerIds"> <el-form-item label="未下发人员:" prop="unSendPersonIds">
<!-- <el-select
multiple
filterable
style="width: 100%"
placeholder="请选择人员"
:loading="personListLoading"
v-model="sendDownFormData.workerIds"
>
<el-option
:key="item.id"
:value="item.id"
v-for="item in personList"
:label="`${item.name}`"
/>
</el-select> -->
<el-checkbox-group <el-checkbox-group
v-model="sendDownFormData.workerIds" v-model="sendDownFormData.unSendPersonIds"
@change="handlePersonChange" @change="handleUnSendPersonChange"
> >
<el-checkbox <el-checkbox
:key="item.id" :key="item.id"
:label="item.id" :label="item.id"
v-for="item in personList" 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 }} {{ item.name }}
</el-checkbox> </el-checkbox>
@ -252,6 +260,14 @@ export default {
type: [String, Number], type: [String, Number],
default: '', default: '',
}, },
subId: {
type: [String, Number],
default: '',
},
teamId: {
type: [String, Number],
default: '',
},
}, },
data() { data() {
return { return {
@ -331,6 +347,11 @@ export default {
// //
sendDownFormData: { sendDownFormData: {
workerIds: [], workerIds: [],
//
unSendPersonIds: [],
//
sentPersonIds: [],
}, },
// //
configFormData: { configFormData: {
@ -339,24 +360,17 @@ export default {
}, },
// //
sendDownFormRules: { sendDownFormRules: {
workerIds: [ unSendPersonIds: [
{ {
required: true, required: true,
message: '请选择人员', message: '请选择人员',
trigger: 'change', trigger: 'change',
}, },
], ],
content: [
{
required: true,
message: '请输入下发内容',
trigger: 'blur',
},
],
}, },
// //
configFormRules: { configFormRules: {
workerIds: [ unSendPersonList: [
{ {
required: true, required: true,
message: '请选择人员', message: '请选择人员',
@ -376,6 +390,18 @@ export default {
personListLoading: false, personListLoading: false,
allSelect: false, allSelect: false,
selectedData: [], selectedData: [],
//
unSendPersonList: [],
//
sentPersonList: [],
//
refreshCountdown: 0,
//
refreshTimer: null,
//
restartCountdown: 0,
//
restartTimer: null,
} }
}, },
computed: { computed: {
@ -406,6 +432,21 @@ export default {
immediate: true, immediate: true,
}, },
}, },
/**
* 组件销毁前清理定时器
* 业务背景避免组件销毁后定时器仍在运行导致的内存泄漏
* 设计决策在组件销毁前清除所有定时器
*/
beforeDestroy() {
if (this.refreshTimer) {
clearInterval(this.refreshTimer)
this.refreshTimer = null
}
if (this.restartTimer) {
clearInterval(this.restartTimer)
this.restartTimer = null
}
},
methods: { methods: {
// //
getTableList() { getTableList() {
@ -489,9 +530,28 @@ export default {
try { try {
const res = await getAllPersonListAPI({ const res = await getAllPersonListAPI({
proId: this.proId, proId: this.proId,
deviceCode: this.macNo,
subId: this.subId,
teamId: this.teamId,
}) })
if (res.code === 200) { if (res.code === 200) {
this.personList = res?.data.map((item) => ({ // 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, id: item.workerId,
name: item.workerName, name: item.workerName,
isSelected: false, isSelected: false,
@ -508,22 +568,35 @@ export default {
this.sendDownDialogConfig.outerVisible = false this.sendDownDialogConfig.outerVisible = false
this.resetSendDownForm() this.resetSendDownForm()
}, },
// /**
* 重置下发表单
* 业务背景关闭弹框或重新打开时需要清空表单数据
* 设计决策需要重置所有表单字段包括未下发和已下发人员ID数组避免 undefined 导致的错误
*/
resetSendDownForm() { resetSendDownForm() {
this.sendDownFormData = { this.sendDownFormData = {
workerIds: [], workerIds: [],
//
unSendPersonIds: [],
//
sentPersonIds: [],
} }
this.allSelect = false
if (this.$refs.sendDownFormRef) { if (this.$refs.sendDownFormRef) {
this.$refs.sendDownFormRef.resetFields() this.$refs.sendDownFormRef.resetFields()
} }
}, },
// /**
* 提交下发表单
* 业务背景将选中的未下发人员下发到考勤机
* 设计决策使用 unSendPersonIds 作为提交参数因为表单绑定的是该字段
*/
handleSendDownSubmit() { handleSendDownSubmit() {
this.$refs.sendDownFormRef.validate((valid) => { this.$refs.sendDownFormRef.validate((valid) => {
if (valid) { if (valid) {
const params = { const params = {
deviceCode: this.macNo, deviceCode: this.macNo,
workerIds: this.sendDownFormData.workerIds, workerIds: this.sendDownFormData.unSendPersonIds,
} }
sendDownAPI(params) sendDownAPI(params)
.then((res) => { .then((res) => {
@ -575,27 +648,68 @@ export default {
} }
}) })
}, },
// /**
* 刷新考勤机
* 业务背景刷新考勤机数据获取最新的人员信息
* 设计决策刷新成功后启动10秒倒计时防止频繁刷新对服务器造成压力
*/
handleRefresh() { handleRefresh() {
if (!this.macNo) { if (!this.macNo) {
this.$modal.msgWarning('请先选择考勤机') this.$modal.msgWarning('请先选择考勤机')
return return
} }
//
if (this.refreshCountdown > 0) {
return
}
refreshAPI(this.macNo) refreshAPI(this.macNo)
.then((res) => { .then((res) => {
if (res.code === 200) { if (res.code === 200) {
this.$modal.msgSuccess('刷新成功') this.$modal.msgSuccess('刷新成功')
this.getTableList() this.getTableList()
//
this.startRefreshCountdown()
} }
}) })
.catch(() => {}) .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() { handleRestart() {
if (!this.macNo) { if (!this.macNo) {
this.$modal.msgWarning('请先选择考勤机') this.$modal.msgWarning('请先选择考勤机')
return return
} }
//
if (this.restartCountdown > 0) {
return
}
this.$modal this.$modal
.confirm('确定要重启该考勤机吗?') .confirm('确定要重启该考勤机吗?')
.then(() => { .then(() => {
@ -603,26 +717,76 @@ export default {
.then((res) => { .then((res) => {
if (res.code === 200) { if (res.code === 200) {
this.$modal.msgSuccess('重启成功') this.$modal.msgSuccess('重启成功')
//
this.startRestartCountdown()
} }
}) })
.catch(() => {}) .catch(() => {})
}) })
.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) { handleAllSelectChange(val) {
if (val) { if (val) {
this.sendDownFormData.workerIds = this.personList.map( this.sendDownFormData.unSendPersonIds =
this.unSendPersonList.map((item) => item.id)
this.sendDownFormData.sentPersonIds = this.sentPersonList.map(
(item) => item.id, (item) => item.id,
) )
} else { } else {
this.sendDownFormData.workerIds = [] this.sendDownFormData.unSendPersonIds = []
this.sendDownFormData.sentPersonIds = []
} }
}, },
// //
handlePersonChange(value) { handleUnSendPersonChange(value) {
console.log(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) { handleSelectionChange(e) {

View File

@ -40,6 +40,8 @@
ref="currentTableRef" ref="currentTableRef"
:mac-no="selectedMacNo" :mac-no="selectedMacNo"
:pro-id="selectedProId" :pro-id="selectedProId"
:sub-id="selectedSubId"
:team-id="selectedTeamId"
@refresh-tree="handleRefreshTree" @refresh-tree="handleRefreshTree"
/> />
</div> </div>
@ -67,6 +69,8 @@ export default {
return { return {
selectedMacNo: '', // selectedMacNo: '', //
selectedProId: '', // id selectedProId: '', // id
selectedSubId: '', // id
selectedTeamId: '', // id
selectedNodeName: '', // selectedNodeName: '', //
activeTab: 'person', // activeTab: 'person', //
} }
@ -89,6 +93,8 @@ export default {
this.selectedMacNo = data.id this.selectedMacNo = data.id
this.selectedProId = data.proId this.selectedProId = data.proId
this.selectedSubId = data.subId
this.selectedTeamId = data.teamId
this.selectedNodeName = data.name this.selectedNodeName = data.name
// if (data.level === 2) { // if (data.level === 2) {