18034727885
2026-04-14 370014cbb9ec1ef64e7e42bb4f9a12671461d8e4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
package com.xw.yunwei.model
 
import com.google.gson.annotations.SerializedName
 
/**
 * 电子围栏
 */
data class AreaModel(
 
    /**
     * 自增id,电子围栏唯一标识
     */
    @SerializedName("id")
    val id: Long? = null,
 
    /**
     * 围栏编号唯一
     * 规则:城市首字母-类型简写-4位自增流水号(如 SZ-OP-001)
     */
    @SerializedName("electronicNumber")
    val electronicNumber: String? = null,
 
    /**
     * 围栏名称
     */
    @SerializedName("electronicName")
    val electronicName: String? = null,
 
    /**
     * 城市code
     */
    @SerializedName("cityCode")
    val cityCode: String? = null,
 
    /**
     * 围栏状态
     * 0=草稿 1=待启用 2=启用中 3=已停用
     */
    @SerializedName("status")
    val status: Int? = null,
 
    /**
     * 生效类型
     * 1=立即生效 2=定时生效
     */
    @SerializedName("effectType")
    val effectType: Int? = null,
 
    /**
     * 生效时间
     * 当effectType=2时有效
     */
    @SerializedName("effectTime")
    val effectTime: String? = null,
 
    /**
     * 失效类型
     * 1=永不失效 2=定时失效
     */
    @SerializedName("failureType")
    val failureType: Int? = null,
 
    /**
     * 失效时间
     * 当failureType=2时有效
     */
    @SerializedName("failureTime")
    val failureTime: String? = null,
 
    /**
     * 运营区域数量
     */
    @SerializedName("operatingAreaCount")
    val operatingAreaCount: Long? = null,
 
    /**
     * 禁行区域数量
     */
    @SerializedName("prohibitedAreaCount")
    val prohibitedAreaCount: Long? = null,
 
    /**
     * 运营策略,JSON字符串格式
     */
    @SerializedName("operationStrategy")
    val operationStrategy: String? = null,
 
    /**
     * 是否删除
     * false=未删除(0) true=已删除(1)
     */
    @SerializedName("deleted")
    val deleted: Boolean? = null,
 
    /**
     * 记录创建人,前端忽略
     */
    @SerializedName("createBy")
    val createBy: String? = null,
 
    /**
     * 记录创建时间,前端忽略
     */
    @SerializedName("createTime")
    val createTime: String? = null,
 
    /**
     * 记录修改人,前端忽略
     */
    @SerializedName("updateBy")
    val updateBy: String? = null,
 
    /**
     * 记录修改时间,前端忽略
     */
    @SerializedName("updateTime")
    val updateTime: String? = null
) {
 
    // ==================== 枚举定义 ====================
 
    /**
     * 围栏状态枚举
     */
    enum class FenceStatus(val value: Int, val description: String) {
        DRAFT(0, "草稿"),
        PENDING_ENABLE(1, "待启用"),
        ENABLED(2, "启用中"),
        DISABLED(3, "已停用");
 
        companion object {
            fun fromValue(value: Int?): FenceStatus? = FenceStatus.entries.find { it.value == value }
        }
    }
 
    /**
     * 生效类型枚举
     */
    enum class EffectType(val value: Int, val description: String) {
        IMMEDIATE(1, "立即生效"),
        SCHEDULED(2, "定时生效");
 
        companion object {
            fun fromValue(value: Int?): EffectType? = EffectType.entries.find { it.value == value }
        }
    }
 
    /**
     * 失效类型枚举
     */
    enum class FailureType(val value: Int, val description: String) {
        NEVER(1, "永不失效"),
        SCHEDULED(2, "定时失效");
 
        companion object {
            fun fromValue(value: Int?): FailureType? = FailureType.entries.find { it.value == value }
        }
    }
 
    // ==================== 便捷方法 ====================
 
    /**
     * 获取围栏状态枚举
     */
    fun getStatusEnum(): FenceStatus? = FenceStatus.fromValue(status)
 
    /**
     * 获取生效类型枚举
     */
    fun getEffectTypeEnum(): EffectType? = EffectType.fromValue(effectType)
 
    /**
     * 获取失效类型枚举
     */
    fun getFailureTypeEnum(): FailureType? = FailureType.fromValue(failureType)
 
    /**
     * 是否已删除
     */
    fun isDeleted(): Boolean = deleted == true
 
    /**
     * 是否处于草稿状态
     */
    fun isDraft(): Boolean = status == 0
 
    /**
     * 是否待启用
     */
    fun isPendingEnable(): Boolean = status == 1
 
    /**
     * 是否启用中
     */
    fun isEnabled(): Boolean = status == 2
 
    /**
     * 是否已停用
     */
    fun isDisabled(): Boolean = status == 3
 
    /**
     * 是否立即生效
     */
    fun isImmediateEffect(): Boolean = effectType == 1
 
    /**
     * 是否定时生效
     */
    fun isScheduledEffect(): Boolean = effectType == 2
 
    /**
     * 是否永不失效
     */
    fun isNeverExpire(): Boolean = failureType == 1
 
    /**
     * 是否定时失效
     */
    fun isScheduledExpire(): Boolean = failureType == 2
 
    /**
     * 获取区域总数(运营区域+禁行区域)
     */
    fun getTotalAreaCount(): Long = (operatingAreaCount ?: 0) + (prohibitedAreaCount ?: 0)
 
    /**
     * 获取围栏编号前缀(城市首字母)
     */
    fun getCityPrefix(): String? = electronicNumber?.substringBefore("-")
 
    /**
     * 获取围栏编号类型(类型简写)
     */
    fun getTypeCode(): String? {
        val parts = electronicNumber?.split("-")
        return if (parts?.size ?: 0 >= 2) parts?.get(1) else null
    }
 
    /**
     * 获取围栏编号序列号
     */
    fun getSerialNumber(): String? {
        val parts = electronicNumber?.split("-")
        return if (parts?.size ?: 0 >= 3) parts?.get(2) else null
    }
 
    companion object {
        /**
         * 围栏编号正则表达式
         * 格式:城市首字母-类型简写-4位自增流水号
         */
        const val ELECTRONIC_NUMBER_PATTERN = "^[A-Z]{2}-[A-Z]{2}-\\d{3,4}$"
 
        /**
         * 验证围栏编号格式是否正确
         */
        fun isValidElectronicNumber(number: String?): Boolean {
            return number?.matches(Regex(ELECTRONIC_NUMBER_PATTERN)) ?: false
        }
    }
}