Merge branch 'master' of https://gitea.zianxin.com/zax/biz-api-cloud
This commit is contained in:
commit
9182fdcb77
23 files changed
+1165
-11
No files matched your search
+34
@@ -0,0 +1,34 @@
|
||||
package com.bsd.pjcloud.canteen.dto.canteenonline;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
import com.bsd.pjcloud.common.core.util.TenantTable;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 在线点餐spu
|
||||
*
|
||||
* @author zjf
|
||||
* @date 2024-12-16 23:42:19
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "在线点餐批量关联新增每日菜谱")
|
||||
public class CanteenOnlineSpuSaveDto {
|
||||
|
||||
|
||||
/**
|
||||
* 商户编号
|
||||
*/
|
||||
@Schema(description="商户编号")
|
||||
private Long merchantId;
|
||||
|
||||
private List<CanteenOnlineSpuSaveItemDto> items;
|
||||
|
||||
|
||||
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package com.bsd.pjcloud.canteen.dto.canteenonline;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class CanteenOnlineSpuSaveItemDto {
|
||||
|
||||
|
||||
/**
|
||||
* 商品名称
|
||||
*/
|
||||
@Schema(description="商品名称")
|
||||
private String name;
|
||||
|
||||
|
||||
@Schema(description="关联每日菜谱id")
|
||||
private Long linkSpuId;
|
||||
|
||||
/**
|
||||
* 商品分类编号
|
||||
*/
|
||||
@Schema(description="商品分类编号")
|
||||
private Long categoryId;
|
||||
|
||||
/**
|
||||
* 商品封面图
|
||||
*/
|
||||
@Schema(description="商品封面图")
|
||||
private String picUrl;
|
||||
|
||||
|
||||
/**
|
||||
* 排序字段
|
||||
*/
|
||||
@Schema(description="排序字段")
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 商品状态: 1 上架(开启) 0 下架(禁用) -1 回收
|
||||
*/
|
||||
@Schema(description="商品状态: 1 上架(开启) 0 下架(禁用) -1 回收")
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 商品价格,单位使用:分
|
||||
*/
|
||||
@Schema(description="商品价格,单位使用:分")
|
||||
private Integer price;
|
||||
|
||||
|
||||
/**
|
||||
* 库存
|
||||
*/
|
||||
@Schema(description="库存")
|
||||
private Integer stock;
|
||||
}
|
||||
+3
@@ -112,4 +112,7 @@ public class CanteenOnlineCategoryEntity extends Model<CanteenOnlineCategoryEnti
|
||||
*/
|
||||
@Schema(description = "商家id")
|
||||
private Long merchantId;
|
||||
|
||||
@Schema(description = "餐段类型")
|
||||
private String categoryType;
|
||||
}
|
||||
+3
@@ -182,4 +182,7 @@ public class CanteenOnlineSpuEntity extends Model<CanteenOnlineSpuEntity> {
|
||||
*/
|
||||
@Schema(description="租户编号")
|
||||
private Long tenantId;
|
||||
|
||||
@Schema(description="关联每日菜谱id")
|
||||
private Long linkSpuId;
|
||||
}
|
||||
+13
-3
@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.bsd.pjcloud.canteen.dto.CanteenOnlineSpuUpdateStockReqDTO;
|
||||
import com.bsd.pjcloud.canteen.dto.canteenonline.CanteenOnlineSpuSaveDto;
|
||||
import com.bsd.pjcloud.canteen.vo.APPOnlineSpuVO;
|
||||
import com.bsd.pjcloud.canteen.vo.app.CanteenOnlineSpuAppVO;
|
||||
import com.bsd.pjcloud.common.core.util.BeanUtils;
|
||||
@@ -58,7 +59,7 @@ public class CanteenOnlineSpuController {
|
||||
LambdaQueryWrapper<CanteenOnlineSpuEntity> wrapper = Wrappers.lambdaQuery();
|
||||
wrapper.like(StrUtil.isNotBlank(canteenOnlineSpu.getName()), CanteenOnlineSpuEntity::getName, canteenOnlineSpu.getName());
|
||||
wrapper.eq(Objects.nonNull(canteenOnlineSpu.getCategoryId()), CanteenOnlineSpuEntity::getCategoryId, canteenOnlineSpu.getCategoryId());
|
||||
return R.ok(canteenOnlineSpuService.page(page, wrapper));
|
||||
return R.ok(canteenOnlineSpuService.pageScope(page, wrapper));
|
||||
}
|
||||
|
||||
|
||||
@@ -90,6 +91,14 @@ public class CanteenOnlineSpuController {
|
||||
return R.ok(canteenOnlineSpuService.save(canteenOnlineSpu));
|
||||
}
|
||||
|
||||
@Operation(summary = "批量新增关联每日菜谱", description = "批量新增关联每日菜谱")
|
||||
@SysLog("批量导入新增点餐spu")
|
||||
@PostMapping("/saveCanteenSpuBatch")
|
||||
@PreAuthorize("@pms.hasPermission('canteen_canteenOnlineSpu_add')")
|
||||
public R saveCanteenSpuBatch(@RequestBody CanteenOnlineSpuSaveDto canteenOnlineSpuSaveDto) {
|
||||
return R.ok(canteenOnlineSpuService.saveCanteenSpuBatch(canteenOnlineSpuSaveDto));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改在线点餐spu
|
||||
*
|
||||
@@ -146,8 +155,9 @@ public class CanteenOnlineSpuController {
|
||||
@GetMapping("/app/getCanteenSpuList")
|
||||
@Operation(summary = "获取在线点餐的菜品列表", description = "1.通过分类id,可以不填,默认查全部,2.商户id,必传")
|
||||
public R<List<APPOnlineSpuVO>> getCanteenSpuList(@RequestParam(value = "categoryId", required = false) String categoryId,
|
||||
@RequestParam(value = "merchantId") String merchantId) {
|
||||
return canteenOnlineSpuService.getCanteenOnlineSpuList(categoryId, merchantId);
|
||||
@RequestParam(value = "merchantId") String merchantId,
|
||||
@RequestParam(value = "time")String time) {
|
||||
return canteenOnlineSpuService.getCanteenOnlineSpuList(categoryId, merchantId,time);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+20
-1
@@ -1,7 +1,10 @@
|
||||
package com.bsd.pjcloud.canteen.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.bsd.pjcloud.canteen.dto.CanteenOnlineSpuUpdateStockReqDTO;
|
||||
import com.bsd.pjcloud.canteen.dto.canteenonline.CanteenOnlineSpuSaveDto;
|
||||
import com.bsd.pjcloud.canteen.entity.CanteenOnlineSpuEntity;
|
||||
import com.bsd.pjcloud.canteen.vo.APPOnlineSpuVO;
|
||||
import com.bsd.pjcloud.common.core.util.R;
|
||||
@@ -18,7 +21,7 @@ public interface CanteenOnlineSpuService extends IService<CanteenOnlineSpuEntity
|
||||
* @param merchantId
|
||||
* @return
|
||||
*/
|
||||
R<List<APPOnlineSpuVO>> getCanteenOnlineSpuList(String categoryId, String merchantId);
|
||||
R<List<APPOnlineSpuVO>> getCanteenOnlineSpuList(String categoryId, String merchantId,String time);
|
||||
|
||||
|
||||
/**
|
||||
@@ -27,4 +30,20 @@ public interface CanteenOnlineSpuService extends IService<CanteenOnlineSpuEntity
|
||||
* @return
|
||||
*/
|
||||
R updateOnlineSpuSkuStock(CanteenOnlineSpuUpdateStockReqDTO canteenOnlineSpuUpdateStockReqDTO);
|
||||
|
||||
/**
|
||||
* 批量新增关联每日菜谱
|
||||
* @param canteenOnlineSpuSaveDto
|
||||
* @return
|
||||
*/
|
||||
Object saveCanteenSpuBatch(CanteenOnlineSpuSaveDto canteenOnlineSpuSaveDto);
|
||||
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
* @param page
|
||||
* @param wrapper
|
||||
* @return
|
||||
*/
|
||||
Object pageScope(Page page, LambdaQueryWrapper<CanteenOnlineSpuEntity> wrapper);
|
||||
}
|
||||
+71
-2
@@ -1,18 +1,33 @@
|
||||
package com.bsd.pjcloud.canteen.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.bsd.pjcloud.canteen.dto.CanteenOnlineSpuUpdateStockReqDTO;
|
||||
import com.bsd.pjcloud.canteen.dto.canteenonline.CanteenOnlineSpuSaveDto;
|
||||
import com.bsd.pjcloud.canteen.dto.canteenonline.CanteenOnlineSpuSaveItemDto;
|
||||
import com.bsd.pjcloud.canteen.entity.CanteenCategoryEntity;
|
||||
import com.bsd.pjcloud.canteen.entity.CanteenDailyMenuEntity;
|
||||
import com.bsd.pjcloud.canteen.entity.CanteenOnlineCategoryEntity;
|
||||
import com.bsd.pjcloud.canteen.entity.CanteenOnlineSpuEntity;
|
||||
import com.bsd.pjcloud.canteen.mapper.CanteenCategoryMapper;
|
||||
import com.bsd.pjcloud.canteen.mapper.CanteenDailyMenuMapper;
|
||||
import com.bsd.pjcloud.canteen.mapper.CanteenOnlineCategoryMapper;
|
||||
import com.bsd.pjcloud.canteen.mapper.CanteenOnlineSpuMapper;
|
||||
import com.bsd.pjcloud.canteen.service.CanteenOnlineSpuService;
|
||||
import com.bsd.pjcloud.canteen.vo.APPOnlineSpuVO;
|
||||
import com.bsd.pjcloud.common.core.util.BeanUtils;
|
||||
import com.bsd.pjcloud.common.core.util.R;
|
||||
import com.bsd.pjcloud.common.data.datascope.DataScope;
|
||||
import com.bsd.pjcloud.common.security.util.SecurityUtils;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 在线点餐spu
|
||||
@@ -21,14 +36,33 @@ import java.util.List;
|
||||
* @date 2024-12-16 23:42:19
|
||||
*/
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class CanteenOnlineSpuServiceImpl extends ServiceImpl<CanteenOnlineSpuMapper, CanteenOnlineSpuEntity> implements CanteenOnlineSpuService {
|
||||
|
||||
private final CanteenCategoryMapper categoryMapper;
|
||||
|
||||
private final CanteenOnlineCategoryMapper canteenOnlineCategoryMapper;
|
||||
|
||||
private final CanteenDailyMenuMapper canteenDailyMenuMapper;
|
||||
@Override
|
||||
public R<List<APPOnlineSpuVO>> getCanteenOnlineSpuList(String categoryId, String merchantId) {
|
||||
public R<List<APPOnlineSpuVO>> getCanteenOnlineSpuList(String categoryId, String merchantId,String time) {
|
||||
LambdaQueryWrapper<CanteenOnlineSpuEntity> canteenOnlineSpuEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
canteenOnlineSpuEntityLambdaQueryWrapper.eq(StringUtils.isNotEmpty(categoryId), CanteenOnlineSpuEntity::getCategoryId, categoryId);
|
||||
canteenOnlineSpuEntityLambdaQueryWrapper.eq(CanteenOnlineSpuEntity::getMerchantId, merchantId);
|
||||
List<CanteenOnlineSpuEntity> canteenSpuEntities = baseMapper.selectList(canteenOnlineSpuEntityLambdaQueryWrapper);
|
||||
List<APPOnlineSpuVO> bean = BeanUtils.toBean(canteenSpuEntities, APPOnlineSpuVO.class);
|
||||
|
||||
//根据商户查询当前日期的每日菜谱,查询每日菜谱上架的菜的id,然后在从在线订餐的列表筛选出今天有上新的数据
|
||||
LambdaQueryWrapper<CanteenDailyMenuEntity> dailyMenuEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
dailyMenuEntityLambdaQueryWrapper.eq(CanteenDailyMenuEntity::getMerchantId, merchantId);
|
||||
dailyMenuEntityLambdaQueryWrapper.eq(CanteenDailyMenuEntity::getStartTime,time);
|
||||
List<CanteenDailyMenuEntity> dailyMenuEntities = canteenDailyMenuMapper.selectList(dailyMenuEntityLambdaQueryWrapper);
|
||||
List<Long> linkSpuIds = dailyMenuEntities.stream().map(d -> d.getSpuId()).collect(Collectors.toList());
|
||||
//从canteenSpuEntities中筛选出今天有上新的数据
|
||||
List<CanteenOnlineSpuEntity> finallyCanteenSpuEntities =
|
||||
canteenSpuEntities.stream().filter(c -> {
|
||||
return c.getLinkSpuId() == null || linkSpuIds.contains(c.getLinkSpuId());
|
||||
}).collect(Collectors.toList());
|
||||
List<APPOnlineSpuVO> bean = BeanUtils.toBean(finallyCanteenSpuEntities, APPOnlineSpuVO.class);
|
||||
return R.ok(bean);
|
||||
|
||||
}
|
||||
@@ -50,4 +84,39 @@ public class CanteenOnlineSpuServiceImpl extends ServiceImpl<CanteenOnlineSpuMap
|
||||
}
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object saveCanteenSpuBatch(CanteenOnlineSpuSaveDto canteenOnlineSpuSaveDto) {
|
||||
Long merchantId = canteenOnlineSpuSaveDto.getMerchantId();
|
||||
List<CanteenOnlineSpuSaveItemDto> items = canteenOnlineSpuSaveDto.getItems();
|
||||
List<CanteenOnlineSpuEntity> canteenSpuEntities = BeanUtils.toBean(items, CanteenOnlineSpuEntity.class);
|
||||
//每日菜谱的分类,查询在线分类里面是否有
|
||||
Set<Long> categoryIds = canteenSpuEntities.stream().map(c -> c.getCategoryId()).collect(Collectors.toSet());
|
||||
List<CanteenCategoryEntity> canteenCategoryEntities = categoryMapper.selectList(new LambdaQueryWrapper<CanteenCategoryEntity>().select(CanteenCategoryEntity::getId).in(CanteenCategoryEntity::getId, categoryIds));
|
||||
//把canteenCategoryEntities转为key map
|
||||
Map<Long, CanteenCategoryEntity> canteenCategoryEntityMap = canteenCategoryEntities.stream().collect(Collectors.toMap(CanteenCategoryEntity::getId, c -> c));
|
||||
|
||||
Long deptId = SecurityUtils.getUser().getDeptId();
|
||||
canteenSpuEntities.forEach(c -> {
|
||||
CanteenCategoryEntity canteenCategoryEntity = canteenCategoryEntityMap.get(c.getCategoryId());
|
||||
String name = canteenCategoryEntity.getName();
|
||||
//查询分类里面是否有
|
||||
CanteenOnlineCategoryEntity canteenOnlineCategoryEntity = canteenOnlineCategoryMapper.selectOne(new LambdaQueryWrapper<CanteenOnlineCategoryEntity>().eq(CanteenOnlineCategoryEntity::getName, name));
|
||||
if (canteenOnlineCategoryEntity == null){
|
||||
CanteenOnlineCategoryEntity bean = BeanUtils.toBean(canteenCategoryEntity, CanteenOnlineCategoryEntity.class);
|
||||
canteenOnlineCategoryMapper.insert(bean);
|
||||
c.setCategoryId(bean.getId());
|
||||
}else {
|
||||
c.setCategoryId(canteenOnlineCategoryEntity.getId());
|
||||
}
|
||||
c.setMerchantId(merchantId);
|
||||
c.setDeptId(deptId);
|
||||
});
|
||||
return baseMapper.insert(canteenSpuEntities);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object pageScope(Page page, LambdaQueryWrapper<CanteenOnlineSpuEntity> wrapper) {
|
||||
return baseMapper.selectPageByScope(page, wrapper, DataScope.of());
|
||||
}
|
||||
}
|
||||
+2
@@ -17,5 +17,7 @@
|
||||
<result property="updateTime" column="update_time"/>
|
||||
<result property="delFlag" column="del_flag"/>
|
||||
<result property="tenantId" column="tenant_id"/>
|
||||
<result property="merchantId" column="merchant_id"/>
|
||||
<result property="categoryType" column="category_type"/>
|
||||
</resultMap>
|
||||
</mapper>
|
||||
+1
@@ -28,5 +28,6 @@
|
||||
<result property="updateTime" column="update_time"/>
|
||||
<result property="delFlag" column="del_flag"/>
|
||||
<result property="tenantId" column="tenant_id"/>
|
||||
<result property="linkSpuId" column="link_spu_id"/>
|
||||
</resultMap>
|
||||
</mapper>
|
||||
+2
@@ -6,6 +6,8 @@ import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
public class NoticeScreenVo {
|
||||
|
||||
private Long id;
|
||||
@Schema(description = "标题")
|
||||
private String title;
|
||||
|
||||
|
||||
@@ -0,0 +1,387 @@
|
||||
# 外部系统滚动通知接口集成指南
|
||||
|
||||
## 📋 概述
|
||||
|
||||
本文档介绍如何集成使用 PJCloud 系统的滚动通知接口,该接口提供安全的 API 访问,供外部系统获取滚动通知信息。
|
||||
|
||||
## 🔐 认证方式
|
||||
|
||||
接口采用 **AppId + AppSecret** 的认证方式,通过 HTTP 请求头进行身份验证。
|
||||
|
||||
### 认证参数
|
||||
|
||||
| 参数名 | 位置 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| X-App-Id | 请求头 | 是 | 应用ID,由系统管理员分配 |
|
||||
| X-App-Secret | 请求头 | 是 | 应用密钥,由系统管理员分配 |
|
||||
|
||||
## 🌐 接口信息
|
||||
|
||||
### 滚动通知接口
|
||||
|
||||
- **接口地址**: `GET /notice/external/scroll`
|
||||
- **请求方式**: GET
|
||||
- **认证方式**: 请求头认证
|
||||
- **数据格式**: JSON
|
||||
|
||||
### 请求参数
|
||||
|
||||
#### 查询参数
|
||||
| 参数名 | 必填 | 默认值 | 说明 |
|
||||
|--------|------|--------|------|
|
||||
| limit | 否 | 20 | 返回条数,最大50条 |
|
||||
|
||||
#### 请求头示例
|
||||
```http
|
||||
X-App-Id: 202501270001
|
||||
X-App-Secret: 550e8400-e29b-41d4-a716-446655440001
|
||||
```
|
||||
|
||||
## 📡 响应格式
|
||||
|
||||
### 成功响应
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"msg": "操作成功",
|
||||
"data": [
|
||||
{
|
||||
"title": "系统维护通知",
|
||||
"createTime": "2025-01-27 10:00:00",
|
||||
"description": "系统将于今晚进行维护升级"
|
||||
},
|
||||
{
|
||||
"title": "新功能上线",
|
||||
"createTime": "2025-01-26 15:30:00",
|
||||
"description": "新增用户管理功能模块"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 错误响应
|
||||
```json
|
||||
{
|
||||
"code": 500,
|
||||
"msg": "无效的应用ID或密钥",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
## 💻 集成示例
|
||||
|
||||
### JavaScript 调用示例
|
||||
|
||||
#### 基础调用
|
||||
```javascript
|
||||
// 获取滚动通知
|
||||
async function getScrollNotices(limit = 20) {
|
||||
try {
|
||||
const response = await fetch('/notice/external/scroll?limit=' + limit, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'X-App-Id': '202501270001',
|
||||
'X-App-Secret': '550e8400-e29b-41d4-a716-446655440001',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.code === 0) {
|
||||
return result.data;
|
||||
} else {
|
||||
throw new Error(result.msg);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取通知失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 使用示例
|
||||
getScrollNotices(15)
|
||||
.then(notices => {
|
||||
console.log('获取到通知:', notices);
|
||||
// 处理通知数据
|
||||
displayNotices(notices);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('错误:', error.message);
|
||||
});
|
||||
```
|
||||
|
||||
#### 滚动展示组件
|
||||
```javascript
|
||||
// 滚动通知展示组件
|
||||
class ScrollNoticeDisplay {
|
||||
constructor(containerId, appId, appSecret) {
|
||||
this.container = document.getElementById(containerId);
|
||||
this.appId = appId;
|
||||
this.appSecret = appSecret;
|
||||
this.notices = [];
|
||||
this.currentIndex = 0;
|
||||
this.interval = null;
|
||||
}
|
||||
|
||||
// 获取通知数据
|
||||
async fetchNotices() {
|
||||
try {
|
||||
const response = await fetch('/notice/external/scroll?limit=10', {
|
||||
headers: {
|
||||
'X-App-Id': this.appId,
|
||||
'X-App-Secret': this.appSecret
|
||||
}
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
if (result.code === 0) {
|
||||
this.notices = result.data;
|
||||
this.startScroll();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取通知失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 开始滚动
|
||||
startScroll() {
|
||||
if (this.notices.length === 0) return;
|
||||
|
||||
this.interval = setInterval(() => {
|
||||
this.showNextNotice();
|
||||
}, 3000); // 每3秒切换一次
|
||||
|
||||
this.showNextNotice(); // 立即显示第一条
|
||||
}
|
||||
|
||||
// 显示下一条通知
|
||||
showNextNotice() {
|
||||
if (this.notices.length === 0) return;
|
||||
|
||||
const notice = this.notices[this.currentIndex];
|
||||
this.container.innerHTML = `
|
||||
<div class="notice-item">
|
||||
<span class="notice-title">${notice.title}</span>
|
||||
<span class="notice-time">${notice.createTime}</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
this.currentIndex = (this.currentIndex + 1) % this.notices.length;
|
||||
}
|
||||
|
||||
// 停止滚动
|
||||
stopScroll() {
|
||||
if (this.interval) {
|
||||
clearInterval(this.interval);
|
||||
this.interval = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 使用示例
|
||||
const noticeDisplay = new ScrollNoticeDisplay(
|
||||
'notice-container',
|
||||
'202501270001',
|
||||
'550e8400-e29b-41d4-a716-446655440001'
|
||||
);
|
||||
|
||||
noticeDisplay.fetchNotices();
|
||||
```
|
||||
|
||||
### cURL 调用示例
|
||||
|
||||
#### 基础调用
|
||||
```bash
|
||||
curl -X GET "http://your-domain/notice/external/scroll?limit=15" \
|
||||
-H "X-App-Id: 202501270001" \
|
||||
-H "X-App-Secret: 550e8400-e29b-41d4-a716-446655440001"
|
||||
```
|
||||
|
||||
#### 获取最大条数
|
||||
```bash
|
||||
curl -X GET "http://your-domain/notice/external/scroll?limit=50" \
|
||||
-H "X-App-Id: 202501270001" \
|
||||
-H "X-App-Secret: 550e8400-e29b-41d4-a716-446655440001"
|
||||
```
|
||||
|
||||
### Java 调用示例
|
||||
|
||||
```java
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
public class NoticeApiClient {
|
||||
|
||||
private final String baseUrl;
|
||||
private final String appId;
|
||||
private final String appSecret;
|
||||
private final RestTemplate restTemplate;
|
||||
|
||||
public NoticeApiClient(String baseUrl, String appId, String appSecret) {
|
||||
this.baseUrl = baseUrl;
|
||||
this.appId = appId;
|
||||
this.appSecret = appSecret;
|
||||
this.restTemplate = new RestTemplate();
|
||||
}
|
||||
|
||||
public List<NoticeScreenVo> getScrollNotices(int limit) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.set("X-App-Id", appId);
|
||||
headers.set("X-App-Secret", appSecret);
|
||||
|
||||
HttpEntity<String> entity = new HttpEntity<>(headers);
|
||||
|
||||
String url = baseUrl + "/notice/external/scroll?limit=" + limit;
|
||||
|
||||
ResponseEntity<ApiResponse> response = restTemplate.exchange(
|
||||
url,
|
||||
HttpMethod.GET,
|
||||
entity,
|
||||
ApiResponse.class
|
||||
);
|
||||
|
||||
if (response.getBody() != null && response.getBody().getCode() == 0) {
|
||||
return response.getBody().getData();
|
||||
}
|
||||
|
||||
throw new RuntimeException("获取通知失败");
|
||||
}
|
||||
}
|
||||
|
||||
// 使用示例
|
||||
NoticeApiClient client = new NoticeApiClient(
|
||||
"http://your-domain",
|
||||
"202501270001",
|
||||
"550e8400-e29b-41d4-a716-446655440001"
|
||||
);
|
||||
|
||||
List<NoticeScreenVo> notices = client.getScrollNotices(20);
|
||||
```
|
||||
|
||||
## 🎨 CSS 样式示例
|
||||
|
||||
```css
|
||||
/* 滚动通知容器 */
|
||||
.notice-container {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
background: linear-gradient(90deg, #f8f9fa, #e9ecef);
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* 通知项 */
|
||||
.notice-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px 16px;
|
||||
height: 100%;
|
||||
animation: slideIn 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
/* 通知标题 */
|
||||
.notice-title {
|
||||
font-weight: 500;
|
||||
color: #495057;
|
||||
flex: 1;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/* 通知时间 */
|
||||
.notice-time {
|
||||
font-size: 12px;
|
||||
color: #6c757d;
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
/* 滑动动画 */
|
||||
@keyframes slideIn {
|
||||
from {
|
||||
transform: translateX(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.notice-container {
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.notice-item {
|
||||
padding: 12px 16px;
|
||||
}
|
||||
|
||||
.notice-time {
|
||||
display: none; /* 移动端隐藏时间 */
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
### 安全要求
|
||||
1. **密钥保护**: 请妥善保管 AppSecret,不要泄露给第三方
|
||||
2. **HTTPS 传输**: 建议使用 HTTPS 协议进行数据传输
|
||||
3. **访问频率**: 建议控制调用频率,避免频繁请求
|
||||
|
||||
### 技术限制
|
||||
1. **返回条数**: 单次请求最多返回 50 条通知
|
||||
2. **数据时效**: 只返回已发布的公告信息
|
||||
3. **排序规则**: 按置顶状态和创建时间倒序排列
|
||||
|
||||
### 错误处理
|
||||
1. **认证失败**: 检查 AppId 和 AppSecret 是否正确
|
||||
2. **网络异常**: 实现重试机制和超时处理
|
||||
3. **数据异常**: 对返回数据进行有效性验证
|
||||
|
||||
## 🔧 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
#### 1. 认证失败
|
||||
**错误信息**: "无效的应用ID或密钥"
|
||||
**解决方案**:
|
||||
- 检查 AppId 和 AppSecret 是否正确
|
||||
- 确认应用是否已启用
|
||||
- 联系系统管理员验证配置
|
||||
|
||||
#### 2. 网络超时
|
||||
**错误信息**: 请求超时或无响应
|
||||
**解决方案**:
|
||||
- 检查网络连接
|
||||
- 确认服务器地址是否正确
|
||||
- 实现请求超时和重试机制
|
||||
|
||||
#### 3. 数据为空
|
||||
**可能原因**:
|
||||
- 当前没有已发布的公告
|
||||
- 查询参数设置不当
|
||||
- 系统维护中
|
||||
|
||||
## 📞 技术支持
|
||||
|
||||
如果在集成过程中遇到问题,请联系技术支持:
|
||||
|
||||
- **技术文档**: 本文档
|
||||
- **API 地址**: `/notice/external/scroll`
|
||||
- **认证方式**: AppId + AppSecret
|
||||
- **数据格式**: JSON
|
||||
|
||||
---
|
||||
|
||||
*最后更新时间: 2025-01-27*
|
||||
*版本: v1.0*
|
||||
@@ -0,0 +1,98 @@
|
||||
# 外部系统滚动通知接口使用说明
|
||||
|
||||
## 接口概述
|
||||
|
||||
提供安全的API访问,供其他系统获取滚动通知信息。
|
||||
|
||||
## 接口信息
|
||||
|
||||
- **接口地址**: `GET /notice/external/scroll`
|
||||
- **请求方式**: GET
|
||||
- **认证方式**: 请求头认证
|
||||
|
||||
## 请求参数
|
||||
|
||||
### 请求头
|
||||
| 参数名 | 必填 | 说明 |
|
||||
|--------|------|------|
|
||||
| X-App-Id | 是 | 应用ID,在配置文件中配置 |
|
||||
| X-App-Secret | 是 | 应用密钥,在配置文件中配置 |
|
||||
|
||||
### 查询参数
|
||||
| 参数名 | 必填 | 默认值 | 说明 |
|
||||
|--------|------|--------|------|
|
||||
| limit | 否 | 20 | 返回条数,最大50条 |
|
||||
|
||||
## 响应格式
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"msg": "操作成功",
|
||||
"data": [
|
||||
{
|
||||
"title": "通知标题",
|
||||
"createTime": "2025-01-27 10:00:00",
|
||||
"description": "通知描述"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 使用示例
|
||||
|
||||
### JavaScript 调用示例
|
||||
```javascript
|
||||
fetch('/notice/external/scroll?limit=15', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'X-App-Id': 'external_app_001',
|
||||
'X-App-Secret': 'secret_2024_001'
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.code === 0) {
|
||||
// 处理通知数据
|
||||
console.log(data.data);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('获取通知失败:', error);
|
||||
});
|
||||
```
|
||||
|
||||
### cURL 调用示例
|
||||
```bash
|
||||
curl -X GET "http://your-domain/notice/external/scroll?limit=10" \
|
||||
-H "X-App-Id: external_app_001" \
|
||||
-H "X-App-Secret: secret_2024_001"
|
||||
```
|
||||
|
||||
## 配置说明
|
||||
|
||||
在 `application.yml` 中添加以下配置:
|
||||
|
||||
```yaml
|
||||
pjcloud:
|
||||
external-app:
|
||||
apps:
|
||||
- appId: "your_app_id"
|
||||
appSecret: "your_app_secret"
|
||||
appName: "你的应用名称"
|
||||
enabled: true
|
||||
```
|
||||
|
||||
## 安全特性
|
||||
|
||||
1. **应用认证**: 通过 appId 和 appSecret 验证调用方身份
|
||||
2. **访问控制**: 只返回已发布的公告
|
||||
3. **数据限制**: 限制最大返回条数,防止恶意调用
|
||||
4. **信息脱敏**: 只返回必要的滚动信息
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. 请妥善保管应用密钥,不要泄露给第三方
|
||||
2. 建议使用HTTPS协议进行传输
|
||||
3. 可以根据需要调整返回条数限制
|
||||
4. 支持动态启用/禁用应用访问权限
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.bsd.pjcloud.integrated.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 外部应用配置
|
||||
* 用于管理外部系统的应用ID和密钥
|
||||
*
|
||||
* @author zjf
|
||||
* @date 2025-01-27
|
||||
*/
|
||||
@Data
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "pjcloud.external-app")
|
||||
public class ExternalAppConfig {
|
||||
|
||||
/**
|
||||
* 外部应用列表
|
||||
*/
|
||||
private List<AppCredential> apps;
|
||||
|
||||
/**
|
||||
* 应用凭证
|
||||
*/
|
||||
@Data
|
||||
public static class AppCredential {
|
||||
/**
|
||||
* 应用ID
|
||||
*/
|
||||
private String appId;
|
||||
|
||||
/**
|
||||
* 应用密钥
|
||||
*/
|
||||
private String appSecret;
|
||||
|
||||
/**
|
||||
* 应用名称
|
||||
*/
|
||||
private String appName;
|
||||
|
||||
/**
|
||||
* 是否启用
|
||||
*/
|
||||
private Boolean enabled = true;
|
||||
}
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
package com.bsd.pjcloud.integrated.controller;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.bsd.pjcloud.common.core.util.R;
|
||||
import com.bsd.pjcloud.common.log.annotation.SysLog;
|
||||
import com.bsd.pjcloud.common.security.util.SecurityUtils;
|
||||
import com.bsd.pjcloud.integrated.entity.CleanUserEntity;
|
||||
import com.bsd.pjcloud.integrated.service.CleanUserService;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import com.bsd.pjcloud.common.excel.annotation.ResponseExcel;
|
||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||
import org.springdoc.core.annotations.ParameterObject;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 保洁信息
|
||||
*
|
||||
* @author zjf
|
||||
* @date 2025-08-11 11:07:52
|
||||
*/
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/cleanUser" )
|
||||
@Tag(description = "cleanUser" , name = "保洁信息管理" )
|
||||
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
|
||||
public class CleanUserController {
|
||||
|
||||
private final CleanUserService cleanUserService;
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
* @param page 分页对象
|
||||
* @param cleanUser 保洁信息
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "分页查询" , description = "分页查询" )
|
||||
@GetMapping("/page" )
|
||||
@PreAuthorize("@pms.hasPermission('integrated_cleanUser_view')" )
|
||||
public R getCleanUserPage(@ParameterObject Page page, @ParameterObject CleanUserEntity cleanUser) {
|
||||
LambdaQueryWrapper<CleanUserEntity> wrapper = Wrappers.lambdaQuery();
|
||||
wrapper.eq(StrUtil.isNotBlank(cleanUser.getName()),CleanUserEntity::getName,cleanUser.getName());
|
||||
wrapper.eq(StrUtil.isNotBlank(cleanUser.getPhone()),CleanUserEntity::getPhone,cleanUser.getPhone());
|
||||
return R.ok(cleanUserService.page(page, wrapper));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通过id查询保洁信息
|
||||
* @param id id
|
||||
* @return R
|
||||
*/
|
||||
@Operation(summary = "通过id查询" , description = "通过id查询" )
|
||||
@GetMapping("/{id}" )
|
||||
@PreAuthorize("@pms.hasPermission('integrated_cleanUser_view')" )
|
||||
public R getById(@PathVariable("id" ) Long id) {
|
||||
return R.ok(cleanUserService.getById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增保洁信息
|
||||
* @param cleanUser 保洁信息
|
||||
* @return R
|
||||
*/
|
||||
@Operation(summary = "新增保洁信息" , description = "新增保洁信息" )
|
||||
@SysLog("新增保洁信息" )
|
||||
@PostMapping
|
||||
@PreAuthorize("@pms.hasPermission('integrated_cleanUser_add')" )
|
||||
public R save(@RequestBody CleanUserEntity cleanUser) {
|
||||
cleanUser.setDeptId(SecurityUtils.getUser().getDeptId());
|
||||
return R.ok(cleanUserService.save(cleanUser));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改保洁信息
|
||||
* @param cleanUser 保洁信息
|
||||
* @return R
|
||||
*/
|
||||
@Operation(summary = "修改保洁信息" , description = "修改保洁信息" )
|
||||
@SysLog("修改保洁信息" )
|
||||
@PutMapping
|
||||
@PreAuthorize("@pms.hasPermission('integrated_cleanUser_edit')" )
|
||||
public R updateById(@RequestBody CleanUserEntity cleanUser) {
|
||||
return R.ok(cleanUserService.updateById(cleanUser));
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除保洁信息
|
||||
* @param ids id列表
|
||||
* @return R
|
||||
*/
|
||||
@Operation(summary = "通过id删除保洁信息" , description = "通过id删除保洁信息" )
|
||||
@SysLog("通过id删除保洁信息" )
|
||||
@DeleteMapping
|
||||
@PreAuthorize("@pms.hasPermission('integrated_cleanUser_del')" )
|
||||
public R removeById(@RequestBody Long[] ids) {
|
||||
return R.ok(cleanUserService.removeBatchByIds(CollUtil.toList(ids)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 导出excel 表格
|
||||
* @param cleanUser 查询条件
|
||||
* @param ids 导出指定ID
|
||||
* @return excel 文件流
|
||||
*/
|
||||
@ResponseExcel
|
||||
@GetMapping("/export")
|
||||
@PreAuthorize("@pms.hasPermission('integrated_cleanUser_export')" )
|
||||
public List<CleanUserEntity> export(CleanUserEntity cleanUser,Long[] ids) {
|
||||
return cleanUserService.list(Wrappers.lambdaQuery(cleanUser).in(ArrayUtil.isNotEmpty(ids), CleanUserEntity::getId, ids));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取保洁用户下拉列表
|
||||
* @return R
|
||||
*/
|
||||
@Operation(summary = "获取保洁用户下拉列表", description = "获取保洁用户下拉列表")
|
||||
@GetMapping("/dropdown")
|
||||
// @PreAuthorize("@pms.hasPermission('integrated_cleanUser_view')")
|
||||
public R getCleanUserDropdown() {
|
||||
LambdaQueryWrapper<CleanUserEntity> wrapper = Wrappers.lambdaQuery();
|
||||
wrapper.select(CleanUserEntity::getId, CleanUserEntity::getName, CleanUserEntity::getPhone);
|
||||
wrapper.orderByAsc(CleanUserEntity::getName);
|
||||
List<CleanUserEntity> list = cleanUserService.list(wrapper);
|
||||
return R.ok(list);
|
||||
}
|
||||
}
|
||||
+71
@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.bsd.pjcloud.common.core.util.R;
|
||||
import com.bsd.pjcloud.common.log.annotation.SysLog;
|
||||
import com.bsd.pjcloud.common.security.annotation.Inner;
|
||||
import com.bsd.pjcloud.common.security.util.SecurityUtils;
|
||||
import com.bsd.pjcloud.integrated.entity.NoticeEntity;
|
||||
import com.bsd.pjcloud.integrated.service.NoticeService;
|
||||
@@ -22,6 +23,7 @@ import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import com.bsd.pjcloud.integrated.vo.notice.NoticeScreenVo;
|
||||
import java.util.stream.Collectors;
|
||||
import com.bsd.pjcloud.integrated.config.ExternalAppConfig;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@@ -40,6 +42,7 @@ import java.util.Objects;
|
||||
public class NoticeController {
|
||||
|
||||
private final NoticeService noticeService;
|
||||
private final ExternalAppConfig externalAppConfig;
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
@@ -192,4 +195,72 @@ public class NoticeController {
|
||||
}).collect(Collectors.toList());
|
||||
return R.ok(voList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 外部系统滚动通知接口
|
||||
* 提供安全的API访问,用于其他系统展示滚动通知
|
||||
* @param appId 应用ID
|
||||
* @param appSecret 应用密钥
|
||||
* @param limit 返回条数限制,默认20条
|
||||
* @return R
|
||||
*/
|
||||
@Operation(summary = "外部系统滚动通知接口", description = "提供安全的API访问,用于其他系统展示滚动通知")
|
||||
@GetMapping("/external/scroll")
|
||||
@Inner(value = false)
|
||||
public R getExternalScrollNotices(
|
||||
@RequestHeader("X-App-Id") String appId,
|
||||
@RequestHeader("X-App-Secret") String appSecret,
|
||||
@RequestParam(defaultValue = "20") Integer limit) {
|
||||
|
||||
// 验证应用ID和密钥
|
||||
if (!isValidAppCredentials(appId, appSecret)) {
|
||||
return R.failed("无效的应用ID或密钥");
|
||||
}
|
||||
|
||||
// 限制最大返回条数,防止恶意调用
|
||||
if (limit > 50) {
|
||||
limit = 50;
|
||||
}
|
||||
|
||||
LambdaQueryWrapper<NoticeEntity> wrapper = Wrappers.lambdaQuery();
|
||||
wrapper.eq(NoticeEntity::getStatus, "0"); // 只查询已发布的公告
|
||||
wrapper.orderByDesc(NoticeEntity::getIsTop, NoticeEntity::getCreateTime); // 置顶优先,时间倒序
|
||||
wrapper.last("limit " + limit);
|
||||
|
||||
List<NoticeEntity> list = noticeService.list(wrapper);
|
||||
|
||||
// 转换为简化的VO对象,只返回必要信息
|
||||
List<NoticeScreenVo> voList = list.stream().map(e -> {
|
||||
NoticeScreenVo vo = new NoticeScreenVo();
|
||||
vo.setId(e.getId());
|
||||
vo.setTitle(e.getTitle());
|
||||
vo.setCreateTime(e.getCreateTime());
|
||||
vo.setDescription(e.getDescription());
|
||||
return vo;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
return R.ok(voList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证应用ID和密钥
|
||||
* @param appId 应用ID
|
||||
* @param appSecret 应用密钥
|
||||
* @return 是否有效
|
||||
*/
|
||||
private boolean isValidAppCredentials(String appId, String appSecret) {
|
||||
// 从配置中读取有效的应用ID和密钥
|
||||
if (StrUtil.isBlank(appId) || StrUtil.isBlank(appSecret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 从配置中验证应用凭证
|
||||
if (externalAppConfig.getApps() != null) {
|
||||
return externalAppConfig.getApps().stream()
|
||||
.filter(ExternalAppConfig.AppCredential::getEnabled)
|
||||
.anyMatch(app -> appId.equals(app.getAppId()) && appSecret.equals(app.getAppSecret()));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
package com.bsd.pjcloud.integrated.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import com.bsd.pjcloud.common.core.util.TenantTable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 保洁信息
|
||||
*
|
||||
* @author zjf
|
||||
* @date 2025-08-11 11:07:52
|
||||
*/
|
||||
@Data
|
||||
@TenantTable
|
||||
@TableName("clean_user")
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Schema(description = "保洁信息")
|
||||
public class CleanUserEntity extends Model<CleanUserEntity> {
|
||||
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@Schema(description="id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 姓名
|
||||
*/
|
||||
@Schema(description="姓名")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
@Schema(description="手机号")
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* 部门id
|
||||
*/
|
||||
@Schema(description="部门id")
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 照片
|
||||
*/
|
||||
@Schema(description="照片")
|
||||
private String picUrl;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
@Schema(description="创建者")
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
@Schema(description="创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
@Schema(description="更新者")
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
@Schema(description="更新时间")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 是否删除
|
||||
*/
|
||||
@TableLogic
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
@Schema(description="是否删除")
|
||||
private String delFlag;
|
||||
|
||||
/**
|
||||
* 租户编号
|
||||
*/
|
||||
@Schema(description="租户编号")
|
||||
private Long tenantId;
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package com.bsd.pjcloud.integrated.mapper;
|
||||
|
||||
import com.bsd.pjcloud.common.data.datascope.PjcloudBaseMapper;
|
||||
import com.bsd.pjcloud.integrated.entity.CleanUserEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface CleanUserMapper extends PjcloudBaseMapper<CleanUserEntity> {
|
||||
|
||||
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package com.bsd.pjcloud.integrated.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.bsd.pjcloud.integrated.entity.CleanUserEntity;
|
||||
|
||||
public interface CleanUserService extends IService<CleanUserEntity> {
|
||||
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.bsd.pjcloud.integrated.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.bsd.pjcloud.integrated.entity.CleanUserEntity;
|
||||
import com.bsd.pjcloud.integrated.mapper.CleanUserMapper;
|
||||
import com.bsd.pjcloud.integrated.service.CleanUserService;
|
||||
import org.springframework.stereotype.Service;
|
||||
/**
|
||||
* 保洁信息
|
||||
*
|
||||
* @author zjf
|
||||
* @date 2025-08-11 11:07:52
|
||||
*/
|
||||
@Service
|
||||
public class CleanUserServiceImpl extends ServiceImpl<CleanUserMapper, CleanUserEntity> implements CleanUserService {
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
# 外部应用配置示例
|
||||
# 将此配置添加到你的 application.yml 或 application-{profile}.yml 文件中
|
||||
|
||||
pjcloud:
|
||||
external-app:
|
||||
apps:
|
||||
# 外部系统1
|
||||
- appId: "202501270001"
|
||||
appSecret: "550e8400-e29b-41d4-a716-446655440001"
|
||||
appName: "外部系统A"
|
||||
enabled: true
|
||||
|
||||
# 外部系统2
|
||||
- appId: "202501270002"
|
||||
appSecret: "550e8400-e29b-41d4-a716-446655440002"
|
||||
appName: "外部系统B"
|
||||
enabled: true
|
||||
|
||||
# 外部系统3
|
||||
- appId: "202501270003"
|
||||
appSecret: "550e8400-e29b-41d4-a716-446655440003"
|
||||
appName: "外部系统C"
|
||||
enabled: true
|
||||
|
||||
# 外部系统4(已禁用)
|
||||
- appId: "202501270004"
|
||||
appSecret: "550e8400-e29b-41d4-a716-446655440004"
|
||||
appName: "外部系统D"
|
||||
enabled: false
|
||||
@@ -26,3 +26,11 @@ spring:
|
||||
visitor:
|
||||
jwt-secret: "u8Jk2n3Lk4pQ5r6T7s8V9w0X1y2Z3a4B"
|
||||
qr-secret: "Qw8eR2t9Yp3sV6bN1mZ4xT7cL0vB5nH2" # 新增二维码secret,随机生成
|
||||
|
||||
pjcloud:
|
||||
external-app:
|
||||
apps:
|
||||
- appId: "202501270001"
|
||||
appSecret: "550e8400-e29b-41d4-a716-446655440001"
|
||||
appName: "通知公告"
|
||||
enabled: true
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
<?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.bsd.pjcloud.integrated.mapper.CleanUserMapper">
|
||||
|
||||
<resultMap id="cleanUserMap" type="com.bsd.pjcloud.integrated.entity.CleanUserEntity">
|
||||
<id property="id" column="id"/>
|
||||
<result property="name" column="name"/>
|
||||
<result property="phone" column="phone"/>
|
||||
<result property="deptId" column="dept_id"/>
|
||||
<result property="picUrl" column="pic_url"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
<result property="delFlag" column="del_flag"/>
|
||||
<result property="tenantId" column="tenant_id"/>
|
||||
</resultMap>
|
||||
</mapper>
|
||||
+25
-5
@@ -107,6 +107,10 @@ public class SmErpInventoryRecordsServiceImpl extends ServiceImpl<SmErpInventory
|
||||
|
||||
List<SmErpInventoryRecordsItemEntity> cgPlanItemEntities = BeanUtils.toBean(items, SmErpInventoryRecordsItemEntity.class);
|
||||
List<UpdateStockDTO> updateStockDTOS = new ArrayList<>();
|
||||
Set<Long> units = cgPlanItemEntities.stream().map(s -> s.getUnitId()).collect(Collectors.toSet());
|
||||
List<SmErpUnitEntity> smErpUnitEntities = smErpUnitMapper.selectList(new LambdaQueryWrapper<SmErpUnitEntity>().in(SmErpUnitEntity::getId, units));
|
||||
Map<Long, SmErpUnitEntity> unitMap = smErpUnitEntities.stream().collect(Collectors.toMap(SmErpUnitEntity::getId, unit -> unit));
|
||||
|
||||
for (SmErpInventoryRecordsItemEntity cgPlanItemEntity : cgPlanItemEntities) {
|
||||
cgPlanItemEntity.setInventoryId(smErpCgDdEntity.getId());
|
||||
cgPlanItemEntity.setDeptId(deptId);
|
||||
@@ -115,10 +119,11 @@ public class SmErpInventoryRecordsServiceImpl extends ServiceImpl<SmErpInventory
|
||||
Double quantity = cgPlanItemEntity.getQuantity();
|
||||
String orderType = smErpCgDdEntity.getOrderType();
|
||||
cgPlanItemEntity.setOrderType(orderType);
|
||||
Integer packageNum = unitMap.get(cgPlanItemEntity.getUnitId()).getPackageNum();
|
||||
if (orderType.equals(OrderTypeEnum.RK.getType())){
|
||||
updateStockDTO.setIncrCount(quantity);
|
||||
updateStockDTO.setIncrCount(packageNum*quantity);
|
||||
}else if (orderType.equals(OrderTypeEnum.CK.getType())){
|
||||
updateStockDTO.setIncrCount(-quantity);
|
||||
updateStockDTO.setIncrCount(-packageNum*quantity);
|
||||
}else if (orderType.equals(OrderTypeEnum.No.getType())){
|
||||
//无需更新库存
|
||||
}else {
|
||||
@@ -460,6 +465,9 @@ public class SmErpInventoryRecordsServiceImpl extends ServiceImpl<SmErpInventory
|
||||
List<InventoryRecordEditItemDTO> items = inventoryRecordEditDTO.getItems();
|
||||
List<UpdateStockDTO> updateStockDTOS = new ArrayList<>();
|
||||
List<SmErpInventoryRecordsItemEntity> smErpInventoryRecordsItemEntityList = new ArrayList<>();
|
||||
Set<Long> units = items.stream().map(s -> s.getUnitId()).collect(Collectors.toSet());
|
||||
List<SmErpUnitEntity> smErpUnitEntities = smErpUnitMapper.selectList(new LambdaQueryWrapper<SmErpUnitEntity>().in(SmErpUnitEntity::getId, units));
|
||||
Map<Long, SmErpUnitEntity> unitMap = smErpUnitEntities.stream().collect(Collectors.toMap(SmErpUnitEntity::getId, unit -> unit));
|
||||
|
||||
for (InventoryRecordEditItemDTO item : items){
|
||||
SmErpInventoryRecordsItemEntity smErpInventoryRecordsItemEntity = new SmErpInventoryRecordsItemEntity();
|
||||
@@ -470,10 +478,11 @@ public class SmErpInventoryRecordsServiceImpl extends ServiceImpl<SmErpInventory
|
||||
Double quantity = item.getQuantity();
|
||||
String orderType = item.getOrderType();
|
||||
smErpInventoryRecordsItemEntity.setOrderType(orderType);
|
||||
Integer packageNum = unitMap.get(item.getUnitId()).getPackageNum();
|
||||
if (orderType.equals(OrderTypeEnum.RK.getType())){
|
||||
updateStockDTO.setIncrCount(quantity);
|
||||
updateStockDTO.setIncrCount(packageNum*quantity);
|
||||
}else if (orderType.equals(OrderTypeEnum.CK.getType())){
|
||||
updateStockDTO.setIncrCount(-quantity);
|
||||
updateStockDTO.setIncrCount(packageNum*-quantity);
|
||||
}else {
|
||||
throw new RuntimeException("订单类型错误");
|
||||
}
|
||||
@@ -499,11 +508,22 @@ public class SmErpInventoryRecordsServiceImpl extends ServiceImpl<SmErpInventory
|
||||
List<SmErpInventoryRecordsItemEntity> dataBaseSmErpInventoryRecordsItemEntityList = smErpInventoryRecordsItemMapper
|
||||
.selectList(new LambdaQueryWrapper<SmErpInventoryRecordsItemEntity>().eq(SmErpInventoryRecordsItemEntity::getInventoryId, inventoryRecordEditDTO.getId()));
|
||||
|
||||
|
||||
Set<Long> unitsRemoved = dataBaseSmErpInventoryRecordsItemEntityList.stream().map(s -> s.getUnitId()).collect(Collectors.toSet());
|
||||
List<SmErpUnitEntity> smErpUnitEntitiesRemoved = smErpUnitMapper.selectList(new LambdaQueryWrapper<SmErpUnitEntity>().in(SmErpUnitEntity::getId, unitsRemoved));
|
||||
Map<Long, SmErpUnitEntity> unitMapRemoved = smErpUnitEntitiesRemoved.stream().collect(Collectors.toMap(SmErpUnitEntity::getId, unit -> unit));
|
||||
|
||||
//这部分是数据库原本添加的库存数据,需要全部减掉,重新添加更新的库存数据进去
|
||||
dataBaseSmErpInventoryRecordsItemEntityList.forEach(item -> {
|
||||
Integer packageNum = unitMapRemoved.get(item.getUnitId()).getPackageNum();
|
||||
UpdateStockDTO updateStockDTO = new UpdateStockDTO();
|
||||
updateStockDTO.setId(item.getErpSpuId());
|
||||
updateStockDTO.setIncrCount(-item.getQuantity());
|
||||
if (item.getOrderType().equals(OrderTypeEnum.RK.getType())){
|
||||
updateStockDTO.setIncrCount(-packageNum *item.getQuantity());
|
||||
}
|
||||
if (item.getOrderType().equals(OrderTypeEnum.CK.getType())){
|
||||
updateStockDTO.setIncrCount(packageNum *item.getQuantity());
|
||||
}
|
||||
updateStockDTOS.add(updateStockDTO);
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user