chen.cheng 6 місяців тому
батько
коміт
4fdc7fdf03

+ 91 - 0
bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/web/controller/park/ParkAttendUsrDetailController.java

@@ -0,0 +1,91 @@
+package com.huashe.park.application.web.controller.park;
+
+import com.huashe.park.core.service.IParkAttendUsrDetailService;
+import com.huashe.park.domain.entity.ParkAttendUsrDetail;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.core.page.TableDataInfo;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+/**
+ * 用户打卡信息Controller
+ *
+ * @author ruoyi
+ * @date 2025-01-08
+ */
+@RestController
+@RequestMapping("/park/attendUsrDetail")
+public class ParkAttendUsrDetailController extends BaseController {
+    @Autowired
+    private IParkAttendUsrDetailService parkAttendUsrDetailService;
+
+    /**
+     * 查询用户打卡信息列表
+     */
+    @PreAuthorize("@ss.hasPermi('park:attendUsrDetail:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(ParkAttendUsrDetail parkAttendUsrDetail) {
+        startPage();
+        List<ParkAttendUsrDetail> list = parkAttendUsrDetailService.selectParkAttendUsrDetailList(parkAttendUsrDetail);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出用户打卡信息列表
+     */
+    @PreAuthorize("@ss.hasPermi('park:attendUsrDetail:export')")
+    @Log(title = "用户打卡信息", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, ParkAttendUsrDetail parkAttendUsrDetail) {
+        List<ParkAttendUsrDetail> list = parkAttendUsrDetailService.selectParkAttendUsrDetailList(parkAttendUsrDetail);
+        ExcelUtil<ParkAttendUsrDetail> util = new ExcelUtil<ParkAttendUsrDetail>(ParkAttendUsrDetail.class);
+        util.exportExcel(response, list, "用户打卡信息数据");
+    }
+
+    /**
+     * 获取用户打卡信息详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('park:attendUsrDetail:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id) {
+        return success(parkAttendUsrDetailService.selectParkAttendUsrDetailById(id));
+    }
+
+    /**
+     * 新增用户打卡信息
+     */
+    @PreAuthorize("@ss.hasPermi('park:attendUsrDetail:add')")
+    @Log(title = "用户打卡信息", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody ParkAttendUsrDetail parkAttendUsrDetail) {
+        return toAjax(parkAttendUsrDetailService.insertParkAttendUsrDetail(parkAttendUsrDetail));
+    }
+
+    /**
+     * 修改用户打卡信息
+     */
+    @PreAuthorize("@ss.hasPermi('park:attendUsrDetail:edit')")
+    @Log(title = "用户打卡信息", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody ParkAttendUsrDetail parkAttendUsrDetail) {
+        return toAjax(parkAttendUsrDetailService.updateParkAttendUsrDetail(parkAttendUsrDetail));
+    }
+
+    /**
+     * 删除用户打卡信息
+     */
+    @PreAuthorize("@ss.hasPermi('park:attendUsrDetail:remove')")
+    @Log(title = "用户打卡信息", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids) {
+        return toAjax(parkAttendUsrDetailService.deleteParkAttendUsrDetailByIds(ids));
+    }
+}

+ 9 - 0
bd-park/park-backend/park-application/src/main/resources/application.yml

@@ -79,6 +79,15 @@ forest:
   log-response-status: true
   ## 打开/关闭Forest响应内容日志(默认为 false)
   log-response-content: true
+  custom:
+    # 自定义配置
+    holiday: https://fastly.jsdelivr.net
+    uwb:
+      enabled: true
+      uwb-socket: ws://172.192.13.77:2223/socket/websocket/pollingArea
+      uwb-usr: admin
+      uwb-pwd: admin123
+      uwb-host: http://172.192.13.80:2223
 # token配置
 token:
   # 令牌自定义标识

+ 61 - 0
bd-park/park-backend/park-core/src/main/java/com/huashe/park/core/mapper/ParkAttendUsrDetailMapper.java

@@ -0,0 +1,61 @@
+package com.huashe.park.core.mapper;
+
+import com.huashe.park.domain.entity.ParkAttendUsrDetail;
+
+import java.util.List;
+
+/**
+ * 用户打卡信息Mapper接口
+ *
+ * @author ruoyi
+ * @date 2025-01-08
+ */
+public interface ParkAttendUsrDetailMapper {
+    /**
+     * 查询用户打卡信息
+     *
+     * @param id 用户打卡信息主键
+     * @return 用户打卡信息
+     */
+    public ParkAttendUsrDetail selectParkAttendUsrDetailById(Long id);
+
+    /**
+     * 查询用户打卡信息列表
+     *
+     * @param parkAttendUsrDetail 用户打卡信息
+     * @return 用户打卡信息集合
+     */
+    public List<ParkAttendUsrDetail> selectParkAttendUsrDetailList(ParkAttendUsrDetail parkAttendUsrDetail);
+
+    /**
+     * 新增用户打卡信息
+     *
+     * @param parkAttendUsrDetail 用户打卡信息
+     * @return 结果
+     */
+    public int insertParkAttendUsrDetail(ParkAttendUsrDetail parkAttendUsrDetail);
+
+    /**
+     * 修改用户打卡信息
+     *
+     * @param parkAttendUsrDetail 用户打卡信息
+     * @return 结果
+     */
+    public int updateParkAttendUsrDetail(ParkAttendUsrDetail parkAttendUsrDetail);
+
+    /**
+     * 删除用户打卡信息
+     *
+     * @param id 用户打卡信息主键
+     * @return 结果
+     */
+    public int deleteParkAttendUsrDetailById(Long id);
+
+    /**
+     * 批量删除用户打卡信息
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteParkAttendUsrDetailByIds(Long[] ids);
+}

+ 61 - 0
bd-park/park-backend/park-core/src/main/java/com/huashe/park/core/service/IParkAttendUsrDetailService.java

@@ -0,0 +1,61 @@
+package com.huashe.park.core.service;
+
+import com.huashe.park.domain.entity.ParkAttendUsrDetail;
+
+import java.util.List;
+
+/**
+ * 用户打卡信息Service接口
+ *
+ * @author ruoyi
+ * @date 2025-01-08
+ */
+public interface IParkAttendUsrDetailService {
+    /**
+     * 查询用户打卡信息
+     *
+     * @param id 用户打卡信息主键
+     * @return 用户打卡信息
+     */
+    public ParkAttendUsrDetail selectParkAttendUsrDetailById(Long id);
+
+    /**
+     * 查询用户打卡信息列表
+     *
+     * @param parkAttendUsrDetail 用户打卡信息
+     * @return 用户打卡信息集合
+     */
+    public List<ParkAttendUsrDetail> selectParkAttendUsrDetailList(ParkAttendUsrDetail parkAttendUsrDetail);
+
+    /**
+     * 新增用户打卡信息
+     *
+     * @param parkAttendUsrDetail 用户打卡信息
+     * @return 结果
+     */
+    public int insertParkAttendUsrDetail(ParkAttendUsrDetail parkAttendUsrDetail);
+
+    /**
+     * 修改用户打卡信息
+     *
+     * @param parkAttendUsrDetail 用户打卡信息
+     * @return 结果
+     */
+    public int updateParkAttendUsrDetail(ParkAttendUsrDetail parkAttendUsrDetail);
+
+    /**
+     * 批量删除用户打卡信息
+     *
+     * @param ids 需要删除的用户打卡信息主键集合
+     * @return 结果
+     */
+    public int deleteParkAttendUsrDetailByIds(Long[] ids);
+
+    /**
+     * 删除用户打卡信息信息
+     *
+     * @param id 用户打卡信息主键
+     * @return 结果
+     */
+    public int deleteParkAttendUsrDetailById(Long id);
+}

+ 90 - 0
bd-park/park-backend/park-core/src/main/java/com/huashe/park/core/service/impl/ParkAttendUsrDetailServiceImpl.java

@@ -0,0 +1,90 @@
+package com.huashe.park.core.service.impl;
+
+import java.util.List;
+
+import com.huashe.park.core.mapper.ParkAttendUsrDetailMapper;
+import com.huashe.park.core.service.IParkAttendUsrDetailService;
+import com.huashe.park.domain.entity.ParkAttendUsrDetail;
+import com.ruoyi.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * 用户打卡信息Service业务层处理
+ *
+ * @author ruoyi
+ * @date 2025-01-08
+ */
+@Service
+public class ParkAttendUsrDetailServiceImpl implements IParkAttendUsrDetailService {
+    @Autowired
+    private ParkAttendUsrDetailMapper parkAttendUsrDetailMapper;
+
+    /**
+     * 查询用户打卡信息
+     *
+     * @param id 用户打卡信息主键
+     * @return 用户打卡信息
+     */
+    @Override
+    public ParkAttendUsrDetail selectParkAttendUsrDetailById(Long id) {
+        return parkAttendUsrDetailMapper.selectParkAttendUsrDetailById(id);
+    }
+
+    /**
+     * 查询用户打卡信息列表
+     *
+     * @param parkAttendUsrDetail 用户打卡信息
+     * @return 用户打卡信息
+     */
+    @Override
+    public List<ParkAttendUsrDetail> selectParkAttendUsrDetailList(ParkAttendUsrDetail parkAttendUsrDetail) {
+        return parkAttendUsrDetailMapper.selectParkAttendUsrDetailList(parkAttendUsrDetail);
+    }
+
+    /**
+     * 新增用户打卡信息
+     *
+     * @param parkAttendUsrDetail 用户打卡信息
+     * @return 结果
+     */
+    @Override
+    public int insertParkAttendUsrDetail(ParkAttendUsrDetail parkAttendUsrDetail) {
+        parkAttendUsrDetail.setCreateTime(DateUtils.getNowDate());
+        return parkAttendUsrDetailMapper.insertParkAttendUsrDetail(parkAttendUsrDetail);
+    }
+
+    /**
+     * 修改用户打卡信息
+     *
+     * @param parkAttendUsrDetail 用户打卡信息
+     * @return 结果
+     */
+    @Override
+    public int updateParkAttendUsrDetail(ParkAttendUsrDetail parkAttendUsrDetail) {
+        parkAttendUsrDetail.setUpdateTime(DateUtils.getNowDate());
+        return parkAttendUsrDetailMapper.updateParkAttendUsrDetail(parkAttendUsrDetail);
+    }
+
+    /**
+     * 批量删除用户打卡信息
+     *
+     * @param ids 需要删除的用户打卡信息主键
+     * @return 结果
+     */
+    @Override
+    public int deleteParkAttendUsrDetailByIds(Long[] ids) {
+        return parkAttendUsrDetailMapper.deleteParkAttendUsrDetailByIds(ids);
+    }
+
+    /**
+     * 删除用户打卡信息信息
+     *
+     * @param id 用户打卡信息主键
+     * @return 结果
+     */
+    @Override
+    public int deleteParkAttendUsrDetailById(Long id) {
+        return parkAttendUsrDetailMapper.deleteParkAttendUsrDetailById(id);
+    }
+}

+ 112 - 0
bd-park/park-backend/park-core/src/main/resources/mapper/park/ParkAttendUsrDetailMapper.xml

@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.huashe.park.core.mapper.ParkAttendUsrDetailMapper">
+    
+    <resultMap type="ParkAttendUsrDetail" id="ParkAttendUsrDetailResult">
+        <result property="id"    column="id"    />
+        <result property="usrId"    column="usr_id"    />
+        <result property="usrName"    column="usr_name"    />
+        <result property="attendStart"    column="attend_start"    />
+        <result property="attendEnd"    column="attend_end"    />
+        <result property="dt"    column="dt"    />
+        <result property="startAttendStat"    column="start_attend_stat"    />
+        <result property="endAttendStat"    column="end_attend_stat"    />
+        <result property="attendGroupId"    column="attend_group_id"    />
+        <result property="updateTime"    column="update_time"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="createBy"    column="create_by"    />
+        <result property="updateBy"    column="update_by"    />
+        <result property="tenantId"    column="tenant_id"    />
+    </resultMap>
+
+    <sql id="selectParkAttendUsrDetailVo">
+        select id, usr_id, usr_name, attend_start, attend_end, dt, start_attend_stat,
+            end_attend_stat, attend_group_id, update_time, create_time, create_by, update_by, tenant_id from park_attend_usr_detail
+    </sql>
+
+    <select id="selectParkAttendUsrDetailList" parameterType="ParkAttendUsrDetail" resultMap="ParkAttendUsrDetailResult">
+        <include refid="selectParkAttendUsrDetailVo"/>
+        <where>
+            <if test="usrName != null  and usrName != ''">and usr_name like concat('%', #{usrName}, '%')</if>
+            <if test="startAttendStat != null ">and start_attend_stat = #{startAttendStat}</if>
+            <if test="endAttendStat != null ">and end_attend_stat = #{endAttendStat}</if>
+            <if test="attendEnd != null ">and attend_end = #{attendEnd}</if>
+            <if test="attendStart != null ">and attend_start = #{attendStart}</if>
+            <if test="attendGroupId != null ">and attend_group_id = #{attendGroupId}</if>
+            <if test="tenantId != null  and tenantId != ''">and tenant_id = #{tenantId}</if>
+        </where>
+    </select>
+    
+    <select id="selectParkAttendUsrDetailById" parameterType="Long" resultMap="ParkAttendUsrDetailResult">
+        <include refid="selectParkAttendUsrDetailVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertParkAttendUsrDetail" parameterType="ParkAttendUsrDetail" useGeneratedKeys="true" keyProperty="id">
+        insert into park_attend_usr_detail
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="usrId != null">usr_id,</if>
+            <if test="usrName != null and usrName != ''">usr_name,</if>
+            <if test="startAttendStat != null">attend_start,</if>
+            <if test="endAttendStat != null">attend_end,</if>
+            <if test="attendEnd != null">attend_end,</if>
+            <if test="attendStart != null">attend_start,</if>
+            <if test="dt != null">dt,</if>
+            <if test="attendGroupId != null">attend_group_id,</if>
+            <if test="updateTime != null">update_time,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="tenantId != null">tenant_id,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="usrId != null">#{usrId},</if>
+            <if test="usrName != null and usrName != ''">#{usrName},</if>
+            <if test="endAttendStat != null">#{endAttendStat},</if>
+            <if test="startAttendStat != null">#{startAttendStat},</if>
+            <if test="attendEnd != null">#{attendEnd},</if>
+            <if test="attendStart != null">#{attendStart},</if>
+            <if test="dt != null">#{dt},</if>
+            <if test="attendGroupId != null">#{attendGroupId},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="tenantId != null">#{tenantId},</if>
+        </trim>
+    </insert>
+
+    <update id="updateParkAttendUsrDetail" parameterType="ParkAttendUsrDetail">
+        update park_attend_usr_detail
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="usrId != null">usr_id = #{usrId},</if>
+            <if test="usrName != null and usrName != ''">usr_name = #{usrName},</if>
+            <if test="startAttendStat != null">start_attend_start = #{startAttendStat},</if>
+            <if test="endAttendStat != null">end_attend_end = #{endAttendStat},</if>
+            <if test="attendStart != null">attend_start = #{attendStart},</if>
+            <if test="attendEnd != null">attend_end = #{attendEnd},</if>
+            <if test="attendStart != null">attend_start = #{attendStart},</if>
+            <if test="dt != null">dt = #{dt},</if>
+            <if test="attendGroupId != null">attend_group_id = #{attendGroupId},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="tenantId != null">tenant_id = #{tenantId},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteParkAttendUsrDetailById" parameterType="Long">
+        delete from park_attend_usr_detail where id = #{id}
+    </delete>
+
+    <delete id="deleteParkAttendUsrDetailByIds" parameterType="String">
+        delete from park_attend_usr_detail where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 167 - 0
bd-park/park-backend/park-domain/src/main/java/com/huashe/park/domain/entity/ParkAttendUsrDetail.java

@@ -0,0 +1,167 @@
+package com.huashe.park.domain.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.util.Date;
+
+/**
+ * 用户打卡信息对象 park_attend_usr_detail
+ *
+ * @author ruoyi
+ * @date 2025-01-08
+ */
+public class ParkAttendUsrDetail extends BaseEntity {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 编号
+     */
+    private Long id;
+
+    /**
+     * $column.columnComment
+     */
+    private String usrId;
+
+    /**
+     * 用户名
+     */
+    @Excel(name = "用户名")
+    private String usrName;
+
+    /**
+     * 开始时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "开始时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    private Date attendStart;
+    @Excel(name = "打卡状态")
+    private String startAttendStat;
+    /**
+     * 结束时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "结束时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    private Date attendEnd;
+    @Excel(name = "打卡状态")
+    private String endAttendStat;
+    /**
+     * yyyyMMdd
+     */
+    private String dt;
+
+
+    /**
+     * 考勤组主键
+     */
+    @Excel(name = "考勤组主键")
+    private Long attendGroupId;
+
+    /**
+     * 租户id
+     */
+    @Excel(name = "租户id")
+    private String tenantId;
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setUsrId(String usrId) {
+        this.usrId = usrId;
+    }
+
+    public String getUsrId() {
+        return usrId;
+    }
+
+    public void setUsrName(String usrName) {
+        this.usrName = usrName;
+    }
+
+    public String getUsrName() {
+        return usrName;
+    }
+
+    public void setAttendStart(Date attendStart) {
+        this.attendStart = attendStart;
+    }
+
+    public Date getAttendStart() {
+        return attendStart;
+    }
+
+    public void setAttendEnd(Date attendEnd) {
+        this.attendEnd = attendEnd;
+    }
+
+    public Date getAttendEnd() {
+        return attendEnd;
+    }
+
+    public void setDt(String dt) {
+        this.dt = dt;
+    }
+
+    public String getDt() {
+        return dt;
+    }
+
+    public String getStartAttendStat() {
+        return startAttendStat;
+    }
+
+    public void setStartAttendStat(String startAttendStat) {
+        this.startAttendStat = startAttendStat;
+    }
+
+    public String getEndAttendStat() {
+        return endAttendStat;
+    }
+
+    public void setEndAttendStat(String endAttendStat) {
+        this.endAttendStat = endAttendStat;
+    }
+
+    public void setAttendGroupId(Long attendGroupId) {
+        this.attendGroupId = attendGroupId;
+    }
+
+    public Long getAttendGroupId() {
+        return attendGroupId;
+    }
+
+    public void setTenantId(String tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public String getTenantId() {
+        return tenantId;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+                .append("id", getId())
+                .append("usrId", getUsrId())
+                .append("usrName", getUsrName())
+                .append("attendStart", getAttendStart())
+                .append("attendEnd", getAttendEnd())
+                .append("dt", getDt())
+                .append("attendGroupId", getAttendGroupId())
+                .append("updateTime", getUpdateTime())
+                .append("createTime", getCreateTime())
+                .append("createBy", getCreateBy())
+                .append("updateBy", getUpdateBy())
+                .append("tenantId", getTenantId())
+                .toString();
+    }
+}

+ 27 - 0
bd-park/park-backend/park-infrastructure/src/main/java/com/huashe/park/infrastructure/cfg/forest/CustomForestCfg.java

@@ -0,0 +1,27 @@
+package com.huashe.park.infrastructure.cfg.forest;
+
+import com.dtflys.forest.annotation.BindingVar;
+import com.dtflys.forest.reflection.ForestMethod;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationProperties(prefix = "forest.custom")
+public class CustomForestCfg {
+    private String holiday;
+
+    @Autowired
+    private UWBCfg uwbCfg;
+
+    @BindingVar("uwbBaseUrl")
+    public String getBaseUrl(ForestMethod method) {
+        return uwbCfg.getUwbHost();
+    }
+
+    @BindingVar("holidayBaseUrl")
+    public String getHolidayBaseUrl(ForestMethod method) {
+        return holiday;
+    }
+
+}

+ 55 - 0
bd-park/park-backend/park-infrastructure/src/main/java/com/huashe/park/infrastructure/cfg/forest/UWBCfg.java

@@ -0,0 +1,55 @@
+package com.huashe.park.infrastructure.cfg.forest;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ConfigurationProperties(prefix = "forest.custom.uwb")
+@ConditionalOnProperty(name = "forest.custom.uwb.enabled", havingValue = "true")
+public class UWBCfg {
+    private static final Logger log = LoggerFactory.getLogger(UWBCfg.class);
+
+    private String uwbSocket;
+
+    private String uwbUsr;
+
+    private String uwbPwd;
+
+    private String uwbHost;
+
+    public String getUwbHost() {
+        return uwbHost;
+    }
+
+    public void setUwbHost(String uwbHost) {
+        this.uwbHost = uwbHost;
+    }
+
+    public String getUwbSocket() {
+        return uwbSocket;
+    }
+
+    public void setUwbSocket(String uwbSocket) {
+        this.uwbSocket = uwbSocket;
+    }
+
+    public String getUwbUsr() {
+        return uwbUsr;
+    }
+
+    public void setUwbUsr(String uwbUsr) {
+        this.uwbUsr = uwbUsr;
+    }
+
+    public String getUwbPwd() {
+        return uwbPwd;
+    }
+
+    public void setUwbPwd(String uwbPwd) {
+        this.uwbPwd = uwbPwd;
+    }
+
+}

+ 192 - 0
bd-park/park-backend/park-infrastructure/src/main/java/com/huashe/park/infrastructure/uwb/HolidayWebService.java

@@ -0,0 +1,192 @@
+package com.huashe.park.infrastructure.uwb;
+
+import com.dtflys.forest.annotation.Get;
+import com.dtflys.forest.annotation.Var;
+
+import java.util.Map;
+
+public interface HolidayWebService {
+
+    /**
+     * {
+     * "$schema": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/schema.json",
+     * "$id": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/2025.json",
+     * "year": 2025,
+     * "papers": [
+     * "https://www.gov.cn/zhengce/zhengceku/202411/content_6986383.htm"
+     * ],
+     * "days": [
+     * {
+     * "name": "元旦",
+     * "date": "2025-01-01",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "春节",
+     * "date": "2025-01-26",
+     * "isOffDay": false
+     * },
+     * {
+     * "name": "春节",
+     * "date": "2025-01-28",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "春节",
+     * "date": "2025-01-29",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "春节",
+     * "date": "2025-01-30",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "春节",
+     * "date": "2025-01-31",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "春节",
+     * "date": "2025-02-01",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "春节",
+     * "date": "2025-02-02",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "春节",
+     * "date": "2025-02-03",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "春节",
+     * "date": "2025-02-04",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "春节",
+     * "date": "2025-02-08",
+     * "isOffDay": false
+     * },
+     * {
+     * "name": "清明节",
+     * "date": "2025-04-04",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "清明节",
+     * "date": "2025-04-05",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "清明节",
+     * "date": "2025-04-06",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "劳动节",
+     * "date": "2025-04-27",
+     * "isOffDay": false
+     * },
+     * {
+     * "name": "劳动节",
+     * "date": "2025-05-01",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "劳动节",
+     * "date": "2025-05-02",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "劳动节",
+     * "date": "2025-05-03",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "劳动节",
+     * "date": "2025-05-04",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "劳动节",
+     * "date": "2025-05-05",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "端午节",
+     * "date": "2025-05-31",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "端午节",
+     * "date": "2025-06-01",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "端午节",
+     * "date": "2025-06-02",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "国庆节、中秋节",
+     * "date": "2025-09-28",
+     * "isOffDay": false
+     * },
+     * {
+     * "name": "国庆节、中秋节",
+     * "date": "2025-10-01",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "国庆节、中秋节",
+     * "date": "2025-10-02",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "国庆节、中秋节",
+     * "date": "2025-10-03",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "国庆节、中秋节",
+     * "date": "2025-10-04",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "国庆节、中秋节",
+     * "date": "2025-10-05",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "国庆节、中秋节",
+     * "date": "2025-10-06",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "国庆节、中秋节",
+     * "date": "2025-10-07",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "国庆节、中秋节",
+     * "date": "2025-10-08",
+     * "isOffDay": true
+     * },
+     * {
+     * "name": "国庆节、中秋节",
+     * "date": "2025-10-11",
+     * "isOffDay": false
+     * }
+     * ]
+     * }
+     *
+     * @param year
+     * @return
+     */
+    @Get(url = "{uwbBaseUrl}/gh/NateScarlet/holiday-cn@master/{year}.json", dataType = "json")
+    Map getYearHoliday(@Var("year") String year);
+}