基于Spring Boot+Vue的助农销售平台(协同过滤算法、限流算法、支付宝沙盒支付、实时聊天、图形化分析)

🎈系统亮点:协同过滤算法、节流算法、支付宝沙盒支付、图形化分析、实时聊天;

一.系统开发工具与环境搭建

1.系统设计开发工具


后端使用Java编程语言的Spring boot框架
项目架构:B/S架构
运行环境:win10/win11、jdk17


前端:
技术:框架Vue.js;UI库:ElementUI;
开发工具:Visual Studio Code;



后端:
技术:Java语言、mybatis plus、Spring boot框架;
开发工具:IDEA 2023.3.3版本;



数据库:
数据库:mysql5.7/8.0
数据库工具:Navicat12版本;


二. 系统实现(部分展示)

1 客户模块

1.1 系统首页模块

首页展示官方精选的一些农产品种类和农产品,吸引客户的注意力。前端为了方便客户去查找其他的界面,在首页设置了农产品大全、农产圈、通知公告导航地址,方便客户点击直接请求url进行跳转等界面。同时,还为客户提供注册和登录入口,方便客户进行账号管理。

 

0e91ce40b54adbf518f8086687d2949c.png

客户没登录前,可以浏览商品,但是不可以进行购买商品。当客户点击加入购物车,则会“请先登录,再操作”,随后前端会请求登录的url地址,跳转到登录页面,客户输入账号、密码,选择角色,输入验证码,点击“登录按钮”,前端将输入的数据作为参数,然后去请求/User/SignIn方法,进行登录操作。进入到商品详情页后,前端请求/Good/Get方法,返回商品详情的数据,展示在前台界面,商品详情页面包含农产品的详细描述、高清图片、规格参数、价格、库存、商品评价等信息。

 

d83db621fe0103a0a455dbfe3d5f54ef.png

后端关键代码展示如下:

@SneakyThrows
@Override
public GoodDto Get(GoodPagedInput input) {
if (input.getId() == null) {
return new GoodDto();
}
PagedResult<GoodDto> pagedResult = List(input);
return pagedResult.getTotalCount() > 0 ? pagedResult.getItems().stream().findFirst().get() : new GoodDto();
}

1.2 农产品大全模块

农产品大全,客户可以根据不同的类别浏览和筛选农产品。在页面的顶部放置了一个清晰的导航栏。导航栏中的分类可以按照农产品的种类进行分类。当客户点击某个分类链接时,导航到该分类的页面。在分类页面上,展示该类别下的所有商品。后端提供/Good/List接口,用于前端查询和筛选农产品信息。搜索框采用模糊查询,只要有正确的关键字,就可以搜索到与关键字相关的商品。农产品大全界面,如图所示。

 

b993d45a29da5e4a61012c32752cd916.png

通过协同过滤算法进行推荐商品,后端提供接口Good/Top10,进行请求推荐的商品。这个方法创建一个协同过滤对象,获取所有用户和订单。遍历所有用户。对于每个用户,找到他们购买的所有商品ID和购买次数。方法将用户ID、商品ID和评分添加到协同过滤对象中。初始化一个用于存储用户相似度的列表。再次遍历所有用户,但是不包含当前用户。对于每个其他用户,检查是否已经计算过与当前用户的相似度。如果还没有计算过相似度,调用方法来计算当前用户和其他用户的相似度。将用户ID对和相似度添加到列表中。查找与当前用户相似度最高的10个用户。遍历这些相似用户的购买记录,找到他们购买但当前用户没有购买的商品。根据相似度和购买次数等因素对这些商品进行排序,生成一个推荐列表,随后将推荐列表返回给当前用户。协同过滤推荐商品如图所示。

 

048c45d33818f173f4745144bea6958d.png

协同过滤算法推荐商品代码:

//随机推荐10个商品
LambdaQueryWrapper<Good> queryWrapper = Wrappers.<Good>lambdaQuery()
.eq(Good::getAuditStatus, Enums.AuditStatus.审核通过.index())
.orderByDesc(Good::getCreationTime)
.last("limit 10");
List<Good> goods = _GoodMpper.selectList(queryWrapper);
List<GoodDto> items = Extension.copyBeanList(goods, GoodDto.class);
return PagedResult.GetInstance(items, (long) 10);

1.3 话题模块

话题模块,前端发送请求后端/Topic/List接口,展示话题列表给前端,前端渲染到导航栏。当用户点击某个话题,前端将话题id作为参数传递给发送请求到后端,请求Topic/Get接口话题详细信息。后端返回话题详细信息给前端。用户发表新的评论,前端收集用户输入的内容,发送请求Comment/CreateOrEdit到后端。话题界面,如图所示。

 

 

f9653c67f26b32803a35e003e2c48ec8.png

关键代码:

//查询出关联的TopicType表信息
TopicTypeDto TopicTypeDTO = new TopicTypeDto();
TopicType TopicTypeEntity = _TopicTypeMapper.selectOne(Wrappers.<TopicType>lambdaQuery().eq(TopicType::getId, item.getTopicTypeId()));
if (TopicTypeEntity != null) {
BeanUtils.copyProperties(TopicTypeDTO, TopicTypeEntity);
item.setTopicTypeDto(TopicTypeDTO);
}

1.4 我的聊天模块

前端通过轮询的方式调用后端的聊天接口ChatTabulation/MyChatTabulationList。前端会每隔一段时间就向服务器发送一次请求,询问是否有新的聊天记录或者聊天消息。后端负责处理前端的请求,查询数据库中是否有新的聊天信息,然后将这些信息返回给前端。我的聊天界面,如图所示。

 

a2e5526982a2a7062bfca53283859062.png

关键代码:

//查询我们2个之间的所有聊天记录
LambdaQueryWrapper<ChatRecord> queryWrapper = Wrappers.<ChatRecord>lambdaQuery().eq(input.getSendUserId()!=null,ChatRecord::getSendUserId,input.getSendUserId()).eq(input.getReceiveUserId()!=null,ChatRecord::getReceiveUserId,input.getReceiveUserId()).or().eq(input.getSendUserId()!=null,ChatRecord::getSendUserId,input.getReceiveUserId()).eq(input.getReceiveUserId()!=null,ChatRecord::getReceiveUserId,input.getSendUserId());

1.5 我的购物车模块

我的购物车使用一个Vue.js组件,用于显示一个数据表格。它使用了Element UI库中的<data-table>组件来展示数据,通过调用url地址/BuyCard/List获取数据。客户可以查看自己的所有加入购物车的商品,支持移除商品或者选择商品去进行结算。我的购物车界面,如图所示。

 

2abdca49b5f85ec260c096571cd23108.png

客户选择商品进行结算,选择支付宝,首先会把填写的订单表单信息提交给后端,后端创建表单成功后会返回一个订单编号,然后根据订单编号去调用payOrder方法,该方法会通过http工具类去调用支付宝沙箱,然后返回一个支付宝表单form,然后把表单form字符串返回给前端,前端把返回的表单加载到当前页面的body,再触发submit事件提交,则会跳转到具体的支付宝支付页面,当客户完成支付的时候,支付宝会根据你设置的回调页面,最终跳转到系统的我的订单页面,从而完成业务的闭环。支付宝支付界面,如图所示。

 

5eb4bab264af82bab33225818a05bba6.png

关键代码:
 

OrderInfo orderInfo = _OrderInfoMpper.selectById(input.getId());
List<OrderDetail> orderDetails = _OrderDetailMapper.selectList(Wrappers.<OrderDetail>lambdaQuery().eq(OrderDetail::getOrderInfoId, orderInfo.getId()));
String body = "";
for (OrderDetail orderDetail : orderDetails) {body += orderDetail.getGoodName() + ",";
}
String result = AliPayHelper.CreatePay("测试系统购买", body, orderInfo.getCode().toString(), orderInfo.getTotalMoney().toString(), input.getCallBack());
return result;

5.1.6 我的订单模块

客户可以在个人中心查找我的订单,将客户Id传递/OrderInfo/List接口,进行调用,返回该客户的所有的订单。客户可以查看自己订单的明细,前端将订单Id传递给/OrderDetail/List接口,进行调用返回数据进行展示。当订单状态为已发货的时候,客户可以进行确认收货。在订单还没有发货的时候,可以选择取消订单。我的订单界面如图所示。

 

05c14f21842eadf004446ef1d39cb0a8.png

关键代码:

queryWrapper = queryWrapper.orderByDesc(OrderInfo::getCreationTime);
Page<OrderInfo> page = new Page<>(input.getPage(), input.getLimit());
IPage<OrderInfo> pageRecords = _OrderInfoMpper.selectPage(page, queryWrapper);
Long totalCount = _OrderInfoMpper.selectCount(queryWrapper);
List<OrderInfoDto> items = Extension.copyBeanList(pageRecords.getRecords(), OrderInfoDto.class);
List<Good> goodList = _GoodMpper.selectList(null).stream().toList();
List<GoodDto> goodDtoList = Extension.copyBeanList(goodList, GoodDto.class);

2 农户模块

2.1 商铺开店

农户想要进行开店,需要进行注册自己的店铺,输入店铺名称,将自己设计的logo进行上传,写入开店铺的地理位置,执业编号,注册的邮箱(邮箱使用正则表达式进行验证,不符合要求不允通过),身份证号(也是用正则表达式,18位,最后一位可以为数字或大写字母X),上传经营许可证,前端根据农户输入的数据进行请求/Shop/ShopRegister接口,查询数据库中是否存在与输入店铺名相同且审核状态为待审核的店铺。如果存在,则抛出一个自定义异常,说明“店铺名已经在审核中”。随后查询数据库,查看是否存在与输入店铺名相同且审核状态为审核通过的店铺。如果存在,则抛出异常,说明“店铺名已经在审核通过”。继续查询数据库中是否存在与输入店铺名相同、审核状态为待审核但id与当前店铺不同的店铺。如果存在,则抛出异常,说明“店铺名已经被其他人占用”。发送申请通过后,就等待管理员审核。商铺开店界面如图所示。

 

0bf056e7fa3b302cdcad5785af3ef10c.png

关键代码:

List<Shop> shopList = _ShopMpper.selectList(Wrappers.<Shop>lambdaQuery().eq(Shop::getName, input.getName()).in(Shop::getAuditStatus, Enums.AuditStatus.待审核.index()).ne(Shop::getId, input.getId()));
if (shopList.size() > 0) {throw new CustomException("店铺名已经被其他人占用");
}
shopList = _ShopMpper.selectList(Wrappers.<Shop>lambdaQuery().eq(Shop::getName, input.getName()).in(Shop::getAuditStatus, Enums.AuditStatus.审核通过.index()).ne(Shop::getId, input.getId()));
if (shopList.size() > 0) {throw new CustomException("店铺名已经被其他人占用");
}

2.2 我的店铺

农户可以装修自己的线上的店铺,修改店铺名称、店铺地址、封面、介绍等信息,前端会使用post方式请求Shop/CreateOrEdit接口,将农户修改的内容作为方法的入参进行传递,后端接收到前端的请求,进行操作店铺表,进行修改数据,并保存。执行完毕后,前端会将页面重新渲染,展示更新后的数据。我的店铺界面如图所示。

 

d1ae38c2a133640c89a310d2f528223a.png

关键代码:

Shop Shop = new Shop();
BeanUtils.copyProperties(Shop, input);
//调用数据库的增加或者修改方法
saveOrUpdate(Shop);
//定义一个返回给前端的店铺传输模型
ShopDto ShopDto = new ShopDto();
//同理把操作的店铺实体拷贝给店铺传输模型
BeanUtils.copyProperties(ShopDto, Shop);
//把传输模型返回给前端
return ShopDto;

2.3 农户店铺的订单

农户店铺的订单,农户可以进行发货处理,输入物流单号,进行发货,前端将订单信息以物流单号发送给后端/OrderInfo/CreateOrEdit接口,将物流单号填写到订单表,订单的状态从待发货改为已发货。农户店铺的订单界面,如图所示。

 

03258147d14cf5cd86f76439253d1b60.png

关键代码:

OrderInfo OrderInfo = new OrderInfo();
//把前端传入的input参数拷贝到订单实体
BeanUtils.copyProperties(OrderInfo, input);
//调用数据库的增加或者修改方法
saveOrUpdate(OrderInfo);
//定义一个返回给前端的订单传输模型
OrderInfoDto OrderInfoDto = new OrderInfoDto();
//同理把操作的订单实体拷贝给订单传输模型
BeanUtils.copyProperties(OrderInfoDto, OrderInfo);
//把传输模型返回给前端
return OrderInfoDto;

2.4 我的商品

农户进行管理自己店铺的商品,可以进行添加商品,以及添加商品的属性。前端会展示一个新增商品的模态框供农户输入商品的基本信息,然后将输入的商品信息传递给Good/CreateOrEdit接口,增加商品数据。请求成功后,前端关闭模态框。并执行商品列表查询接口,查询出最新的商品列表。我的商品界面,如图所示。

 

097e6dabbfefaa26fc5d9eaea67c974f.png

关键代码:

public GoodPropsDto Get(GoodPropsPagedInput input) {if(input.getId()==null){return new GoodPropsDto();}PagedResult<GoodPropsDto>  pagedResult =List(input);return pagedResult.getTotalCount()>0?pagedResult.getItems().stream().findFirst().get():new GoodPropsDto();
}

2.5 库存分析

农户的库存分析,使用ECharts 图表展示农产品库存Top10的数据。前端通过调用/OrderInfo/InventoryAnalyse,从后端获取数据。option 对象定义了 ECharts 图表的配置项。title: 设置了图表的标题为“农场品库存Top10”。legend: 设置了图例的位置和属性。xAxis: 定义了 x 轴的类型为“category”(分类),并使用 Data 数组中的 name 属性来设置轴标签。toolbox: 提供了图表工具箱,用户可以保存图表为图片、恢复原始配置或查看数据视图。yAxis: 定义了 y 轴的类型为“value”(数值)。series: 定义了数据系列,这里只有一个类型为“line”(折线)的系列。数据来自 Data 数组中的 value 属性,线条颜色被设置为黄色。库存分析界面,如图所示。

 

6822ea25a1e31c9f68d4e1bf44166be5.png

关键代码:

List<Good> list = _GoodMapper.selectList(null).stream().toList();
if (input.getShopIds() != null) {list = list.stream().filter(x -> input.getShopIds().contains(x.getShopId())).toList();
}
for (Good good : list) {Map<String, Object> data = new HashMap<>();data.put("name", good.getName());data.put("value", good.getStock());dataList.add(data);
}

3 管理员模块

3.1 农产品资讯管理

农产品资讯管理,前端使用 Vue.js 表单包含三个 el-form-item 组件,分别用于输入标题、选择浏览数范围和选择资讯类型。当管理员点击搜索按钮时,前端会触发TableSearch()方法,处理表格搜索的逻辑。将this.searchForm的数据被传递给 reload 方法。前端再调用/Topic/List方法。获取资讯列表。农产品资讯界面如图所示。

 

e2ce1422ca09f2ac17b7b96d92a50be8.png

关键代码:

//查询出关联的TopicType表信息
TopicTypeDto TopicTypeDTO = new TopicTypeDto();
TopicType TopicTypeEntity = _TopicTypeMapper.selectOne(Wrappers.<TopicType>lambdaQuery().eq(TopicType::getId, item.getTopicTypeId()));
if (TopicTypeEntity != null) {BeanUtils.copyProperties(TopicTypeDTO, TopicTypeEntity);item.setTopicTypeDto(TopicTypeDTO);
}

3.2 农产品管理

管理员主要对农户添加的商品进行审核或者下架不符合要求的商品。前端展示出一个修改的模态框,管理员可以对商品进行审核,调用后端方法Good/CreateOrEdit,更改商品的审核状态。随后前端会自动关闭模态框。农产品资讯界面如图所示。

 

0f7eddc91b517e1f3722023e1cc5095e.png

关键代码:

//按创建时间从大到小排序最新的显示在最前面
queryWrapper = queryWrapper.orderByDesc(Good::getCreationTime);
//构建一个分页查询的model
Page<Good> page = new Page<>(input.getPage(), input.getLimit());
//从数据库进行分页查询获取商品数据
IPage<Good> pageRecords = _GoodMpper.selectPage(page, queryWrapper);
//获取所有满足条件的数据行数
Long totalCount = _GoodMpper.selectCount(queryWrapper);
//把Good实体转换成Good传输模型
List<GoodDto> items = Extension.copyBeanList(pageRecords.getRecords(), GoodDto.class);
for (GoodDto item : items) {GoodInfoProcess(item);
}

3.3 优惠券管理

前端展示优惠券的名称、封面、金额、支付限制等基本信息。进入页面,直接通过post请求调用/Volumes/List接口,请求数据,将后端返回的数据通过前端vue进行渲染到界面。优惠券界面如图所示。

 

f4cb167780e28dbe188d08a528995e35.png

关键代码:

IPage<Volumes> pageRecords = _VolumesMpper.selectPage(page, queryWrapper);
Long totalCount = _VolumesMpper.selectCount(queryWrapper);
List<VolumesDto> items = Extension.copyBeanList(pageRecords.getRecords(), VolumesDto.class);
for (VolumesDto item : items) {AppUserDto CreatorAppUserDTO = new AppUserDto();AppUser CreatorAppUserEntity = _AppUserMapper.selectOne(Wrappers.<AppUser>lambdaQuery().eq(AppUser::getId, item.getCreatorId()));

3.4 店铺管理

管理员通过店铺管理,对农户的开店申请进行审核。显示所有开店申请的店铺名称、封面、账号、执业执照等信息列表。允许管理员通过关键词方式搜索和筛选开店申请。审核操作后,前端需要实时显示审核状态的变化,并给出相应的提示信息。店铺管理界面如图所示。

 

bb1d1b6b089186325ee24d384c8ee393.png

关键代码:

String Content = "";
if (input.getAuditStatus() == Enums.AuditStatus.审核通过.index()) {Content = "恭喜您,你的店铺" + input.getName() + "通过了系统的审核!,您可以正常完成账号信息的填写了,具体的链接为[http://localhost:9528/#/Register?ShopId=" + input.getId()+"]";
}
if (input.getAuditStatus() == Enums.AuditStatus.审核失败.index()) {Content = "很抱歉,您的店铺" + input.getName() + "未通过系统的审核,具体原因为:" + input.getAuditRemark();
}
EmailUtil.sendTextMail(input.getRegisterEmail(), "开店审核结果通知", Content);
三.需求分析

三.需求分析

1.客户

(1) 查询农产品:客户可以根据农产品的名称等关键字进行搜索,快速找到所需的农产品。搜索结果展示农产品的详细信息,包括图片、库存、售价等,方便客户查看。

(2) 加入购物车:客户可以将感兴趣的农产品加入购物车。购物车支持修改数量、删除商品等操作,客户可以调整购买商品的清单。点击购物车结算功能,客户可以选择支付方式完成购买。

(3) 农产圈交流:农产圈交流区,客户可以在这里发布自己的农产品信息、经验分享、问题求助等。其他客户可以浏览、评论和互动,形成一个活跃的农产品交流社区。

(4) 浏览通知公告:平台发布的重要通知、活动信息、政策变动等都会在通知公告区展示。客户可以随时浏览这些公告,了解平台的最新动态。

(5) 我的聊天:为了方便客户与客服人员进行即时沟通,解决他们在使用产品或服务过程中遇到的任何问题。通过“我的聊天”,客户可以轻松地与客服建立起联系,无论是询问产品详情、寻求技术支持,都能得到快速而有效的响应。

(6) 个人中心功能:

① 收藏话题资讯:客户可以收藏感兴趣的农产品话题资讯。

② 收货地址维护:客户可以添加、修改和删除收货地址。

③ 我的优惠券:展示客户领取的优惠券信息,包含是否使用,使用的订单等信息。

④ 我的订单:客户可以查看自己的订单状态以及订单明细,支持客户取消订单。

⑤ 我的购物车:展示客户购物车中的商品信息,方便客户随时查看和修改。

⑥ 我的资讯:客户可以查看自己发布的资讯,进行修改和删除。

 

2c0199f14ea863b625aa9af08c15b35b.png

2.管理员

(1) 客户管理:管理员管理客户的账户信息。查看客户资料、编辑客户权限以及在必要时删除不符合标准的账户。

(2) 通知公告管理:管理员可以发布、编辑和删除系统的通知和公告,确保客户可以及时获取到最新的系统更新、政策变更或其他重要信息。

(3) 农产品资讯管理:管理员可以添加、更新或删除农产品相关的资讯和文章,为客户提供丰富的农产品知识,帮助他们了解市场动态、种植技巧等有用信息。

(4) 店铺管理:管理员可以利用这个功能对接入平台的店铺进行管理,包括审核新店铺的入驻申请、更新店铺信息、监控店铺的销售行为等。

(5) 农产品管理:允许管理员对平台上销售的农产品进行审核,确保农产品信息的合规性。

(6) 订单管理:支持管理员查看订单详情、删除订单。

(7) 广告封面管理:管理员可以设计和更换平台的广告封面,以吸引客户注意力,提升平台的专业形象和客户体验。

(8) 优惠券管理:管理员可以创建、分发和管理优惠券,包括设置优惠券的使用条件、有效期和折扣额度,以此来激励客户消费,增加销售量。

 

3b25e1d53d36d5514d063428ccd7ed11.png

3.农户

(1) 实时聊天:允许农户与顾客进行实时沟通。无论是解答顾客的疑问,还是提供售后服务,实时聊天都能确保农户与顾客之间的沟通无障碍,从而提高顾客满意度和购物体验。

(2) 我的店铺管理:允许农户对自己的在线店铺进行全面管理。包括店铺的店铺名称、地址、封面、店铺介绍等基本信息设置。

(3) 我的商品管理:农户可以为店铺添加新商品、编辑现有商品信息,或者删除不再销售的商品。农户还可以设置商品的库存量、价格、商品介绍等信息,确保商品信息的准确与及时更新。

(4) 我的订单管理:农户可以在这里查看所有订单的状态,包括待发货、已发货和已完成、评价完成以及取消的订单。农户可以对订单进行发货操作,确保订单处理的高效与准确。

(5) 库存分析:可帮助农户跟踪商品的库存情况,预测库存需求,避免库存积压或缺货的情况发生。通过数据分析,农户可以更好地掌握库存动态,优化库存管理。

(6) 最近7天销量分析:帮助农户了解过去一周的销售情况。通过分析哪些商品销售良好,哪些不畅销,农户可以调整销售策略,提高销售效率。

(7) 最近30天销量分析:提供了一个月的销售数据,帮助农户从宏观角度把握销售趋势。农户可以根据这些数据来制定长期的销售计划和市场策略。

(8) 助农话题交流:农户可以通过参与这个话题,与客户进行交流互动,发布农产品的专业知识,为客户提供专业的知识见解。可以扩大自己的销售额,促进农村经济的发展。

 

08895e75f78fafdfaf9d9763dc1445a7.png

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/137.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

GetX的一些高级API

目录 前言 一、一些常用的API 二、局部状态组件 1.可选的全局设置和手动配置 2.局部状态组件 1.ValueBuilder 1.特点 2.基本用法 2.ObxValue 1.特点 2.基本用法 前言 这篇文章主要讲解GetX的一些高级API和一些有用的小组件。 一、一些常用的API GetX提供了一些高级…

第三届北京国际水利科技博览会将于25年3月在国家会议中心召开

由中国农业节水和农村供水技术协会、北京水利学会、振威国际会展集团等单位联合主办的第三届北京国际水利科技博览会暨供水技术与设备展&#xff08;北京水利展&#xff09;将于2025年3月31日至4月2日在北京•国家会议中心举办&#xff01; 博览会以“新制造、新服务、新业态”…

基于SpringBoot的学生读书笔记共享的设计与实现

一、项目背景 计算机的普及和互联网时代的到来使信息的发布和传播更加方便快捷。用户可以通过计算机上的浏览器访问多个应用系统&#xff0c;从中获取一些可以满足用户需求的管理系统。网站系统有时更像是一个大型“展示平台”&#xff0c;用户可以选择所需的信息进入系统查看…

org.springframework.boot:type=Admin,name=SpringApplication异常

org.springframework.boot:typeAdmin,nameSpringApplication异常 问题&#xff1a;更换最新版本idea之后&#xff0c;启动springboot项目报错 javax.management.InstanceNotFoundException: org.springframework.boot:typeAdmin,nameSpringApplication idea自动默认的启动设…

Netty核心源码与优化

1.Netty的优化 1.1 使用EventLoop的任务调度 直接使用 channel.writeAndFlush(data) 可能会导致线程切换&#xff0c;这是因为如果当前线程并不是该 Channel 所绑定的 EventLoop 线程&#xff0c;那么 writeAndFlush() 操作会将任务重新提交给关联的 EventLoop 线程执行&#…

CTF之web题集详情随手笔记

《Web安全》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484238&idx1&snca66551c31e37b8d726f151265fc9211&chksmc0e47a12f793f3049fefde6e9ebe9ec4e2c7626b8594511bd314783719c216bd9929962a71e6&scene21#wechat_redirect 1 WEB 1 靶场目…

使用Nginx作为反向代理和负载均衡器

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 使用Nginx作为反向代理和负载均衡器 引言 Nginx 简介 安装 Nginx Ubuntu CentOS 配置 Nginx 作为反向代理 配置 Nginx 作为负载…

【PTA】图的邻接矩阵存储和遍历

图的邻接矩阵存储用一个一维数组存储各顶点数据元素&#xff0c;一个二维数组存储顶点之间的邻接关系。 如上面的无向加权图&#xff0c;顶点数据元素为“A-Z”之间的单个字符&#xff0c;为了使遍历输出结果唯一&#xff0c;要求顶点数据元素按由小到大(ASCII码)的顺序存储。…

数据结构之树

1.树的基本概念 1.树的定义 树是由n(n>0)个结点&#xff08;或元素&#xff09;组成的有限集合&#xff08;记为T&#xff09;。 如果n0,它是一棵空树&#xff0c;这是树的特例。 如果n>0&#xff0c;这个结点中有且仅有一个结点作为树的根结点&#xff0c;简称为根。…

国内PLC市场份额报告,西门子老大的地位从未动摇

【导读】国内PLC市场占有率&#xff0c;西门子依然是老大。 PLC市场集中度很高&#xff0c;从销售额来看&#xff0c;TOP3厂家占据一半以上的市场份额&#xff0c;以外资品牌为主&#xff0c;其中西门子排名第一&#xff0c;2022年市场份额约47.1%&#xff1b;三菱排名第二&…

计算机毕业设计 | 基于SpringBoot的健身房管理系统(附源码)

1&#xff0c;项目背景 随着人们生活水平的提高和健康意识的增强&#xff0c;健身行业逐渐兴起并迅速发展。而现代化的健身房管理系统已经成为健身房发展的必备工具之一。传统的健身房管理方式已经无法满足现代化健身房的需求&#xff0c;需要一种更加高效、智能、安全的管理系…

ADI常规SHARC音频处理器性能对比

1、 ADSP-2156x:是基于SHARC+ DSP架构的单核32位/40位/64位浮点处理器,不仅具有灵活的音频连接性和性能可扩展性,还提供多个引脚兼容版本(400MHz至1GHz)和多种片内存储器选项,数据手册链接:https://www.analog.com/media/en/technical-documentation/data-sheets/adsp-2…

PG实践|条件处理表达式函数及其操作

文章目录 引言条件处理表达式1.1 GREATEST() 和 LEAST() - 最大值和最小值1.2 CASE() - 万一/具体情况为1.3 COALESCE - 处理NULL1.4 NULLIF - 处理NULL 总结 &#x1f4eb; 作者简介&#xff1a;「六月暴雪飞梨花」&#xff0c;专注于研究Java&#xff0c;就职于科技型公司后端…

跨境行业的客户运营利器:构建在线培训知识库

在跨境行业中&#xff0c;客户运营是企业成功的关键。随着全球市场的不断扩大和数字化转型的深入&#xff0c;构建一个有效的在线培训知识库对于提升客户服务质量、优化客户体验至关重要。本文将探讨在线培训知识库的构建策略、应用价值&#xff0c;并分析其在跨境行业的实际应…

C语言另一种编码方式开发状态机(无switch)

目录 概述 一、开发环境 二、coding 三、运行结果 四、总结 概述 状态机编码思想&#xff0c;在很多领域都随处可见&#xff0c;传统的coding方式使用switch case来实现&#xff0c;状态跳转可读性差&#xff0c;咋们换一种思路来实现状态机开发&#xff0c;该方式 拓展好…

Android 面试Socket与WebSocket

Android 面试Socket与WebSocket 文章目录 Android 面试Socket与WebSocketSocket什么是SocketSocket通讯的过程TCP协议Socket代码示例UDP协议Socket代码示例Socket实现Android跨进程通信 WebSocket什么是websocket Socket 什么是Socket 网络上的两个程序通过以一个双向通讯的链…

python通过pyarmor库保护源代码

pyarmor 介绍 python是解释型语言&#xff0c;因此&#xff0c;代码不需要编译&#xff0c;而是通过明文提供的。在这种情况下&#xff0c;假如你发布了一个软件&#xff0c;那么&#xff0c;只能将源代码提供给使用者&#xff0c;这样就造成了源代码泄露。 使用pyinstaller…

使用传感器融合进行3D激光雷达点云运动补偿

此示例展示了如何通过融合来自全球定位系统 (GPS) 和惯性测量单元 (IMU) 传感器的数据来补偿由于自我车辆运动而导致的点云失真。此示例的目标是补偿点云数据中的失真并准确地重新创建周围环境。 文章目录 概述坐标系预处理激光雷达数据预处理 GPS 数据结合 GPS、IMU 和激光雷达…

微信小程序 - 获取汉字拼音首字母(汉字英文首字母)根据汉字查拼音,实现汉字拼音首字母获取,在小程序上实现汉字的拼音提取首字母!

前言 例如 “中国” 的首字母就是 “Z”,我们需要通过代码来自动判断从而得出结果。 本文介绍在小程序中,如何从 0-1 完成。 支持 Vue2 / Vue3 语法,您可以传入中文字,会自动返回其首字母,可控制大小写。 示例代码 具体代码如下,复制测试即可。

获取Hive表备注

DESCRIBE EXTENDED 表名;先获取Detailed Table Information这行的data_type字段数据&#xff0c;进行正则匹配&#xff0c;拿到表备注&#xff0c;如下&#xff1a; String str ReUtil.get("parameters:\\{(?!.*?\\().*transient_lastDdlTime.*?comment(.*?)\\}&quo…