From 8db21030dda8c80f05eca827180305a2654d1e20 Mon Sep 17 00:00:00 2001
From: BianLzhaoMin <11485688+bianliangzhaomin123@user.noreply.gitee.com>
Date: Wed, 3 Dec 2025 11:15:59 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../AttMacManage/components/leftTree.vue | 33 ++-
.../AttMacManage/components/rightTable.vue | 256 ++++++++++++++----
src/views/system/AttMacManage/index.vue | 6 +
3 files changed, 245 insertions(+), 50 deletions(-)
diff --git a/src/views/system/AttMacManage/components/leftTree.vue b/src/views/system/AttMacManage/components/leftTree.vue
index ec5e053..a58516b 100644
--- a/src/views/system/AttMacManage/components/leftTree.vue
+++ b/src/views/system/AttMacManage/components/leftTree.vue
@@ -34,11 +34,18 @@
:class="getStatusDotClass(node.data)"
>
- {{ node.label }}
+
+ {{ node.label }}
+
+
@@ -119,6 +126,19 @@ export default {
}
return ''
},
+ /**
+ * 判断文本是否溢出
+ * 业务背景:当节点名称过长时,需要显示 tooltip 提示完整名称
+ * 设计决策:通过检查文本长度来判断是否需要显示 tooltip,避免短文本也显示提示
+ * @param {string} text - 节点文本内容
+ * @returns {boolean} 是否溢出
+ */
+ isTextOverflow(text) {
+ if (!text) return false
+ // 根据实际容器宽度,这里假设超过 20 个字符可能需要省略
+ // 实际项目中可以根据容器宽度动态计算
+ return text.length > 20
+ },
},
}
@@ -196,6 +216,11 @@ export default {
.node-label {
flex: 1;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ display: inline-block;
+ max-width: 100%;
}
&.node-online {
diff --git a/src/views/system/AttMacManage/components/rightTable.vue b/src/views/system/AttMacManage/components/rightTable.vue
index 4ea268f..725fd8a 100644
--- a/src/views/system/AttMacManage/components/rightTable.vue
+++ b/src/views/system/AttMacManage/components/rightTable.vue
@@ -43,17 +43,27 @@
size="mini"
type="success"
icon="el-icon-refresh"
+ :disabled="refreshCountdown > 0"
@click="handleRefresh"
>
- 刷新
+ {{
+ refreshCountdown > 0
+ ? `刷新(${refreshCountdown}s)`
+ : '刷新'
+ }}
- 重启
+ {{
+ restartCountdown > 0
+ ? `重启(${restartCountdown}s)`
+ : '重启'
+ }}
@@ -119,31 +129,29 @@
{{ `${allSelect ? '取消全选' : '全选'}` }}
-
-
-
+
+ {{ item.name }}
+
+
+
+
+
+
{{ item.name }}
@@ -252,6 +260,14 @@ export default {
type: [String, Number],
default: '',
},
+ subId: {
+ type: [String, Number],
+ default: '',
+ },
+ teamId: {
+ type: [String, Number],
+ default: '',
+ },
},
data() {
return {
@@ -331,6 +347,11 @@ export default {
// 下发表单数据
sendDownFormData: {
workerIds: [],
+
+ // 未下发人员
+ unSendPersonIds: [],
+ // 已下发人员
+ sentPersonIds: [],
},
// 配置表单数据
configFormData: {
@@ -339,24 +360,17 @@ export default {
},
// 下发表单校验规则
sendDownFormRules: {
- workerIds: [
+ unSendPersonIds: [
{
required: true,
message: '请选择人员',
trigger: 'change',
},
],
- content: [
- {
- required: true,
- message: '请输入下发内容',
- trigger: 'blur',
- },
- ],
},
// 配置表单校验规则
configFormRules: {
- workerIds: [
+ unSendPersonList: [
{
required: true,
message: '请选择人员',
@@ -376,6 +390,18 @@ export default {
personListLoading: false,
allSelect: false,
selectedData: [],
+ // 未下发人员
+ unSendPersonList: [],
+ // 已下发人员
+ sentPersonList: [],
+ // 刷新倒计时(秒)
+ refreshCountdown: 0,
+ // 刷新倒计时定时器
+ refreshTimer: null,
+ // 重启倒计时(秒)
+ restartCountdown: 0,
+ // 重启倒计时定时器
+ restartTimer: null,
}
},
computed: {
@@ -406,6 +432,21 @@ export default {
immediate: true,
},
},
+ /**
+ * 组件销毁前清理定时器
+ * 业务背景:避免组件销毁后定时器仍在运行导致的内存泄漏
+ * 设计决策:在组件销毁前清除所有定时器
+ */
+ beforeDestroy() {
+ if (this.refreshTimer) {
+ clearInterval(this.refreshTimer)
+ this.refreshTimer = null
+ }
+ if (this.restartTimer) {
+ clearInterval(this.restartTimer)
+ this.restartTimer = null
+ }
+ },
methods: {
// 获取表格列表(供父组件调用)
getTableList() {
@@ -489,13 +530,32 @@ export default {
try {
const res = await getAllPersonListAPI({
proId: this.proId,
+ deviceCode: this.macNo,
+ subId: this.subId,
+ teamId: this.teamId,
})
if (res.code === 200) {
- this.personList = res?.data.map((item) => ({
- id: item.workerId,
- name: item.workerName,
- isSelected: false,
- }))
+ // 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)
@@ -508,22 +568,35 @@ export default {
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.workerIds,
+ workerIds: this.sendDownFormData.unSendPersonIds,
}
sendDownAPI(params)
.then((res) => {
@@ -575,27 +648,68 @@ export default {
}
})
},
- // 刷新
+ /**
+ * 刷新考勤机
+ * 业务背景:刷新考勤机数据,获取最新的人员信息
+ * 设计决策:刷新成功后启动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(() => {
@@ -603,26 +717,76 @@ export default {
.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.workerIds = this.personList.map(
+ this.sendDownFormData.unSendPersonIds =
+ this.unSendPersonList.map((item) => item.id)
+
+ this.sendDownFormData.sentPersonIds = this.sentPersonList.map(
(item) => item.id,
)
} else {
- this.sendDownFormData.workerIds = []
+ this.sendDownFormData.unSendPersonIds = []
+ this.sendDownFormData.sentPersonIds = []
}
},
- // 人员选择
- handlePersonChange(value) {
- console.log(value)
+ // 未下发人员选择
+ 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) {
diff --git a/src/views/system/AttMacManage/index.vue b/src/views/system/AttMacManage/index.vue
index 8a6cb9a..475a8e4 100644
--- a/src/views/system/AttMacManage/index.vue
+++ b/src/views/system/AttMacManage/index.vue
@@ -40,6 +40,8 @@
ref="currentTableRef"
:mac-no="selectedMacNo"
:pro-id="selectedProId"
+ :sub-id="selectedSubId"
+ :team-id="selectedTeamId"
@refresh-tree="handleRefreshTree"
/>
@@ -67,6 +69,8 @@ export default {
return {
selectedMacNo: '', // 选中的考勤机编号
selectedProId: '', // 选中的工程id
+ selectedSubId: '', // 选中的分包id
+ selectedTeamId: '', // 选中的班组id
selectedNodeName: '', // 选中的节点名称
activeTab: 'person', // 当前激活的标签页
}
@@ -89,6 +93,8 @@ export default {
this.selectedMacNo = data.id
this.selectedProId = data.proId
+ this.selectedSubId = data.subId
+ this.selectedTeamId = data.teamId
this.selectedNodeName = data.name
// if (data.level === 2) {