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.

575 lines
10 KiB
Vue

<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 border stripe emptyText="暂无参数数据">
<uni-tr>
<uni-th width="200" align="center">参数名称</uni-th>
<uni-th width="250" align="center">参数值</uni-th>
<uni-th width="150" align="center">操作</uni-th>
</uni-tr>
<uni-tr v-for="(param, index) in hallParams" :key="param.key">
<uni-td align="center">
<text class="param-name">{{ param.name }}</text>
</uni-td>
<uni-td align="center">
<view v-if="!param.editing" class="param-value">
<text>{{ param.value }}</text>
<text class="param-unit" v-if="param.unit">{{ param.unit }}</text>
</view>
<view v-else class="param-edit">
<tn-input v-model="param.editValue" :type="param.inputType || 'text'"
:placeholder="`请输入${param.name}`" size="small" border />
</view>
</uni-td>
<uni-td align="center">
<view class="param-actions">
<tn-button v-if="!param.editing" size="sm" type="primary" plain
@click="startEditParam(index)">
编辑
</tn-button>
<view v-else class="edit-actions">
<tn-button size="sm" type="primary" @click="saveParam(index)">
保存
</tn-button>
<tn-button size="sm" type="default" @click="cancelEditParam(index)">
取消
</tn-button>
</view>
</view>
</uni-td>
</uni-tr>
</uni-table>
</view>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import { ref, reactive, computed, onMounted } from 'vue'
//
const hallParams = ref([
{
key: 'hallName',
name: '',
value: '',
editing: false,
editValue: '',
inputType: 'text'
},
{
key: 'workTimeStart',
name: '',
value: '09:00',
editing: false,
editValue: '',
inputType: 'text'
},
{
key: 'workTimeEnd',
name: '',
value: '17:00',
editing: false,
editValue: '',
inputType: 'text'
},
{
key: 'lunchStart',
name: '',
value: '12:00',
editing: false,
editValue: '',
inputType: 'text'
},
{
key: 'lunchEnd',
name: '',
value: '13:30',
editing: false,
editValue: '',
inputType: 'text'
},
{
key: 'maxWaiting',
name: '',
value: '50',
editing: false,
editValue: '',
inputType: 'number',
unit: ''
},
{
key: 'serviceTimeout',
name: '',
value: '30',
editing: false,
editValue: '',
inputType: 'number',
unit: ''
},
{
key: 'weekendService',
name: '',
value: '',
editing: false,
editValue: '',
inputType: 'text'
}
])
//
const startEditParam = (index : number) => {
hallParams.value.forEach((param, i) => {
if (i === index) {
param.editing = true
param.editValue = param.value
} else {
param.editing = false
}
})
}
const saveParam = (index : number) => {
const param = hallParams.value[index]
if (param.editValue.trim()) {
param.value = param.editValue
param.editing = false
uni.showToast({
title: '参数保存成功',
icon: 'success'
})
// 实际项目中这里应该调用API保存到服务器
console.log(`保存参数: ${param.name} = ${param.value}`)
} else {
uni.showToast({
title: '参数值不能为空',
icon: 'none'
})
}
}
const cancelEditParam = (index : number) => {
hallParams.value[index].editing = false
hallParams.value[index].editValue = ''
}
// 批量编辑参数
const handleEditParams = () => {
if (editing.value) {
// 保存所有编辑中的参数
hallParams.value.forEach((param, index) => {
if (param.editing) {
saveParam(index)
}
})
} else {
// 进入编辑模式
uni.showToast({
title: '进入编辑模式',
icon: 'success'
})
}
}
const backToIndex = () => {
uni.navigateTo({
url: '/pages/index/index'
})
}
onMounted(() => {
// 可以在这里初始化数据或调用API
})
</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;
}
.content {
padding: 20rpx;
}
// 通用卡片样式
.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;
}
}
}
}
// 参数表格样式
.param-name {
font-size: 26rpx;
color: #333;
font-weight: 500;
}
.param-value {
display: flex;
align-items: center;
justify-content: center;
gap: 8rpx;
.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>