SpingBoot的项目实战--模拟电商【5.沙箱支付】
🥳🥳Welcome Huihui's Code World ! !🥳🥳
接下来看看由辉辉所写的关于SpringBoot电商项目的相关操作吧
目录
🥳🥳Welcome Huihui's Code World ! !🥳🥳
一. 沙箱支付是什么
二.SpringBoot项目集成沙箱支付
1.进入支付宝开放平台
2.进入控制台
(1)找到沙箱
(2)设置公钥
(3)生成密钥
①下载密钥生成工具
②使用密钥生成工具生成密钥
3.Java集成沙箱支付
(1)进入文档中心
(2)下载依赖
(3)Alipay Easy SDK API 总览
(4)配置类AplipayConfig
(5)编写controller
(6)支付测试
因为我们写的这个项目是用来练手的,用来熟练技术点的,所以自然也不能接入支付宝的接口【没有营业执照这些证件】。但是支付宝也提供了可以供我们开发使用的接口--沙箱支付
一. 沙箱支付是什么
沙箱支付(Sandbox payment)是指在软件开发过程中用于模拟真实支付环境的测试工具。它提供了一个安全的环境,允许开发人员在不涉及真实货币交易的情况下进行支付系统的测试和调试。
通常,沙箱支付系统会模拟真实支付系统的功能和流程,但使用虚拟货币或测试帐户来完成支付过程。这样,开发人员可以在没有真实金钱交易的情况下验证他们的支付代码是否正常工作,并进行必要的调试和优化。
沙箱支付对于开发支付相关应用程序和网站非常有用,因为它们可以在不影响真实用户和真实支付的情况下进行测试和调试。通过使用沙箱支付,开发人员可以确保应用程序在正式上线之前能够正确处理支付事务,减少潜在的错误和风险。
需要注意的是,沙箱支付只用于开发和测试目的,不是真实的支付系统,不能进行真实的交易操作。
二.SpringBoot项目集成沙箱支付
1.进入支付宝开放平台
支付宝开放平台
https://openhome.alipay.com/
如果说没有支付宝账号的话,需要进行注册
有的话直接登录就好了
2.进入控制台
(1)找到沙箱
往下滑找到沙箱
(2)设置公钥
因为我们再写的是一个模拟的电商项目,那么我们就也模拟一下商户和用户之间的交易--那么我们就需要用到自定义密钥
系统密钥与自定义密钥区别:
系统密钥(System Key):系统密钥是支付宝沙箱环境中的全局密钥,由支付宝提供。系统密钥用于对数据进行加密和签名,以确保数据的安全性和完整性。开发者在使用支付宝沙箱支付时,需要使用正确的系统密钥来进行数据加密和验证。
自定义密钥(Custom Key):自定义密钥是开发者在支付宝沙箱环境中创建和管理的密钥,用于模拟真实商户的身份和权限。开发者可以在支付宝开放平台上创建自定义密钥,并将其用于沙箱环境中的支付请求和验证。自定义密钥用于模拟真实商户的身份认证和数据签名。
(3)生成密钥
①下载密钥生成工具
②使用密钥生成工具生成密钥
将生成的密钥中的公钥填入即可
然后我们就可以查看到支付宝公钥了
点击查看也是一样可以查看到的
3.Java集成沙箱支付
(1)进入文档中心
支付宝文档中心
https://opendocs.alipay.com/common/找到对应的SDK【软件开发工具包(Software Development Kit)】,这里我选择的是easy版,因为这个项目不是上线的项目,没有那么庞大的数据和复杂的场景
Java通用版与Java Easy版的区别:
Java通用版(General Version):Java通用版是基于支付宝开放平台提供的Java SDK开发的,适用于更为复杂的场景和高度自定义需求。使用Java通用版可以更灵活地进行开发,但相应地也需要更多的配置和代码编写。开发者需要根据支付宝提供的API文档,手动构建请求参数、进行签名、发送请求并处理响应等操作。
Java Easy版:Java Easy版是基于支付宝提供的简化SDK开发的,旨在降低开发门槛,简化开发过程。Java Easy版封装了一些常用的功能和操作,提供了更简单、易用的接口,并自动处理一些繁琐的步骤,如参数构建、签名等。使用Java Easy版可以快速上手并进行基本的沙箱支付测试,减少了开发者的工作量。
(2)下载依赖
<dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-easysdk</artifactId><version>2.2.0</version> </dependency>
(3)Alipay Easy SDK API 总览
这里是其中提供的aip接口,大家也可以通过网站链接访问
Alipay Easy SDK API 总览
https://opendocs.alipay.com/common/02n6z6?pathHash=f5e2a056
能力类别
场景类别
接口方法名称
Base(基础能力)
OAuth(用户授权)
getToken(获取授权访问令牌和用户 user_id)
Base(基础能力)
OAuth(用户授权)
refreshToken(刷新授权访问令牌)
Base(基础能力)
Qrcode(小程序二维码)
create(创建小程序二维码)
Base(基础能力)
Image(图片)
upload(上传门店照片)
Base(基础能力)
Video(视频)
upload(上传门店视频)
Member(会员能力)
Identification(支付宝身份认证)
init(身份认证初始化)
Member(会员能力)
Identification(支付宝身份认证)
certify(生成认证链接)
Member(会员能力)
Identification(支付宝身份认证)
query(身份认证记录查询)
Payment(支付能力)
Common(通用)
create(创建交易)
Payment(支付能力)
Common(通用)
query(查询交易)
Payment(支付能力)
Common(通用)
refund(交易退款)
Payment(支付能力)
Common(通用)
close(关闭交易)
Payment(支付能力)
Common(通用)
cancel(撤销交易)
Payment(支付能力)
Common(通用)
queryRefund(交易退款查询)
Payment(支付能力)
Common(通用)
downloadBill(查询对账单下载地址)
Payment(支付能力)
Common(通用)
verifyNotify(异步通知验签)
Payment(支付能力)
Huabei(花呗分期)
create(创建花呗分期交易)
Payment(支付能力)
FaceToFace(当面付)
pay(扫用户出示的付款码,完成付款)
Payment(支付能力)
FaceToFace(当面付)
precreate(生成交易付款码,待用户扫码付款)
Payment(支付能力)
App(手机APP)
pay(生成订单串,再使用客户端 SDK 凭此串唤起支付宝收银台)
Payment(支付能力)
Page(电脑网站)
pay(生成交易表单,渲染后自动跳转支付宝网站引导用户完成支付)
Payment(支付能力)
Wap(手机网站)
pay(生成交易表单,渲染后自动跳转支付宝网站引导用户完成支付)
Security(安全能力)
TextRisk(文本内容安全)
detect(检测内容风险)
Marketing(营销能力)
Pass(支付宝卡包)
createTemplate(卡券模板创建)
Marketing(营销能力)
Pass(支付宝卡包)
updateTemplate(卡券模板更新)
Marketing(营销能力)
Pass(支付宝卡包)
addInstance(卡券实例发放)
Marketing(营销能力)
Pass(支付宝卡包)
updateInstance(卡券实例更新)
Marketing(营销能力)
TemplateMessage(小程序模板消息)
send(发送模板消息)
Marketing(营销能力)
OpenLife(生活号)
createImageTextContent(创建图文消息内容)
Marketing(营销能力)
OpenLife(生活号)
modifyImageTextContent(更新图文消息内容)
Marketing(营销能力)
OpenLife(生活号)
sendText(群发本文消息)
Marketing(营销能力)
OpenLife(生活号)
sendImageText(群发图文消息)
Marketing(营销能力)
OpenLife(生活号)
sendSingleMessage(单发模板消息)
Marketing(营销能力)
OpenLife(生活号)
recallMessage(生活号消息撤回)
Marketing(营销能力)
OpenLife(生活号)
setIndustry(模板消息行业设置)
Marketing(营销能力)
OpenLife(生活号)
getIndustry(生活号查询行业设置)
Util(辅助工具)
AES(加解密)
decrypt(解密,常用于会员手机号解密)
Util(辅助工具)
AES(加解密)
encrypt(加密)
Util(辅助工具)
Generic(通用接口)
execute(自行拼接参数,执行OpenAPI调用)
Util(辅助工具)
Generic(通用接口)
sdkExecute(自行拼接参数,生成加签串,功能等同于通用版 SDK 中的 sdkExecute 方法)
(4)配置类AplipayConfig
其中的appid
支付宝公钥
应用私钥
应用私钥是在我们的密钥生成工具中
package com.wh.easyshop.util;import com.alipay.easysdk.factory.Factory; import com.alipay.easysdk.kernel.Config; import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse; import com.zking.starshop.pojo.Order; import org.springframework.stereotype.Component;@Component public class AlipayConfig {private Config aliconfig() {Config config = new Config();//沙箱支付宝地址config.gatewayHost = "openapi-sandbox.dl.alipaydev.com";//协议httpsconfig.protocol = "https";//应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号config.appId = "appId ";//支付宝公钥config.alipayPublicKey = "支付宝公钥";//签名方式config.signType = "RSA2";//商户私钥(应用私钥),您的PKCS8格式RSA2私钥config.merchantPrivateKey ="应用私钥";return config;}}
需要修改沙箱支付的支付方式,改成网页支付:
public String goAlipay(Order order) {try {// 1. 设置参数(全局只需设置一次)Factory.setOptions(aliconfig());// 2. 发起API调用(subject商品标题、outTradeNo订单编号、totalAmount总金额、returnUrl异步通知地址)AlipayTradePagePayResponse response = Factory.Payment.Page().pay("SpringBoot练手项目收款",order.getOid().toString(),//订单编号order.getTotal().toString(),//总金额//支付成功之后的异步通知(跳出到自己系统的哪个位置)"http://localhost:8080/order/payDone");return response.body;} catch (Exception e) {e.printStackTrace();throw new RuntimeException(e);}}
(5)编写controller
然后再前端接收到这个订单编号,并且把这个id带到指定的路径中
$.post('/order/addOrder',order,resp=>{if(resp.code===200){let f=confirm("确认支付吗");if(f){location.href="/order/pay?oid="+resp.data;}else{location.href="/";}}},'json')
指定的路径:此方法用查询订单,然后把订单的信息带到支付页面中
这个是在配置类中缩写的支付成功之后的异步通知
package com.wh.easyshop.controller;import com.alipay.easysdk.factory.Factory; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.github.yitter.idgen.YitIdHelper; import com.wh.easyshop.exception.BusinessException; import com.wh.easyshop.model.Goods; import com.wh.easyshop.model.Order; import com.wh.easyshop.model.OrderItem; import com.wh.easyshop.model.User; import com.wh.easyshop.resp.JsonResponseBody; import com.wh.easyshop.resp.JsonResponseStatus; import com.wh.easyshop.service.IGoodsService; import com.wh.easyshop.service.IOrderItemService; import com.wh.easyshop.service.IOrderService; import com.wh.easyshop.service.IRedisService; import com.wh.easyshop.util.AlipayConfig; import com.wh.easyshop.vo.CartVo; import com.wh.easyshop.vo.OrderVo; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController;import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors;/*** <p>* 订单信息表 前端控制器* </p>** @author wh* @since 2023-12-27*/ @RestController @RequestMapping("/order") public class OrderController {@AutowiredIRedisService redisService;@AutowiredIGoodsService goodsService;@AutowiredIOrderItemService iOrderItemService;@AutowiredIOrderService iOrderService;@RequestMapping("/addOrder")public JsonResponseBody<?> order (User user, OrderVo orderVo) {//拿到其中的商品idString ids = orderVo.getIds();//拿到购物车中指定的商品【数量和id】List<CartVo> cartVos = redisService.loadCart(user, ids);List<Long> ds = cartVos.stream().map(CartVo::getGid).collect(Collectors.toList());//拿到数据库中的内容【名字,价格】List<Goods> goods = goodsService.listByIds(ds);//遍历集合 赋值给对应的对象for (Goods g : goods) {//找到对应id相同的元素CartVo vo = cartVos.stream().filter(v -> Objects.equals(v.getGid(), g.getGid())).findFirst().get();//将商品g的属性赋值给vo【这样vo中的属性就有数据了】BeanUtils.copyProperties(g,vo);}//订单中的总价BigDecimal total =new BigDecimal(0);//生成订单详情//需要订单id【雪花id生成】long oid = YitIdHelper.nextId();//使用集合将需要加进去的订单详情装起来【使用批处理一次性处理掉】List<OrderItem> orderItemList=new ArrayList<>();for (CartVo cartVo : cartVos) {//订单详情OrderItem orderItem = new OrderItem();//将vo类的属性赋值给orderitem【共有的属性赋值】BeanUtils.copyProperties(cartVo,orderItem);//还有一个数量的值没有赋成功【因为两个实体中的这个属性名字不一样】orderItem.setQuantity(cartVo.getNum());//设置订单详情的idorderItem.setOoid(YitIdHelper.nextId());//设置订单idorderItem.setOid(oid);//将订单详情加入到订单详情的集合中orderItemList.add(orderItem);//计算总价total=total.add(cartVo.xj());}//将生成的额订单详情加入到数据库中iOrderItemService.saveBatch(orderItemList,5);//生成订单Order order = new Order();//将其中的ordervo的属性赋值给orderBeanUtils.copyProperties(orderVo,order);//订单idorder.setOid(oid);//总价order.setTotal(total);//用户idorder.setUserId(user.getId());//订单生成时间order.setCreateDate(new Date());//订单状态【0 未支付】order.setStatus(0);//将生成的订单加入到数据库iOrderService.save(order);//订单生成成功之后需要将购物车中的信息删除String ids1 = orderVo.getIds();List<String> delids = Arrays.asList(ids1.split(","));redisService.delCart(delids,user);return JsonResponseBody.success(oid);}@RequestMapping("/pay")public String order (User user, String oid) {//根据传递过来的订单编号拿到订单对象Order order = iOrderService.getById(oid);AlipayConfig alipayConfig = new AlipayConfig();String body= alipayConfig.goAlipay(order);//表单内容return body;}/*** 支付成功之后的回调路径* @param ms* @return* @throws Exception*/@RequestMapping("/payDone")@ResponseBody//@RequestParam没有这个注解就无法正确的接受参数public String payDone(@RequestParam Map<String, String> ms) throws Exception {//验签【不然的话就可以在地址栏上手动传递参数】Boolean f = Factory.Payment.Common().verifyNotify(ms);//如果验证不通过,那就抛出一个异常if(!f){throw new BusinessException(JsonResponseStatus.UN_KNOWN);}String oid = ms.get("out_trade_no");//拿到请求中的订单编号iOrderService.update(new UpdateWrapper<Order>()//根据订单编号,修改订单状态【未支付=>已支付】.eq("oid", oid).set("status", 1).set("pay_date", new Date())//设置支付的时间);return "<script>\n" +" alert('支付成功')\n" +" location.href = '/'\n" +"</script>";}}
(6)支付测试
如果支付成功就会跳到主页面中
好啦,今天的分享就到这了,希望能够帮到你呢!😊😊
相关文章:

SpingBoot的项目实战--模拟电商【5.沙箱支付】
🥳🥳Welcome Huihuis Code World ! !🥳🥳 接下来看看由辉辉所写的关于SpringBoot电商项目的相关操作吧 目录 🥳🥳Welcome Huihuis Code World ! !🥳🥳 一. 沙箱支付是什么 二.Sp…...
How to collect data
How to collect data 爬虫JavaPythonurllibrequestsBeautifulSoup 反爬虫信息校验型反爬虫动态渲染反爬虫文本混淆反爬虫特征识别反爬虫App反爬虫验证码 自动化测试工具SeleniumAppiumQMetry Automation StudioTestComplete RPA商业化产品艺赛旗影刀UIPath 开源产品Robot Frame…...

二刷Laravel 教程(用户注册)总结Ⅳ
一、显示用户信息 1)resource Route::resource(users, UsersController); 相当于下面这7个路由 我们先用 Artisan 命令查看目前应用的路由: php artisan route:list 2) compact 方法 //我们将用户对象 $user 通过 compact 方法转化为一个关联…...

跨国制造业组网方案解析,如何实现总部-分支稳定互联?
既要控制成本,又要稳定高效,可能吗? 在制造企业积极向“智造”发展、数字化转型的当下,物联网、人工智能、机器人等新型设备加入到生产、管理环节,为企业内部数据传输提出了更高的要求。而当企业规模扩大,数…...

网络的设置
一、网络设置 1.1查看linux基础的网络设置 网关 route -n ip地址ifconfigDNS服务器cat /etc/resolv.conf主机名hostname路由 route -n 网络连接状态ss 或者 netstat域名解析nslookup host 例题:除了ping,什么命令可以测试DNS服务器来解…...

CentOS常用命令
CentOS常用命令 1 背景知识1.1 Centos 简介1.2 centos 和ubuntu的区别1.3 安装centos的时候需要注意什么 2 常用命令集锦2.1 文件目录类:2.2 驱动挂载类:2.3 关机命令:2.4 查看系统信息命令:2.5 文本命令2.6 系统管理命令…...

Linux运维之切换到 root 用户
春花秋月何时了,往事知多少。此付费专栏不要订阅,不要订阅,听人劝。 🌹作者主页:青花锁 🌹简介:Java领域优质创作者🏆、Java微服务架构公号作者😄 🌹简历模板、学习资料、面试题库、技术互助 🌹文末获取联系方式 📝 系列专栏目录 [Java项目实战] 介绍Java…...
【2024系统架构设计】 系统架构设计师第二版-层次式架构设计理论与实践
目录 一 表现层框架设计 二 中间层架构设计 三 数据访问层设计 四 数据架构规划与设计 五 物联网层次架构设计 六 层次式架构案例分析...

SpringSecurity的注解@PreAuthorize的失效问题
问题:测试响应式框架时,测试框架对于权限与角色的拦截问题,对于/delete的访问报错访问拒绝,但是数据里面配置了权限。 配置详情 原因:调用roles方法时源码会重新new一个list将authorities的数据覆盖,导致…...

k8s的集群调度
1、scheduler:负责调度资源,把pod调度到指定的node节点 (1)预算策略 (2)优先策略 2、List-watch (1)在k8s集群中,通过List-watch的机制进行每个组件的协作࿰…...
简单易懂的理解 PyTorch 中 Transformer 组件
目录 torch.nn子模块transformer详解 nn.Transformer Transformer 类描述 Transformer 类的功能和作用 Transformer 类的参数 forward 方法 参数 输出 示例代码 注意事项 nn.TransformerEncoder TransformerEncoder 类描述 TransformerEncoder 类的功能和作用 Tr…...

搭建Eureka服务注册中心
一、前言 我们在别的章节中已经详细讲解过eureka注册中心的作用,本节会简单讲解eureka作用,侧重注册中心的搭建。 Eureka作为服务注册中心可以进行服务注册和服务发现,注册在上面的服务可以到Eureka上进行服务实例的拉取,主要作用…...
【React】react-router-dom中的HashRouter和BrowserRouter实现原理
1. 前言 在之前整理BOM的五个对象时,提到: location.hash发生改变后,会触发hashchange事件,且history栈中会增加一条记录,但页面不会重新加载——实现HashRouter的关键history.pushState(state, , URL)执行后…...

生物信息学中的可重复性研究
科学就其本质而言,是累积渐进的。无论你是使用基于网络的还是基于命令行的工具,在进行研究时都应保证该研究可被其他研究人员重复。这有利于你的工作的累积与进展。在生物信息学领域,这意味着如下内容。 工作流应该有据可查。这可能包括在电脑…...
css-img图像同比缩小
1. HTML 中使图像按比例缩小 CSS 来控制图像的大小,并保持其宽高比 <!DOCTYPE html> <html> <head><style>.image-container {width: 300px; /* 设置容器宽度 */height: auto; /* 让高度自适应 */}.image-container img {width: 100%; /* …...

SpringBoot+Prometheus+Grafana搭建应用监控系统
1.应用监控系统介绍 SpringBoot的应用监控方案比较多,SpringBootPrometheusGrafana是比较常用的一种解决方案,主要的监控数据的处理逻辑如下: SpringBoot 的 actuator 提供了应用监控端点,可以对外暴露监控数据信息。Prometheu…...

QT c++和qml交互实例
文章目录 一、demo效果图二、c和qml交互的基本方式1、qml 调用 C 类对象2、C 类对象调用 qml3、qml 给 C 发送信号4、C 给 qml 发送信号 三、关键代码1、工程结构图2、c代码MainWindow.cppMainQuickView.cppStudentInfoView.cppStudentInfoModel.cpp 3、qml代码main.qmlMainQui…...

mysql基础-数据操作之增删改
目录 1.新增数据 1.1单条数据新增 1.2多条数据新增 1.3查询数据新增 2.更新 2.1单值更新 2.2多值更新 2.3批量更新 2.3.1 批量-单条件更新 2.3.2批量-多条件更新 2.4 插入或更新 2.5 联表更新 3.删除 本次分享一下数据库的DML操作语言。 操作表的数据结构…...
写字母(文件)
请编写函数,将大写字母写入文件中。 函数原型 void WriteLetter(FILE *f, int n);说明:参数 f 为文件指针,n 为字母数目(1 ≤ n ≤ 26)。函数将前 n 个大写英文字母写入 f 所指示的文件中。 裁判程序 #include <stdio.h> #include &…...

基于Jackson自定义json数据的对象转换器
1、问题说明 后端数据表定义的id主键是Long类型,一共有20多位。 前端在接收到后端返回的json数据时,Long类型会默认当做数值类型进行处理。但前端处理20多位的数值会造成精度丢失,于是导致前端查询数据出现问题。 测试前端Long类型的代码 …...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...

实战三:开发网页端界面完成黑白视频转为彩色视频
一、需求描述 设计一个简单的视频上色应用,用户可以通过网页界面上传黑白视频,系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观,不需要了解技术细节。 效果图 二、实现思路 总体思路: 用户通过Gradio界面上…...