Files
threeonecheck_web/components/AreaFormPopup.vue
2026-02-08 09:30:43 +08:00

264 lines
4.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="popup-mask" v-if="visible" @click="handleClose">
<view class="popup-content" @click.stop>
<view class="popup-header">
<view class="popup-title text-bold">{{ isEdit ? '编辑区域' : '新增区域' }}</view>
<view class="popup-close" @click="handleClose">×</view>
</view>
<view class="popup-body">
<!-- 区域名称 -->
<view class="flex margin-bottom-sm">
<view>区域名称</view>
<view class="text-red">*</view>
</view>
<input
class="form-input"
v-model="formData.name"
placeholder="请输入区域名称"
/>
<!-- 区域颜色 -->
<view class="flex margin-bottom-sm margin-top">
<view>区域颜色</view>
<view class="text-red">*</view>
</view>
<view class="flex align-center">
<input
class="color-input flex-sub"
v-model="formData.color"
placeholder="#FF5733"
/>
<view class="color-preview" :style="{ backgroundColor: formData.color }"></view>
</view>
<!-- 预设颜色 -->
<view class="margin-top margin-bottom-sm text-gray">预设颜色</view>
<view class="color-grid">
<view
v-for="(color, index) in presetColors"
:key="color + index"
class="color-item"
:class="{ 'color-item-active': formData.color === color }"
:style="{ backgroundColor: color }"
@click="selectColor(color)"
></view>
</view>
</view>
<view class="popup-footer">
<button class="btn-cancel" @click="handleClose">取消</button>
<button class="btn-confirm bg-blue" @click="handleSubmit" :loading="loading">确定</button>
</view>
</view>
</view>
</template>
<script setup>
import { ref, reactive, watch } from 'vue';
const props = defineProps({
visible: {
type: Boolean,
default: false
},
isEdit: {
type: Boolean,
default: false
},
editData: {
type: Object,
default: () => ({})
},
loading: {
type: Boolean,
default: false
}
});
const emit = defineEmits(['update:visible', 'submit', 'close']);
// 表单数据
const formData = reactive({
name: '',
color: '#FF5733'
});
// 预设颜色
const presetColors = [
'#2563eb', '#ef4444', '#10b981', '#f59e0b', '#6366f1', '#ec4899', '#06b6d4',
'#84cc16', '#f97316', '#4f46e5', '#dc2626', '#f59e0b', '#d97706', '#8b5cf6',
'#db2777'
];
// 监听 editData 变化,填充表单
watch(() => props.editData, (newVal) => {
if (newVal && Object.keys(newVal).length > 0) {
formData.name = newVal.name || '';
formData.color = newVal.color || '#FF5733';
}
}, { immediate: true, deep: true });
// 监听弹窗关闭,重置表单
watch(() => props.visible, (newVal) => {
if (!newVal) {
resetForm();
}
});
// 选择预设颜色
const selectColor = (color) => {
formData.color = color;
};
// 重置表单
const resetForm = () => {
formData.name = '';
formData.color = '#FF5733';
};
// 关闭弹窗
const handleClose = () => {
emit('update:visible', false);
emit('close');
};
// 提交表单
const handleSubmit = () => {
// 表单验证
if (!formData.name) {
uni.showToast({ title: '请输入区域名称', icon: 'none' });
return;
}
if (!formData.color) {
uni.showToast({ title: '请选择区域颜色', icon: 'none' });
return;
}
emit('submit', {
name: formData.name,
color: formData.color
});
};
</script>
<style lang="scss" scoped>
// 弹窗遮罩
.popup-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 999;
}
// 弹窗内容
.popup-content {
width: 600rpx;
background: #fff;
border-radius: 20rpx;
overflow: hidden;
}
.popup-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
border-bottom: 1rpx solid #eee;
}
.popup-title {
font-size: 32rpx;
}
.popup-close {
font-size: 40rpx;
color: #999;
}
.popup-body {
padding: 30rpx;
}
.popup-footer {
display: flex;
padding: 20rpx 30rpx 30rpx;
button {
flex: 1;
height: 80rpx;
line-height: 80rpx;
border-radius: 40rpx;
font-size: 30rpx;
margin: 0 10rpx;
&::after {
border: none;
}
}
.btn-cancel {
background: #f5f5f5;
color: #666;
}
.btn-confirm {
color: #fff;
}
}
// 表单输入框
.form-input {
width: 100%;
height: 70rpx;
padding: 0 20rpx;
border: 2rpx solid #dadbde;
border-radius: 8rpx;
font-size: 28rpx;
box-sizing: border-box;
}
// 颜色输入框
.color-input {
height: 70rpx;
padding: 0 20rpx;
border: 2rpx solid #dadbde;
border-radius: 8rpx;
font-size: 28rpx;
box-sizing: border-box;
}
// 颜色预览
.color-preview {
width: 70rpx;
height: 70rpx;
border-radius: 8rpx;
margin-left: 20rpx;
flex-shrink: 0;
border: 2rpx solid #e5e5e5;
}
// 预设颜色网格
.color-grid {
display: flex;
flex-wrap: wrap;
gap: 16rpx;
}
.color-item {
width: 70rpx;
height: 70rpx;
border-radius: 12rpx;
border: 4rpx solid transparent;
box-sizing: border-box;
}
.color-item-active {
border-color: #333;
}
</style>