You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

577 lines
11 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="page-container">
<div class="top-div">
<div></div>
<tn-button width="80px" height="32px" :plain="true" text-color="#0099ff" @click="backToIndex">
<uni-icons type="arrow-left" size="18" color="#0099ff" style="margin-right: 5px;"></uni-icons>
</tn-button>
</div>
<view class="content">
<!-- 大厅参数管理 -->
<view class="params-section">
<view class="section-card">
<view class="section-header">
<text class="section-title">大厅参数配置</text>
<!-- <tn-button size="sm" type="primary" plain @click="handleEditParams" :disabled="editing">
<uni-icons type="compose" size="16" color="#1890ff"></uni-icons>
{{ editing ? '保存中...' : '编辑参数' }}
</tn-button> -->
</view>
<uni-table class="params-table" border stripe emptyText="暂无参数数据">
<uni-tr>
<uni-th align="center">操作</uni-th>
<uni-th align="center">参数名称</uni-th>
<uni-th align="center">参数Key</uni-th>
<uni-th align="center">参数值</uni-th>
</uni-tr>
<uni-tr v-for="(param, index) in hallParams" :key="param.key">
<uni-td align="center">
<view class="param-actions">
<tn-button size="sm" type="primary" plain @click="startEditParam(index)">
编辑
</tn-button>
</view>
</uni-td>
<uni-td align="center">
<text class="param-name">{{ param.name }}</text>
</uni-td>
<uni-td align="center">
<text class="param-key">{{ param.key }}</text>
</uni-td>
<uni-td align="center">
<view class="param-value">
<text>{{ param.value }}</text>
</view>
</uni-td>
</uni-tr>
</uni-table>
</view>
</view>
</view>
<!-- 参数编辑弹窗 -->
<uni-popup ref="editPopup" type="center" background-color="#fff">
<view class="popup-content" v-if="selectedParam">
<view class="popup-header">
<text class="popup-title">编辑参数</text>
<uni-icons type="close" size="20" color="#999" @click="closeEditPopup"></uni-icons>
</view>
<view class="popup-body">
<view class="detail-grid">
<view class="detail-item">
<text class="detail-label">参数名称:</text>
<text class="detail-value">{{ selectedParam.name }}</text>
</view>
<view class="detail-item">
<text class="detail-label">参数Key</text>
<text class="detail-value">{{ selectedParam.key }}</text>
</view>
<view class="detail-item">
<text class="detail-label">参数值:</text>
<view class="detail-value" style="flex: 1; margin-left: 16rpx;">
<tn-input v-model="editValue" type="text" :placeholder="`请输入${selectedParam.name}`" border />
</view>
</view>
</view>
</view>
<view class="popup-footer">
<tn-button type="primary" @click="confirmSaveParam">保存</tn-button>
</view>
</view>
</uni-popup>
</view>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { getSystemList, updateSysValue } from '@/api/system.js'
//
const hallParams = ref<any[]>([])
const editPopup = ref()
const selectedParam = ref<any>(null)
const editValue = ref('')
const fetchSystemList = async () => {
try {
const res = await getSystemList()
console.log(res)
const list = Array.isArray(res.list) ? res.list : []
hallParams.value = list.map((item : any) => ({
key: item.key,
name: item.memo,
value: item.value
}))
} catch (error) {
console.log('获取大厅参数失败', error)
uni.showToast({
title: '获取参数失败',
icon: 'none'
})
}
}
// 参数编辑处理(弹窗)
const startEditParam = (index : number) => {
const current = hallParams.value[index]
selectedParam.value = { ...current }
editValue.value = String(current?.value ?? '')
editPopup.value?.open()
}
const closeEditPopup = () => {
editPopup.value?.close()
}
const confirmSaveParam = () => {
const value = editValue.value?.toString().trim()
if (!selectedParam.value?.key) {
uni.showToast({
title: '参数Key缺失',
icon: 'none'
})
return
}
if (!value) {
uni.showToast({
title: '参数值不能为空',
icon: 'none'
})
return
}
uni.showModal({
title: '二次确认',
content: `确认将 ${selectedParam.value.name} 修改为 ${value} 吗?`,
success: async (res) => {
if (!res.confirm) return
console.log(selectedParam.value.key)
try {
await updateSysValue({
key: selectedParam.value.key,
value
})
uni.showToast({
title: '修改成功',
icon: 'success'
})
closeEditPopup()
await fetchSystemList()
} catch (error) {
console.log('修改大厅参数失败', error)
uni.showToast({
title: '修改失败',
icon: 'none'
})
}
}
})
}
const backToIndex = () => {
uni.navigateTo({
url: '/pages/index/index'
})
}
onLoad(() => {
fetchSystemList()
})
</script>
<style lang="scss" scoped>
.page-container {
min-height: 100vh;
background-color: #f5f7fa;
}
.top-div {
display: flex;
justify-content: space-between;
background-color: #fff;
padding: 6vh 20px 10px 20px;
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 100;
box-sizing: border-box;
}
.content {
padding: 20rpx;
margin-top: 100px;
}
// 通用卡片样式
.section-card {
background: #fff;
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 30rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30rpx;
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
.status-summary {
display: flex;
gap: 20rpx;
.summary-item {
font-size: 24rpx;
color: #666;
}
}
}
// 窗口组样式
.window-group {
margin-bottom: 40rpx;
.group-title {
display: flex;
align-items: center;
gap: 10rpx;
margin-bottom: 20rpx;
font-size: 28rpx;
font-weight: bold;
color: #333;
}
}
// 人工窗口网格
.windows-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20rpx;
.window-item {
padding: 24rpx;
border-radius: 12rpx;
border: 2rpx solid #e8e8e8;
transition: all 0.3s;
&.window-free {
border-color: #52c41a;
background: #f6ffed;
}
&.window-busy {
border-color: #fa541c;
background: #fff2e8;
}
&.window-pause {
border-color: #faad14;
background: #fffbe6;
}
&:active {
transform: scale(0.98);
}
.window-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15rpx;
.window-number {
font-size: 28rpx;
font-weight: bold;
color: #333;
}
.window-status {
padding: 6rpx 12rpx;
border-radius: 12rpx;
font-size: 20rpx;
font-weight: 500;
&.status-free {
background: #52c41a;
color: #fff;
}
&.status-busy {
background: #fa541c;
color: #fff;
}
&.status-pause {
background: #faad14;
color: #fff;
}
}
}
.window-info {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10rpx;
.window-type {
font-size: 24rpx;
color: #666;
}
.waiting-count {
font-size: 22rpx;
color: #fa541c;
font-weight: 500;
}
}
.window-current {
.current-task {
font-size: 22rpx;
color: #333;
background: #f0f0f0;
padding: 4rpx 8rpx;
border-radius: 6rpx;
}
.no-task {
font-size: 22rpx;
color: #999;
font-style: italic;
}
}
}
}
// 自助设备网格
.devices-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20rpx;
.device-item {
padding: 24rpx;
border-radius: 12rpx;
border: 2rpx solid #e8e8e8;
text-align: center;
&.device-free {
border-color: #52c41a;
background: #f6ffed;
}
&.device-busy {
border-color: #fa541c;
background: #fff2e8;
}
&.device-maintenance {
border-color: #faad14;
background: #fffbe6;
}
.device-icon {
margin-bottom: 15rpx;
}
.device-info {
.device-name {
display: block;
font-size: 24rpx;
color: #333;
margin-bottom: 8rpx;
}
.device-status {
display: block;
font-size: 20rpx;
margin-bottom: 5rpx;
&.status-free {
color: #52c41a;
}
&.status-busy {
color: #fa541c;
}
&.status-maintenance {
color: #faad14;
}
}
.device-usage {
font-size: 18rpx;
color: #999;
}
}
}
}
// 参数表格样式
.params-table {
:deep(.uni-table-th),
:deep(.uni-table-td) {
white-space: normal !important;
word-break: break-all;
overflow-wrap: anywhere;
}
}
.param-name {
font-size: 26rpx;
color: #333;
font-weight: 500;
word-break: break-all;
}
.param-key {
font-size: 24rpx;
color: #666;
word-break: break-all;
}
.param-value {
display: flex;
align-items: center;
justify-content: center;
gap: 8rpx;
word-break: break-all;
white-space: normal;
.param-unit {
font-size: 22rpx;
color: #999;
}
}
.param-edit {
display: flex;
justify-content: center;
}
.param-actions {
display: flex;
justify-content: center;
.edit-actions {
display: flex;
gap: 10rpx;
}
}
// 弹窗样式
.popup-content {
width: 650rpx;
border-radius: 20rpx;
overflow: hidden;
background: #fff;
}
.popup-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
border-bottom: 1rpx solid #f0f0f0;
.popup-title {
font-size: 28rpx;
font-weight: bold;
color: #333;
}
}
.popup-body {
padding: 30rpx;
max-height: 60vh;
overflow-y: auto;
}
.detail-grid {
.detail-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15rpx 0;
border-bottom: 1rpx solid #f5f5f5;
.detail-label {
font-size: 26rpx;
color: #666;
}
.detail-value {
font-size: 26rpx;
color: #333;
font-weight: 500;
}
.status-badge {
padding: 6rpx 12rpx;
border-radius: 12rpx;
font-size: 20rpx;
color: #fff;
&.status-free {
background: #52c41a;
}
&.status-busy {
background: #fa541c;
}
&.status-pause {
background: #faad14;
}
}
}
}
.waiting-list {
margin-top: 30rpx;
.list-title {
font-size: 26rpx;
font-weight: bold;
color: #333;
margin-bottom: 15rpx;
}
.list-items {
.list-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12rpx 0;
border-bottom: 1rpx solid #f5f5f5;
.queue-number {
font-size: 24rpx;
color: #333;
}
.estimate-time {
font-size: 22rpx;
color: #999;
}
}
}
}
.popup-footer {
padding: 30rpx;
border-top: 1rpx solid #f0f0f0;
text-align: center;
}
</style>