skyline 1 өдөр өмнө
parent
commit
74c431eb00

+ 36 - 2
admin-web/src/views/admin/notice/index.vue

@@ -9,6 +9,9 @@
                 <el-form-item label="状态">
                     <ext-d-select v-model="queryParams.status" type="notice_status" placeholder="请选择" clearable style="width: 150px" />
                 </el-form-item>
+                <el-form-item label="目标">
+                    <ext-d-select v-model="queryParams.target" type="notice_target" placeholder="请选择" clearable style="width: 150px" />
+                </el-form-item>
                 <el-form-item>
                     <el-button type="primary" @click="handleQuery">
                         <el-icon><ele-Search /></el-icon> 查询
@@ -42,6 +45,11 @@
                         <el-tag :type="getStatusType(row.status)">{{ getStatusLabel(row.status) }}</el-tag>
                     </template>
                 </el-table-column>
+                <el-table-column prop="target" label="目标" width="100" align="center">
+                    <template #default="{ row }">
+                        {{ getTargetLabel(row.target) }}
+                    </template>
+                </el-table-column>
                 <el-table-column prop="startTime" label="开始时间" width="170" align="center" />
                 <el-table-column prop="endTime" label="结束时间" width="170" align="center" />
                 <el-table-column prop="createTime" label="创建时间" width="170" align="center" />
@@ -76,6 +84,13 @@
                 <el-form-item label="公告内容" prop="content">
                     <el-input v-model="formData.content" type="textarea" :rows="5" placeholder="请输入公告内容" />
                 </el-form-item>
+                <el-form-item label="目标" prop="target">
+                    <el-checkbox-group v-model="formData.targetList">
+                        <el-checkbox label="client">客户端</el-checkbox>
+                        <el-checkbox label="merchant">商户端</el-checkbox>
+                    </el-checkbox-group>
+                    <span style="color: #999; font-size: 12px; margin-left: 10px;">不选则默认全部</span>
+                </el-form-item>
                 <el-form-item label="生效时间" prop="startTime">
                     <el-date-picker
                         v-model="formData.startTime"
@@ -116,7 +131,8 @@ const queryParams = reactive({
     pageNum: 1,
     pageSize: 10,
     title: '',
-    status: null as number | null
+    status: null as number | null,
+    target: '' as string
 });
 
 // 表格数据
@@ -134,7 +150,9 @@ const formData = reactive({
     content: '',
     startTime: '',
     endTime: '',
-    stationIdList: [] as number[]
+    stationIdList: [] as number[],
+    target: '' as string,
+    targetList: [] as string[]
 });
 
 const rules = {
@@ -152,6 +170,7 @@ const mockData = [
 // 获取状态标签
 const getStatusLabel = (status: number) => u.fmt.fmtDict(status, 'notice_status');
 const getStatusType = (status: number) => u.fmt.fmtDictColor(status, 'notice_status');
+const getTargetLabel = (target: string) => u.fmt.fmtDict(target, 'notice_target');
 
 // 查询数据
 const handleQuery = async () => {
@@ -173,6 +192,7 @@ const handleQuery = async () => {
 const resetQuery = () => {
     queryParams.title = '';
     queryParams.status = null;
+    queryParams.target = '';
     queryParams.pageNum = 1;
     handleQuery();
 };
@@ -185,6 +205,8 @@ const handleAdd = () => {
     formData.content = '';
     formData.startTime = '';
     formData.endTime = '';
+    formData.target = '';
+    formData.targetList = [];
     dialogVisible.value = true;
 };
 
@@ -196,6 +218,12 @@ const handleEdit = (row: any) => {
     formData.content = row.content;
     formData.startTime = row.startTime;
     formData.endTime = row.endTime;
+    formData.target = row.target || '';
+    if (!row.target || row.target === 'all') {
+        formData.targetList = ['client', 'merchant'];
+    } else {
+        formData.targetList = row.target.split(',').filter(Boolean);
+    }
     dialogVisible.value = true;
 };
 
@@ -205,6 +233,12 @@ const handleSubmit = async () => {
     await formRef.value.validate();
     
     try {
+        // 将 targetList 转为 target 字符串
+        if (!formData.targetList || formData.targetList.length === 0 || formData.targetList.length === 2) {
+            formData.target = 'all';
+        } else {
+            formData.target = formData.targetList.join(',');
+        }
         await $body('/notice/create', formData);
         ElMessage.success(formData.id ? '修改成功' : '新增成功');
         dialogVisible.value = false;

+ 5 - 0
car-wash-entity/src/main/java/com/kym/entity/SystemNotice.java

@@ -58,4 +58,9 @@ public class SystemNotice  extends BaseEntity<SystemNotice>{
      * 状态:0-未开始,1-生效中,2-已结束,3-已取消
      */
     private Integer status;
+
+    /**
+     * 目标:client-客户端, merchant-商户端, all-全部
+     */
+    private String target;
 }

+ 5 - 0
car-wash-entity/src/main/java/com/kym/entity/queryParams/NoticeQueryParams.java

@@ -27,4 +27,9 @@ public class NoticeQueryParams extends PageParams {
      * 状态:0-未开始,1-生效中,2-已结束,3-已取消
      */
     private Integer status;
+
+    /**
+     * 目标:client-客户端, merchant-商户端, all-全部
+     */
+    private String target;
 }

+ 5 - 0
car-wash-entity/src/main/java/com/kym/entity/vo/NoticeStationVo.java

@@ -56,4 +56,9 @@ public class NoticeStationVo extends BaseEntity {
      */
     private List<String> stationIdList;
 
+    /**
+     * 目标:client-客户端, merchant-商户端, all-全部
+     */
+    private String target;
+
 }

+ 5 - 0
car-wash-entity/src/main/resources/sql/init.sql

@@ -172,6 +172,7 @@ CREATE TABLE IF NOT EXISTS `t_system_notice` (
     `start_time` DATETIME DEFAULT NULL COMMENT '开始时间',
     `end_time` DATETIME DEFAULT NULL COMMENT '结束时间',
     `status` TINYINT NOT NULL DEFAULT 0 COMMENT '状态:0-未开始,1-生效中,2-已结束,3-已取消',
+    `target` VARCHAR(20) NOT NULL DEFAULT 'all' COMMENT '目标:client-客户端, merchant-商户端, all-全部',
     `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
     `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
     PRIMARY KEY (`id`),
@@ -344,6 +345,10 @@ INSERT INTO `t_data_dict` (`code`, `name`, `value`, `weight`, `remark`, `color`)
 ('notice_status', '生效中', '1', 2, '公告状态', 'success'),
 ('notice_status', '已结束', '2', 3, '公告状态', ''),
 ('notice_status', '已取消', '3', 4, '公告状态', 'danger'),
+-- 公告目标
+('notice_target', '客户端', 'client', 1, '公告目标', ''),
+('notice_target', '商户端', 'merchant', 2, '公告目标', ''),
+('notice_target', '全部', 'all', 3, '公告目标', ''),
 -- 是否
 ('yes_no', '否', '0', 1, '是否', 'info'),
 ('yes_no', '是', '1', 2, '是否', 'success'),

+ 37 - 0
car-wash-miniapp/src/main/java/com/kym/miniapp/controller/NoticeController.java

@@ -0,0 +1,37 @@
+package com.kym.miniapp.controller;
+
+import cn.dev33.satoken.annotation.SaIgnore;
+import com.kym.common.R;
+import com.kym.service.SystemNoticeService;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 客户端-公告通知 前端控制器
+ * </p>
+ *
+ * @author skyline
+ * @since 2025-05-28
+ */
+@RestController
+@RequestMapping("/notice")
+public class NoticeController {
+
+    private final SystemNoticeService systemNoticeService;
+
+    public NoticeController(SystemNoticeService systemNoticeService) {
+        this.systemNoticeService = systemNoticeService;
+    }
+
+    /**
+     * 客户端公告列表(公开接口)
+     * 返回当前生效中、目标为client或all、且在有效期内的公告
+     */
+    @SaIgnore
+    @GetMapping("/client/list")
+    public R<?> listClientNotice() {
+        return R.success(systemNoticeService.listClientNotice());
+    }
+}

+ 8 - 0
car-wash-service/src/main/java/com/kym/service/SystemNoticeService.java

@@ -6,6 +6,8 @@ import com.kym.entity.vo.NoticeStationVo;
 import com.kym.entity.common.PageBean;
 import com.kym.service.mybatisplus.MyBaseService;
 
+import java.util.List;
+
 /**
  * <p>
  * 系统公告通知表 服务类
@@ -20,4 +22,10 @@ public interface SystemNoticeService extends MyBaseService<SystemNotice> {
     PageBean<NoticeStationVo> listSystemNotice(NoticeQueryParams params);
 
     NoticeStationVo getNoticeById(Long noticeId);
+
+    /**
+     * 客户端公告列表(公开接口,无需登录)
+     * 返回当前生效中、目标为client或all、且在有效期内的公告
+     */
+    List<NoticeStationVo> listClientNotice();
 }

+ 19 - 0
car-wash-service/src/main/java/com/kym/service/impl/SystemNoticeServiceImpl.java

@@ -19,6 +19,7 @@ import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.time.LocalDateTime;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -67,6 +68,7 @@ public class SystemNoticeServiceImpl extends MyBaseServiceImpl<SystemNoticeMappe
                 .eq(CommUtil.isNotEmptyAndNull(params.getStatus()), SystemNotice::getStatus, params.getStatus())
                 .like(CommUtil.isNotEmptyAndNull(params.getTitle()), SystemNotice::getTitle, params.getTitle())
                 .like(CommUtil.isNotEmptyAndNull(params.getContent()), SystemNotice::getContent, params.getContent())
+                .eq(CommUtil.isNotEmptyAndNull(params.getTarget()), SystemNotice::getTarget, params.getTarget())
                 .orderByDesc(SystemNotice::getUpdateTime);
         List<NoticeStationVo> res = this.selectJoinList(NoticeStationVo.class, wrapper);
         var notice2stations = stationNoticeService.lambdaQuery().in(StationNotice::getNoticeId, res.stream().map(NoticeStationVo::getId).toList()).list().stream().collect(Collectors.groupingBy(StationNotice::getNoticeId, Collectors.mapping(StationNotice::getStationId, Collectors.toList())));
@@ -89,4 +91,21 @@ public class SystemNoticeServiceImpl extends MyBaseServiceImpl<SystemNoticeMappe
         return stationNoticeVo;
     }
 
+    /**
+     * 客户端公告列表(公开接口)
+     * 返回status=1(生效中),target为client或all,且在有效期内的公告
+     */
+    @Override
+    public List<NoticeStationVo> listClientNotice() {
+        var now = LocalDateTime.now();
+        var wrapper = JoinWrappers.lambda(SystemNotice.class)
+                .selectAsClass(SystemNotice.class, NoticeStationVo.class)
+                .eq(SystemNotice::getStatus, 1)
+                .in(SystemNotice::getTarget, "client", "all")
+                .le(SystemNotice::getStartTime, now)
+                .ge(SystemNotice::getEndTime, now)
+                .orderByDesc(SystemNotice::getUpdateTime);
+        return this.selectJoinList(NoticeStationVo.class, wrapper);
+    }
+
 }