From 5270308151082506e0e6df2c72d278d2976ec860 Mon Sep 17 00:00:00 2001
From: liulijun <liulijun@hnkhzn.com>
Date: 星期三, 29 四月 2026 10:28:58 +0800
Subject: [PATCH] WCS设备监控

---
 项目代码/WCS/WCSClient/src/views/LineInfocopy.vue |  613 ++++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 399 insertions(+), 214 deletions(-)

diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WCS/WCSClient/src/views/LineInfocopy.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WCS/WCSClient/src/views/LineInfocopy.vue"
index 338a8f0..47cceb6 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WCS/WCSClient/src/views/LineInfocopy.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WCS/WCSClient/src/views/LineInfocopy.vue"
@@ -5,96 +5,46 @@
 		<img v-if="imgType === '1'" src="../../public/lines2.png" />
 		<label v-if="equipNo" class="equip-no">{{ equipNo }}</label>
 	</div>
-	<el-dialog v-model="dialogVisible" title="杈撻�佺嚎淇℃伅鏌ョ湅" :before-close="handleClose">
-		<el-form ref="$form" :model="lineItemInfo" label-position="left" label-width="100px" size="medium">
-			<el-row :gutter="20" type="flex" justify="start" align="top" tag="div">
-				<el-col :span="12" :offset="0" :push="0" :pull="0" tag="div">
-					<el-form-item label="璁惧缂栧彿锛�">
-						<j-el-description :value="equipNo" type="primary" ellipsis></j-el-description>
-					</el-form-item>
-				</el-col>
-				<el-col :span="12" :offset="0" :push="0" :pull="0" tag="div">
-					<el-form-item label="鏄惁鏈夌洏:">
-						<j-el-description :value="lineItemInfo.inStock" type="primary" ellipsis></j-el-description>
-					</el-form-item>
-				</el-col>
-			</el-row>
-			<el-row :gutter="20" type="flex" justify="start" align="top" tag="div">
-				<el-col :span="12" :offset="0" :push="0" :pull="0" tag="div">
-					<el-form-item label="浠诲姟鍙�:">
-						<j-el-description :value="lineItemInfo.taskNum" type="primary" ellipsis></j-el-description>
-					</el-form-item>
-				</el-col>
-				<el-col :span="12" :offset="0" :push="0" :pull="0" tag="div">
-					<el-form-item label="鎶ヨ浠g爜锛�">
-						<j-el-description :value="lineItemInfo.alarm" type="primary" ellipsis></j-el-description>
-					</el-form-item>
-				</el-col>
-			</el-row>
-
-		</el-form><el-divider />
-		<h4 style="margin-bottom: 20px;">鎵嬪姩鎿嶄綔</h4>
-		<el-form ref="form" :model="form" label-width="100px">
-			<el-row :gutter="20" type="flex" justify="start" align="top" tag="div">
-				<el-col :span="16" :offset="0" :push="0" :pull="0" tag="div">
-					<el-form-item label="浠�  鍔�  鍛�  浠�" prop="TargetAddress">
-						<el-select size="large" v-model="form.TaskType" placeholder="璇烽�夋嫨浠诲姟鍛戒护">
-							<el-option label="鍏ュ簱" value="1" />
-							<el-option label="鍑哄簱" value="2" />
-						</el-select>
-					</el-form-item>
-				</el-col>
-			</el-row>
-			<el-row :gutter="20" type="flex" justify="start" align="top" tag="div">
-				<el-col :span="16" :offset="0" :push="0" :pull="0" tag="div">
-					<el-form-item label="涓嬩竴鐩爣鍦板潃:">
-						<el-input size="large" v-model="form.TargetAddress" placeholder="璇疯緭鍏ヤ笅涓�鐩爣鍦板潃" />
-					</el-form-item>
-				</el-col>
-			</el-row>
-		</el-form>
-		<el-divider />
-		<el-row :gutter="20" type="flex" justify="start" align="top" tag="div">
-			<el-col :span="4" :offset="0" :push="0" :pull="0" tag="div">
-				<el-button type="primary" size="small" plain @click="SendCommand">
-					<i class="el-icon-check">鍙戦�佸懡浠�</i>
-				</el-button>
-			</el-col>
-			<el-col :span="4" :offset="0" :push="0" :pull="0" tag="div">
-				<el-button type="warning" size="small" plain @click="ConveyorLineReset">
-					<i class="el-icon-check">澶嶄綅</i>
-				</el-button>
-
-			</el-col>
-			<el-col :span="4" :offset="0" :push="0" :pull="0" tag="div">
-				<el-button type="danger" size="small" plain @click="ConveyorLineEmergencyStop">
-					<i class="el-icon-check">鍋滄</i>
-				</el-button>
-			</el-col>
-			<el-col :span="4" :offset="0" :push="0" :pull="0" tag="div">
-				<el-button type="danger" size="small" plain @click="ConveyorLineReturn">
-					<i class="el-icon-check">閫�鍥�</i>
-				</el-button>
-			</el-col>
-			<el-col :span="4" :offset="0" :push="0" :pull="0" tag="div">
-				<el-button type="danger" size="small" plain @click="ConveyorLineCancel">
-					<i class="el-icon-check">鍙栨秷浠诲姟</i>
-				</el-button>
-			</el-col>
-			<el-col :span="4" :offset="0" :push="0" :pull="0" tag="div">
-				<el-button type="danger" size="small" plain @click="ConveyorLineInitialize">
-					<i class="el-icon-check">宸ヤ綅鍒濆鍖�</i>
-				</el-button>
-			</el-col>
-		</el-row>
-		<template #footer>
-			<div class="dialog-footer">
-				<el-button @click="dialogVisible = false">鍙栨秷</el-button>
-				<el-button type="primary" @click="dialogVisible = false">
-					纭
-				</el-button>
+	<el-dialog v-model="dialogVisible" :before-close="handleClose" width="520px" class="modern-dialog">
+		<div class="dialog-header">
+			<h3 class="dialog-title">杈撻�佺嚎淇℃伅</h3>
+		</div>
+		<div class="dialog-content">
+			<div class="info-list">
+				<div class="info-item">
+					<span class="item-label">璁惧缂栧彿</span>
+					<span class="item-value">{{ equipNo || '鏃�' }}</span>
+				</div>
+				<div class="info-item">
+					<span class="item-label">浠诲姟鍙�</span>
+					<span class="item-value">{{ lineItemInfo.taskNum || '鏃�' }}</span>
+				</div>
+				<div class="info-item">
+					<span class="item-label">鏄惁鏈夌洏</span>
+					<span class="item-value">{{ lineItemInfo.inStock || '鏃�' }}</span>
+				</div>
+				<div class="info-item">
+					<span class="item-label">RFID</span>
+					<span class="item-value">{{ lineItemInfo.rfid || '鏃�' }}</span>
+				</div>
+				<div class="info-item">
+					<span class="item-label">鐢宠</span>
+					<span class="item-value">{{ lineItemInfo.request || '鏃�' }}</span>
+				</div>
+				<div class="info-item">
+					<span class="item-label">鐢宠鍙嶉</span>
+					<span class="item-value">{{ lineItemInfo.reresult || '鏃�' }}</span>
+				</div>
+				<div class="info-item">
+					<span class="item-label">绾稿嵎骞呭</span>
+					<span class="item-value">{{ lineItemInfo.width || '鏃�' }}</span>
+				</div>
+				<div class="info-item">
+					<span class="item-label">鎶ヨ淇℃伅</span>
+					<span class="item-value">{{ lineItemInfo.error || '鏃�' }}</span>
+				</div>
 			</div>
-		</template>
+		</div>
 	</el-dialog>
 </template>
 
@@ -119,11 +69,11 @@
 			default: "1",
 		},
 		positionX: {
-			type: Int32Array,
+			type: Number,
 			default: 1,
 		},
 		positionY: {
-			type: Int32Array,
+			type: Number,
 			default: 1,
 		},
 		url: {
@@ -136,144 +86,284 @@
 		},
 	},
 	data() {
-		return {
-			left: "500px",
-			top: "400px",
-			dialogVisible: false,
-			lineItemInfo: {
-				inStock: "",
-				taskNum: "",
-				alarm: "",
-			},
-			form: {
-				TaskType: "",
-				TargetAddress: "",
-				DeviceCode: "",
-			},
-		};
+			return {
+				left: "500px",
+				top: "400px",
+				dialogVisible: false,
+				fullscreenLoading: false,
+				isAlarm: false,
+				lineItemInfo: {
+					inStock: "",
+					taskNum: "",
+					rfid: "",
+					width: "",
+					request: "",
+					reresult: "",
+					error: "",
+				},
+				// 鐢宠鍙嶉鐘舵�佽窡韪�
+				feedbackTracking: {
+					currentTaskNum: "", // 褰撳墠浠诲姟鍙�
+					hasFeedback: false, // 鏄惁宸插弽棣堣繃
+					lastFeedbackValue: "" // 涓婃鍙嶉鐨勫��
+				},
+				form: {
+					TaskType: "",
+					TargetAddress: "",
+					DeviceCode: "",
+				},
+			};
 	},
 	mounted() {
-		const axisX = (this.positionX - 1) * 40 + 100;
+		const axisX = (this.positionX - 1) * 60 + 100;
 		const axisY = (this.positionY - 1) + 50;
 		this.$nextTick(() => {
 			this.left = `${axisX}px`;
 			this.top = `${axisY}px`;
 		});
+		
+		// 鐩戝惉鍏ㄥ眬conveyorLineDetails鐨勫彉鍖�
+		this.$watch(
+			() => this.$root.conveyorLineDetails,
+			() => {
+				this.updateAlarmStatus();
+			},
+			{ deep: true, immediate: true }
+		);
+		
+		// 寮�鍚畾鏃跺櫒锛屽畾鏈熸鏌ユ暟鎹彉鍖�
+		this.timer = setInterval(() => {
+			this.updateAlarmStatus();
+		}, 1000); // 姣�1绉掓鏌ヤ竴娆�
 	},
 	methods: {
+		// 鏇存柊鎶ヨ鐘舵��
+		updateAlarmStatus() {
+			const equipNoStr = String(this.equipNo);
+			if (this.$root.conveyorLineDetails && this.$root.conveyorLineDetails[equipNoStr]) {
+				const rawData = this.$root.conveyorLineDetails[equipNoStr];
+				this.isAlarm = rawData.isAlarm || false;
+				
+				// 鑾峰彇褰撳墠浠诲姟鍙�
+				const currentTaskNum = rawData.taskNum || '鏃�';
+				
+				// 妫�鏌ヤ换鍔″彿鏄惁鍙樺寲
+				if (currentTaskNum !== this.feedbackTracking.currentTaskNum) {
+					// 浠诲姟鍙峰彉鍖栵紝閲嶇疆鍙嶉鐘舵��
+					this.feedbackTracking.currentTaskNum = currentTaskNum;
+					this.feedbackTracking.hasFeedback = false;
+					this.feedbackTracking.lastFeedbackValue = "";
+				}
+				
+				// 澶勭悊鐢宠鍙嶉閫昏緫
+				let reresultValue = rawData.reresult || '鏃�';
+				
+				// 濡傛灉鏀跺埌浜嗗弽棣堝�硷紙闈炵┖闈炴棤锛変笖杩樻病鏈夊弽棣堣繃
+				if ((reresultValue !== '鏃�' && reresultValue !== '' && reresultValue !== undefined) && !this.feedbackTracking.hasFeedback) {
+					// 璁板綍宸插弽棣�
+					this.feedbackTracking.hasFeedback = true;
+					this.feedbackTracking.lastFeedbackValue = reresultValue;
+				}
+				
+				// 濡傛灉宸茬粡鍙嶉杩囷紝鏄剧ず"宸插弽棣�"
+				if (this.feedbackTracking.hasFeedback) {
+					reresultValue = '宸插弽棣�';
+				}
+				
+				// 鏇存柊lineItemInfo鏁版嵁
+				this.lineItemInfo = {
+					taskNum: currentTaskNum,
+					inStock: rawData.inStock || '鏃�',
+					rfid: rawData.rfid || '鏃�',
+					width: rawData.width || '鏃�',
+					request: rawData.request || '鏃�',
+					reresult: reresultValue,
+					error: rawData.error || '鏃�',
+				};
+			} else {
+				this.isAlarm = false;
+				this.lineItemInfo = {
+					taskNum: '',
+					inStock: '',
+					rfid: '',
+					width: '',
+					request: '',
+					reresult: '',
+					error: ''
+				};
+			}
+		},
+		// 缁勪欢閿�姣佹椂娓呴櫎瀹氭椂鍣�
+		beforeUnmount() {
+			if (this.timer) {
+				clearInterval(this.timer);
+			}
+		},
 		mouseClick() {
 			this.fullscreenLoading = true;
 			this.dialogVisible = true;
-			// 澶勭悊鐐瑰嚮浜嬩欢
-			this.http.post("api/DeviceInfo/GetConveyorLineInfo?DeviceChildCode=" + this.equipNo, null, "")
-				.then((x) => {
-					if (x.status) {
-						this.lineItemInfo = x.data;
-					} else {
-						this.$message({
-							type: "error",
-							message: x.message,
-						});
-					}
-				});
+			// 浠庡叏灞�鍙橀噺涓幏鍙栬緭閫佺嚎璇︾粏淇℃伅
+			const equipNoStr = String(this.equipNo);
+			if (this.$root.conveyorLineDetails && this.$root.conveyorLineDetails[equipNoStr]) {
+				// 鍏堣幏鍙栧師濮嬫暟鎹�
+				const rawData = this.$root.conveyorLineDetails[equipNoStr];
+				
+				// 鑾峰彇褰撳墠浠诲姟鍙�
+				const currentTaskNum = rawData.taskNum || '鏃�';
+				
+				// 妫�鏌ヤ换鍔″彿鏄惁鍙樺寲锛堜笌updateAlarmStatus淇濇寔涓�鑷达級
+				if (currentTaskNum !== this.feedbackTracking.currentTaskNum) {
+					this.feedbackTracking.currentTaskNum = currentTaskNum;
+					this.feedbackTracking.hasFeedback = false;
+					this.feedbackTracking.lastFeedbackValue = "";
+				}
+				
+				// 澶勭悊鐢宠鍙嶉閫昏緫
+				let reresultValue = rawData.reresult || '鏃�';
+				
+				// 濡傛灉鏀跺埌浜嗗弽棣堝�硷紙闈炵┖闈炴棤锛変笖杩樻病鏈夊弽棣堣繃
+				if ((reresultValue !== '鏃�' && reresultValue !== '' && reresultValue !== undefined) && !this.feedbackTracking.hasFeedback) {
+					this.feedbackTracking.hasFeedback = true;
+					this.feedbackTracking.lastFeedbackValue = reresultValue;
+				}
+				
+				// 濡傛灉宸茬粡鍙嶉杩囷紝鏄剧ず"宸插弽棣�"
+				if (this.feedbackTracking.hasFeedback) {
+					reresultValue = '宸插弽棣�';
+				}
 
+				// 澶嶅埗鏁版嵁鍒發ineItemInfo锛堟ā鏉夸腑缁戝畾鐨勫璞★級
+				this.lineItemInfo = {
+					taskNum: currentTaskNum,
+					inStock: rawData.inStock || '鏃�',
+					rfid: rawData.rfid || '鏃�',
+					width: rawData.width || '鏃�',
+					request: rawData.request || '鏃�',
+					reresult: reresultValue,
+					error: rawData.error || '鏃�',
+				};
+				// 淇濆瓨鎶ヨ鐘舵��
+				this.isAlarm = rawData.isAlarm || false;
+			} else {
+				// 濡傛灉娌℃湁鏁版嵁锛屼娇鐢ㄩ粯璁ゅ��
+				this.lineItemInfo = {
+					taskNum: '',
+					inStock: '',
+					rfid: '',
+					width: '',
+					request: '',
+					reresult: '',
+					error: ''
+				};
+				this.isAlarm = false;
+			}
+			this.fullscreenLoading = false;
+		},
+		handleClose() {
+			this.dialogVisible = false;
 			this.fullscreenLoading = false;
 		},
 
-		SendCommand() {
-			this.fullscreenLoading = true;
-			this.form.DeviceCode=this.equipNo;
-			this.http.post("api/DeviceInfo/ConveyorLineHandTask" ,this.form)
-				.then((x) => {
-					if (!x.status) {
-						this.$message.error(x.message);
-					} else {
-						this.$Message.success(x.message);
-					}
-				})
-				.finally(() => {
-					this.fullscreenLoading = false;
-				});
-		}, 
-		ConveyorLineReset() {
-			this.fullscreenLoading = true;
-			this.http.post("api/DeviceInfo/ConveyorLineReset?DeviceChildCode=" + this.equipNo, null, "")
-				.then((x) => {
-					if (!x.status) {
-						this.$message.error(x.message);
-					} else {
-						this.$Message.success(x.message);
+		// SendCommand() {
+		// 	this.fullscreenLoading = true;
+		// 	this.form.DeviceCode=this.equipNo;
+		// 	this.http.post("api/DeviceInfo/ConveyorLineHandTask" ,this.form)
+		// 		.then((x) => {
+		// 			if (!x.status) {
+		// 				this.$message.error(x.message);
+		// 			} else {
+		// 				this.$Message.success(x.message);
+		// 			}
+		// 		})
+		// 		.finally(() => {
+		// 			this.fullscreenLoading = false;
+		// 		});
+		// }, 
+		// ConveyorLineReset() {
+		// 	this.fullscreenLoading = true;
+		// 	this.http.post("api/DeviceInfo/ConveyorLineReset?DeviceChildCode=" + this.equipNo, null, "")
+		// 		.then((x) => {
+		// 			if (!x.status) {
+		// 				this.$message.error(x.message);
+		// 			} else {
+		// 				this.$Message.success(x.message);
 
-					}
-				})
-				.finally(() => {
-					this.fullscreenLoading = false;
-				});
-		},
-		ConveyorLineEmergencyStop() {
-			this.fullscreenLoading = true;
-			this.http.post("api/DeviceInfo/ConveyorLineEmergencyStop?DeviceChildCode=" + this.equipNo, null, "")
-				.then((x) => {
-					if (!x.status) {
-						this.$message.error(x.message);
-					} else {
-						this.$Message.success(x.message);
+		// 			}
+		// 		})
+		// 		.finally(() => {
+		// 			this.fullscreenLoading = false;
+		// 		});
+		// },
+		// ConveyorLineEmergencyStop() {
+		// 	this.fullscreenLoading = true;
+		// 	this.http.post("api/DeviceInfo/ConveyorLineEmergencyStop?DeviceChildCode=" + this.equipNo, null, "")
+		// 		.then((x) => {
+		// 			if (!x.status) {
+		// 				this.$message.error(x.message);
+		// 			} else {
+		// 				this.$Message.success(x.message);
 
-					}
-				})
-				.finally(() => {
-					this.fullscreenLoading = false;
-				});
-		}, 
-		ConveyorLineReturn() {
-			this.fullscreenLoading = true;
-			this.http.post("api/DeviceInfo/ConveyorLineReturn?DeviceChildCode=" + this.equipNo, null, "")
-				.then((x) => {
-					if (!x.status) {
-						this.$message.error(x.message);
-					} else {
-						this.$Message.success(x.message);
-					}
-				})
-				.finally(() => {
-					this.fullscreenLoading = false;
-				});
-		},
-		ConveyorLineCancel() {
-			this.fullscreenLoading = true;
-			this.http.post("api/DeviceInfo/ConveyorLineCancel?DeviceChildCode=" + this.equipNo, null, "")
-				.then((x) => {
-					if (!x.status) {
-						this.$message.error(x.message);
-					} else {
-						this.$Message.success(x.message);
-					}
-				})
-				.finally(() => {
-					this.fullscreenLoading = false;
-				});
-		},
-		ConveyorLineInitialize() {
-			this.fullscreenLoading = true;
-			this.http.post("api/DeviceInfo/ConveyorLineInitialize?DeviceChildCode=" + this.equipNo, null, "")
-				.then((x) => {
-					if (!x.status) {
-						this.$message.error(x.message);
-					} else {
-						this.$Message.success(x.message);
-					}
-				})
-				.finally(() => {
-					this.fullscreenLoading = false;
-				});
-		},
+		// 			}
+		// 		})
+		// 		.finally(() => {
+		// 			this.fullscreenLoading = false;
+		// 		});
+		// }, 
+		// ConveyorLineReturn() {
+		// 	this.fullscreenLoading = true;
+		// 	this.http.post("api/DeviceInfo/ConveyorLineReturn?DeviceChildCode=" + this.equipNo, null, "")
+		// 		.then((x) => {
+		// 			if (!x.status) {
+		// 				this.$message.error(x.message);
+		// 			} else {
+		// 				this.$Message.success(x.message);
+		// 			}
+		// 		})
+		// 		.finally(() => {
+		// 			this.fullscreenLoading = false;
+		// 		});
+		// },
+		// ConveyorLineCancel() {
+		// 	this.fullscreenLoading = true;
+		// 	this.http.post("api/DeviceInfo/ConveyorLineCancel?DeviceChildCode=" + this.equipNo, null, "")
+		// 		.then((x) => {
+		// 			if (!x.status) {
+		// 				this.$message.error(x.message);
+		// 			} else {
+		// 				this.$Message.success(x.message);
+		// 			}
+		// 		})
+		// 		.finally(() => {
+		// 			this.fullscreenLoading = false;
+		// 		});
+		// },
+		// ConveyorLineInitialize() {
+		// 	this.fullscreenLoading = true;
+		// 	this.http.post("api/DeviceInfo/ConveyorLineInitialize?DeviceChildCode=" + this.equipNo, null, "")
+		// 		.then((x) => {
+		// 			if (!x.status) {
+		// 				this.$message.error(x.message);
+		// 			} else {
+		// 				this.$Message.success(x.message);
+		// 			}
+		// 		})
+		// 		.finally(() => {
+		// 			this.fullscreenLoading = false;
+		// 		});
+		// },
 		update() {
-			return !this.condition ? 'custom-img' : 'custom-img-color'
+			if (this.isAlarm) {
+				return 'custom-img-alarm';
+			} else if (this.lineItemInfo.inStock === '鏄�') {
+				return 'custom-img-color';
+			} else {
+				return 'custom-img';
+			}
 		},
 		startTimer() {
 			// 寮�鍚畾鏃跺櫒锛屾瘡3绉掓墽琛屼竴娆�
 			this.timer1 = setInterval(() => {
-				update();
+				this.update();
 			}, 500);
 		},
 	},
@@ -284,13 +374,20 @@
 .custom-img {
 	position: relative;
 	display: inline-block;
-	/* background-color:  #d9ecff ; */
 }
 
 .custom-img-color {
 	position: relative;
 	display: inline-block;
 	background-color: #05fa7f;
+	color: white;
+	text-align: center;
+}
+
+.custom-img-alarm {
+	position: relative;
+	display: inline-block;
+	background-color: #ff4d4f;
 	color: white;
 	text-align: center;
 }
@@ -307,19 +404,107 @@
 } */
 
 .custom-img img {
-	width: 40px;
-	height: 40px;
+	width: 80px;
+	height: 50px;
 }
 
 .custom-img-color img {
-	width: 40px;
-	height: 40px;
+	width: 80px;
+	height: 50px;
+}
+
+.custom-img-alarm img {
+	width: 80px;
+	height: 50px;
 }
 
 .equip-no {
 	position: absolute;
-	top: 15px;
-	font-size: 12px;
-	margin-left: -35px;
+	top: 50%;
+	left: 50%;
+	transform: translate(-50%, -50%);
+	font-size: 25px;
+	text-align: center;
+	width: 100%;
+}
+
+.modern-dialog {
+	border-radius: 16px !important;
+	overflow: hidden;
+	box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);
+}
+
+.modern-dialog .el-dialog__header {
+	display: none;
+}
+
+.modern-dialog .el-dialog__body {
+	padding: 0;
+	margin: 0;
+}
+
+.dialog-header {
+	background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
+	padding: 20px 24px;
+	text-align: center;
+}
+
+.dialog-title {
+	color: #fff;
+	font-size: 18px;
+	font-weight: 600;
+	margin: 0;
+	letter-spacing: 2px;
+}
+
+.dialog-content {
+	padding: 28px;
+	background: #f8fafc;
+	display: flex;
+	justify-content: center;
+}
+
+.info-list {
+	width: 100%;
+	max-width: 420px;
+	display: flex;
+	flex-direction: column;
+	gap: 12px;
+}
+
+.info-item {
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	padding: 16px 20px;
+	background: #fff;
+	border-radius: 12px;
+	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
+	transition: all 0.3s ease;
+}
+
+.info-item:hover {
+	transform: translateX(4px);
+	box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
+}
+
+.item-label {
+	font-size: 14px;
+	color: #6b7280;
+	font-weight: 500;
+	min-width: 80px;
+	text-align: left;
+}
+
+.item-value {
+	font-size: 15px;
+	color: #1f2937;
+	font-weight: 500;
+	text-align: right;
+	flex: 1;
+	margin-left: 20px;
+	word-break: break-all;
+	padding-left: 20px;
+	border-left: 1px solid #e5e7eb;
 }
 </style>

--
Gitblit v1.9.3