乱码三千 – 分享实用IT技术

乱码三千 – 码出一个新世界


  • 首页

  • 归档

  • 搜索

盘点目前主流的跨平台开发引擎

发表于 2023-04-11

前言

我曾想, 有没有一款引擎可以实现PC端, 移动端, Web端和小程序的应用开发

那么对于大型应用而言, 我最先想到的就是使用游戏开发引擎, 即实现了跨平台又保证了程序性能, 生产效率大幅提高

比如目前有一些跨平台的桌面程序就是用Godot游戏引擎开发的

但是面对日常的展示类应用, 使用游戏引擎就有种牛刀杀鸡的感觉, 由于游戏引擎设计的初衷不同, 导致了使用游戏引擎开发日常应用会存在一些难点, 比如:

  • UI组件的不完善 需要自己造轮子
  • 第三方SDK的支持度不够, 同样需要自己造轮子
  • 游戏引擎默认的UI自刷新机制和日常应用的响应式刷新不同, 开发者需要具备对引擎修改调优的能力

除非有现成的框架能直接上手使用, 否则 前期开发的时间成本会比较大, 不过后期轮子造出来了这一部分的问题会得到有效解决

接下来咱们列举一下目前市面上主流的跨平台开发引擎:

跨平台开发框架

日常应用引擎:

引擎名称 Web端 移动端 PC端 小程序
flutter √ √ √
uni-app √ √ √ √
  • uni-app官方默认支持Web, 移动, 小程序三端, 和Electron结合后可实现桌面程序的开发, 具体文章参考: 《Uniapp+Vite+Vue3+Electron 快速构建桌面应用》

  • flutter很强 性能媲美原生, 唯一不足是不支持小程序, 目前有团队在研究小程序+flutter容器的方案, 也就是将开发小程序嵌入到flutter应用中,从而实现跨全平台, 对于企业而言只需开发和维护一套小程序即可, 具体参见:《FinClip 实现小程序反向生成 App》

    这种方案能方便现有的前端开发者快速上手, 不过感觉和uni-app有点类似, 可能内部交互原理不太一样, 这一块有兴趣的可自行研究

  • MPFlutter :是基于Flutter延伸出来的一个支持小程序的框架, 从而实现全平台开发, 不过仅适合展示类应用的开发, 而且得掌握Dart语言, 对于纯前端开发者来说有一定的学习成本, MPFlutter未来发展如何 咱们拭目以待

    image-20230414140355841

游戏引擎:

引擎名称 Web端 移动端 PC端 小程序
cocos √ √ √ √
godot √ √ √
unity √ √ √ √

关于游戏引擎开发日常应用的方案, 由于本人并未实操过, 暂不做评价, 等后续体验过了再来补充

关于其他游戏引擎可参考文章《常用游戏开发引擎汇总》

总结

展示类应用推荐uniapp和MPFlutter, 高性能应用的开发推荐原生flutter

游戏和大型桌面程序的开发使用游戏引擎进行开发

本文为作者原创转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

个人开发者收款方案之--面包多

发表于 2023-04-10

前言

收款,是大多数个人开发者的梦想。如果你正在搜寻这方面的内容,恭喜你,至少说明你的项目有赢收的可能。作为一个WEB前端开发者,我对接过目前一些比较常见的收款方案,并应用于自己的项目中,现在把自己对接的过程记录下来,希望对你有所帮助。

本文仅讨论WEB端(包括H5、浏览器扩展)售卖虚拟商品(激活码),且支持全程自动化的收款方案。

介绍

“面包多”属于创业团队作品,作者@greatdk偶尔活跃于V2等论坛,个人博客偶有更新,是个喜欢思考的人。

官网:点击进入

优缺点

优点:申请免费、对接简单、实时提现
缺点:入驻需实名认证、支付流程在平台进行,且用户需登录

价格费用

普通模式:5%服务费+1%的第三方支付手续费。
闪电结算:5.7%的服务费。

ps:官方预告2022-10-01之后服务费将提高到13%
官方价格说明:https://mbd.pub/help/#/withdraw

对接过程

流程:(开发者)创建商品–>(用户)登录后支付–>(平台)发送回调通知–>(开发者)获取通知、查询订单、完成入库、发货。
官方帮助文档:https://mbd.pub/help

第一步:入驻申请

填写基础资料、实名认证后,拿到Developer Key。

第二步:创建作品

(略)

第二步:接收回调请求(非必须)

在面包多后台设置回调地址,用户支付后平台会主动向开发者推送回调请求,内容如下:

1
2
3
4
5
6
7
8
{
"order_id": "3faa1cfd5a364d29a5d2aec8606a2fxa", //面包多订单号
"out_order_id": "211234132", //独立订单号
"product_name": "新品小报第123期", //作品名称
"product_url_key": "usdas", //作品urlkey
"amount": 0,1, //支付金额
"state": 1, //支付状态,成功支付则为1
}

注意:如果担心回调通知有延迟或失败,可引导用户手动复制订单号进行查询以入库。

第三步:主动查询订单信息

在收到面包多的支付通知回调后,开发者可以主动去查询一次订单支付信息,双重验证后入库。

订单查询接口地址:https://x.mianbaoduo.com/api/order-detail
请求方式:GET
Header公参:x-token (string, 必须,即第一步拿到的Developer Key)
入参:order_id (string, 必须)
出参:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
"code": 200,
"result": {
"ordertime": 1590508123,
"orderamount": 3,
"payway": "alipay",
"orderid": "d878ee7909c902b19d193fb8fd0af695",
"creatorid": "a2w=",
"state": "success",
"expire_at": 1593186560,
"rounds": 1,
"urlkey": "Y5ublZk=",
"re": {
"ordertime": 1594108875,
"orderamount": 3,
"payway": "alipay",
"orderid": "4a03d948c448fb8b5f51a31ab33011e0",
"creatorid": "a2w=",
"state": "success",
"expire_at": 1596787295,
"rounds": 1,
"urlkey": "Y5ublZk="
}
},
"error_info": ""
}

第四步:入库、发货

入数据库、发激活码(略)

总结

面包多最大的问题在于支付全程在平台进行,且用户必须登录,体验不是很好。类似的还有“爱发电”、“Buy Me A Coffee”等。

流程调通之后,我因为上面的原因,选择了其它方案。但如果仅作为打赏捐赠平台,还是可以考虑。目前面包多的功能还在更新迭代,可以持续关注。

其它方案

《个人开发者全球收款方案实践之–Paddle支付》

本文转载自: 前端邓浩

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

个人开发者全球收款方案之--Paddle支付

发表于 2023-04-10

前言

本文仅讨论WEB端(包括H5、浏览器扩展)售卖虚拟商品(激活码),且支持全程自动化的收款方案。

介绍

“Paddle”成立于2012年,是英国一家专门提供支付及订阅管理服务的公司。支持全球收款,支持个人开发者,且支持上传自定义的license,适合激活码软件开发者。

官网:https://www.paddle.com
沙盒测试环境:https://sandbox-vendors.paddle.com/

优缺点

优点:全球收款(支持PayPal、Apple Pay、Google Pay、iDEAL)、支持个人、独立沙盒测试环境、软件内部完成支付

缺点:非实时到账、提现有门槛(全球收款通病)

价格费用

每笔交易:5% + 50¢

(注意:PayPal或Payoneer提现费用另算)

官方提现说明:https://www.paddle.com/help/manage/get-paid/when-and-how-do-i-get-paid

对接过程

流程:(开发者)创建商品、上传激活码[非必须]–>(用户)支付–>(平台)发送激活码到用户邮箱–>(用户)使用激活码。

官方帮助文档:https://www.paddle.com/help

第一步:创建商品

在Paddle后台新建商品,操作路径:Catalog–Products

个人开发者全球收款方案实践之--Paddle支付

第二步:上传Licenses(激活码)

文件为.txt格式,命名随意,每行就是一个激活码。激活码在后台可随时上传补充,自带排重功能。

个人开发者全球收款方案实践之--Paddle支付

此外,还支持Coupons(折扣券),最多可打折到免费,方便测试。

第三步:用户支付

个人开发者全球收款方案实践之--Paddle支付

第四步:Paddle发送激活码到用户邮箱

每完成一笔支付,用户就会收到一个带激活码的邮件。

个人开发者全球收款方案实践之--Paddle支付

ps. Paddle后台支持几个主要的事件提醒,比如订阅、下单、支付等等事件。

第四步:用户使用激活码

(略)

核心代码

1
2
3
4
5
6
7
8
//第一步:引入paddle.js
<script src="https://cdn.paddle.com/paddle/paddle.js"></script>

//第二步:初始化(vendor 在Developer Tools--Authentication里)
Paddle.Setup({ vendor: 3498x });

//第三步:开始支付(product_id在商品列表页里)
Paddle.Checkout.open({ product: 77447x });

如果是测试环境,可以加个判断:

1
2
3
if (location.hostname === 'localhost') {
Paddle.Environment.set('sandbox');
}

踩坑

在测试环境的联调过程相当顺利,一切都是理想的样子,可到了生产环境却始终报错“Page Not Found. Sorry, the page you were looking for could not be found.”。查找资料后发现需要域名认证,(后台设置Checkout–Request Domain Approval)。

提交域名苦等两周后,收到驳回邮件:

个人开发者全球收款方案实践之--Paddle支付

因为在等待审核期间,自己对接的另外一些支付方式都已经上线,已经有替代品,遂不再折腾Paddle。

总结

Paddle算是个不错的全球收款方案,功能丰富,无需大爬梯,暂未看到有无故封号的案例。如果你愿意花时间去审核域名,可以考虑。

其它方案

《个人开发者收款方案实践之–面包多》

本文转载自: 前端邓浩

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

个人开发者收款方案汇总

发表于 2023-04-10

前言

网站或者APP收款问题始终是大部分个人开发者的一个痛点, 目前支付宝和微信收款业务只面向企业和个体户开放, 个人无法申请

在产品盈利状况不明的情况下, 如果特地为此去注册一家公司, 那么前期的维护成本太高了,并不推荐

此时 我们可以考虑先接入第三方的收款平台, 等产品步入稳定盈利阶段后, 再考虑注册公司或者个体户

目前市面上有许多供个人申请的收款平台, 这里做了个汇总, 供大家查阅

国内首款方案

  1. 虎皮椒

    官网: 点击进入

    image-20230412115844779

  2. PayJs

    官网: 点击进入

    image-20230412111136593

  3. XorPay

    官网: 点击进入

    image-20230412105948282

  4. 微豆付

    官网: 点击进入

    image-20230412110538451

  5. 叮咚支付

    官网: 点击进入

    image-20230412110437720

  6. 云免签

    官网: 点击进入

    image-20230412110957697

  7. V免签

    开源项目, 采用app监控+服务端回调的方式

    Github: 点击进入

    演示地址:点击进入
    测试支付地址:点击进入

    V免签软件工具网盘:点击进入

    备用网盘:vmianqian.uupan.net 登录密码:66666

    image-20230412112520373

  8. 面包多

    官网: 点击进入

    image-20230412122804341

  9. 爱发电

    官网: 点击进入

    image-20230412140048731

  10. YunGouOS

    官网: 点击进入

    image-20230412120842858

  11. h5zhifu

    官网: 点击进入

    image-20230412122647173

全球首款方案

  1. Paddle支付

    官网:点击进入
    沙盒测试环境:点击进入

本文为作者原创转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

SpringBoot报错lateinit property mapper has not been initialized

发表于 2023-04-09

问题

SpringBoot工程突然莫名其妙报错:lateinit property mapper has not been initialized

最后发现是事务注解@Transactional导致的

由于kotlin方法访问权限默认为final, 而事务注解使用的是反射, 两者冲突

解决方案

  1. 第一种 去除事务注解(不推荐)

  2. 第二种 给报错的方法添加open权限, 如下:

    1
    2
    3
    4
    5
    6
    7
    8
    open fun userLogin(
    userAccount: String,
    userPassword: String,
    request: HttpServletRequest?,
    response: HttpServletResponse?
    ): String {
    return ""
    }

本文为作者原创转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

SpringBoot中的Fliter和Interceptor

发表于 2023-04-08

两者区别

两者区别:

  • Filter属于servlet组件, interceptor属于Spring内置组件
  • 多个Filter存在时按照文件的排列顺序依次执行
  • Filter会拦截所有的资源而interceptor只拦截Spring环境中的资源
  • Filter的执行流程在interceptor之前, 也就是先执行过滤器再执行拦截器

执行流程图如下:

image-20230410143454632

Filter实现

  1. 第一步 定义过滤器, 实现servlet包下的Filter接口, 并重写其所有方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    @WebFilter(urlPatterns = ["/*"])
    class LoginFilter:Filter {
    /**
    * 请求拦截
    */
    override fun doFilter(
    request: ServletRequest?,
    response: ServletResponse?,
    chain: FilterChain?
    ) {


    //放行
    chain?.doFilter(request,response)
    }

    /**
    * 服务启动时调用 只调用一次
    */
    override fun init(filterConfig: FilterConfig?) {
    super.init(filterConfig)

    }

    /**
    * 服务关闭时调用
    */
    override fun destroy() {
    super.destroy()
    }
    }
  1. 第二步 项目启动入口类上添加@ServletComponentScan开启servlet组件支持

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    @ServletComponentScan /
    @SpringBootApplication
    open class MainApplication {
    companion object {
    @JvmStatic
    fun main(args: Array<String>) {

    SpringApplication.run(MainApplication::class.java, *args)
    }
    }


    }

Interceptor实现

Cookie

  1. 第一步 定义拦截器, 实现HandlerInterceptor接口 并重写其所有方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    @Component
    class LoginCheckInterceptor :HandlerInterceptor {

    /**
    * 在目标方法执行前执行 返回true放行 否则不放行
    */
    override fun preHandle(
    request: HttpServletRequest,
    response: HttpServletResponse,
    handler: Any
    ): Boolean {
    return true
    }
    /**
    * 在目标方法执行后执行
    */
    override fun postHandle(
    request: HttpServletRequest,
    response: HttpServletResponse,
    handler: Any,
    modelAndView: ModelAndView?
    ) {
    }
    /**
    * 最后执行
    */
    override fun afterCompletion(
    request: HttpServletRequest,
    response: HttpServletResponse,
    handler: Any,
    ex: Exception?
    ) {
    }
    }
  1. 第二步 创建配置类 并将刚定义的拦截器添加进配置类中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Configuration
    open class WebConfig : WebMvcConfigurer {

    @Autowired
    lateinit var loginCheckInterceptor: LoginCheckInterceptor

    override fun addInterceptors(registry: InterceptorRegistry) {
    registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**") //拦截所有路径
    }
    }

本文为作者原创转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

关于几种Web会话跟踪技术的对比分析

发表于 2023-04-08

前言

正常情况下, 当浏览器打开访问某个网站时一个新会话便创建了, 当浏览器关闭, 那该会话便结束

会话跟踪技术: 检查多个或多次接口请求是否属于同一个会话的技术, 简而言之就是判断这些请求是否来自同一个用户的技术

常见的会话跟踪技术有:

  • Cookie
  • Session
  • JWT

Cookie

优势:

  • HTTP协议中支持的技术
  • 全程自动跟踪

劣势:

  • 移动端APP无法使用Cookie
  • 不支持跨域
  • 不安全 用户可以手动禁用Cookie
  • 前端收到的Cookie数据为明文 信息不安全

Session

优势:

  • HTTP协议中支持的技术
  • 信息相对安全 前端收到的Cookie数据为密文, 真实数据存在后端
  • 全程自动跟踪

劣势:

  • 移动端APP无法使用Session
  • 不支持跨域
  • 由于Session是基于Cookie实现的, 所以用户同样可以手动禁用Cookie使得Session无法使用
  • 由于数据存在后端 加大了后端了存储压力
  • 服务器集群环境下无法共享Session

JWT

全称json web token,

优势:

  • 支持PC端和移动端
  • 解决集群环境下的认证问题
  • 减轻了服务端的存储压力
  • 不存在跨域问题
  • 数据为密文 防篡改 安全性高

劣势:

  • 需要手动存储token到本地

总结

Cookie和Session属于传统的会话跟踪技术, 如果只做Web端, 可以采用

如果是面对多平台的开发, 推荐目前主流的jwt技术

本文为作者原创转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

SpringBoot工程根据实体类自动创建数据库表

发表于 2023-04-07

实现步骤

  1. 集成jpa依赖包

    1
    implementation "org.springframework.boot:spring-boot-starter-data-jpa"
  2. 给实体类添加注解

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    @Entity
    @Table(name = "user")
    data class User(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long? = null,
    @Column(name = "nickName",nullable = false)
    val nickName: String? = null,
    @Transient //表中不生成对应字段
    val qqAccount: String? = null,
    val avatar: String? = null,
    val realName: String? = null,
    val password: String? = null,
    )
  3. 在application.yml配置文件中对jpa进行相关配置

    1
    2
    3
    4
    5
    spring:
    jpa:
    hibernate:
    ddl-auto: update # 当实体类发生改变时更新表
    show-sql: true

    ddl-auto枚举参数介绍:

    • create:每次运行程序时,都会重新创建表,故而数据会丢失
    • create-drop:每次运行程序时会先创建表结构,然后程序结束时清空表
    • update:每次运行程序,没有表时会创建表,如果对象发生改变会更新表结构,原有数据不会清空,只会更新(推荐使用)
    • validate:运行程序会校验数据于数据库的字段类型是否相同,字段不同会报错
    • none:禁用DDL处理, 此为默认模式
  4. 启动工程

    配置完后, 每次启动工程则会检查相关实体类, 如有新增实体类则自动创建表

    需要注意的是: 只能自动创建表和新增字段 删除字段和修改字段类型需要手动处理

本文为作者原创转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

SpringBoot实现自动生成接口文档

发表于 2023-04-06

前言

需要使用knife4j这个框架来实现我们的需求, 这里我使用的是Gradle构建环境, 具体步骤如下

实现步骤

  1. 添加依赖

    1
    implementation "com.github.xiaoymin:knife4j-spring-boot-starter:2.0.9"
  2. 定义配置类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    @Configuration
    @EnableSwagger2WebMvc
    open class SwaggerConfiguration : WebMvcConfigurer{
    override fun addResourceHandlers(registry: ResourceHandlerRegistry?) {}

    // 创建Docket存入容器,Docket代表一个接口文档
    @Bean
    open fun webApiConfig(): Docket? {
    return Docket(DocumentationType.SWAGGER_2) // 创建接口文档的具体信息
    .apiInfo(webApiInfo()) // 创建选择器,控制哪些接口被加入文档
    .select() // 指定@ApiOperation标注的接口被加入文档
    .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation::class.java))
    .build()
    }

    // 创建接口文档的具体信息,会显示在接口文档页面中
    private fun webApiInfo(): ApiInfo? {
    return ApiInfoBuilder() //
    .title("文档标题") //
    .description("文档描述")
    .version("1.0")// 版本
    .contact(Contact("联系人信息", "http://baidu.com", "baidu@qq.com")) // 版权
    .license("版权地址")
    .licenseUrl("http://www.baidu.com")
    .build()
    }
    }
  3. 给Controller添加文档注解

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    @Api(tags = ["文件管理"])
    @ApiSupport(author = "开发者名称", order = 1)
    @CrossOrigin
    @RestController
    @RequestMapping("/file")
    class FileController {


    @Autowired
    lateinit var service: FileService
    @ApiOperation(value = "文件上传", notes = "这是注释")
    @PostMapping(value = ["/upload"])
    fun uploadFile(
    @RequestParam(value = "file", required = true) file: MultipartFile,
    ): BaseEntity<String> {
    return try {
    val url = service.uploadFile(file)
    BaseEntity(data = url)
    } catch (e: Exception) {
    BaseEntity(code = 505, msg = e.message.orEmpty(), data = "")
    }

    }

    }
  4. 在application.yml配置文件中对knife4j进行相关配置

    1
    2
    3
    4
    5
    6
    7
    knife4j:
    enable: true #开启文档自动生成功能
    production: false # 生产版本时 无权限访问
    basic: # 设置访问密码
    enable: false
    username: abc
    password: 123
  5. 运行工程, 查看文档

    浏览器输入http://ip:端口/doc.html查看自动生成的文档, 如下:

    image-20230410114636451

文档参考

官方文档: 点击进入

本文为作者原创转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

SSH链接失败提示REMOTE HOST IDENTIFICATION HAS CHANGED

发表于 2023-04-05

前言

昨天在使用Git推送代码的时候, 莫名其妙突然报错,提示:

1
2
3
4
5
6
7
8
9
10
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is SHA256:uNiVztksCsDhcc0u9e8BujQXVUpKZIDTMc
Please contact your system administrator.
Add correct host key in /root/.ssh/known_hosts to get rid of this message.
Offending key in /root/.ssh/known_hosts:3

解决方案

  1. 第一种 直接删除.ssh目录下的known_hosts文件

  2. 第二种 修改.ssh目录下的config配置文件, 添加如下配置:

    1
    2
    StrictHostKeyChecking no  # 不进行主机检查
    UserKnownHostsFile /dev/null #不保存在known_hosts中
  3. 第三种 只删除known_hosts文件中对应ip的相关rsa信息

本文为作者原创转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

1…8910…50

乱码三千

android程序员一枚,擅长java,kotlin,python,金融投资,欢迎交流~

491 日志
143 标签
RSS
© 2025 乱码三千
本站总访问量次
由 Hexo 强力驱动
|
主题 — NexT.Muse v5.1.4
0%