2025-11-26 17:27:25
昨晚吃完饭,刚准备放松一下,有一位老板加我微信,说想开发一个 H5 网页版本的手机租赁用的租金计算器。需要能输入手机结算价格,选择首付比例(三成,四成,或者五成),和分期期数(6期,9期),能自动计算出每月的还款金额。之前开发了很多微信小程序版本的手机租金计算器,而 H5 网页版本的还是第一次。感觉也不是很麻烦,逻辑都是一样的,只不过前端的界面不太一样而已。
在 Gemini 3 Pro 的加持下,一个小时就搞定了前端页面及逻辑。而且用 Vue 重写了一版,代码逻辑更清晰,主要是为了方便后续维护修改。界面效果如下:

又花了一个小时,实现了一个管理后台,用于自定义配置参数。这样老板要调整计算参数,就不需要找我修改了,可以自行在管理后台设置即可。输入独立的账号密码即可。
对我而言,微信小程序唯一方便的就是不需要每次去服务器上部署。H5 网页版本则需要一个在国内已备案的域名和国内的服务器。其实选择腾讯云或者阿里云 99 一年的 2核2G的服务器就足够了。好在老板比较懂行,早就有了阿里云账号,也有备案的域名,省去了大量的备案时间。直接新购服务器直接部署就可以了。因为后台是 go 开发的,配好 Nginx,设置一下 HTTPS 证书,就大功告成了。略显繁琐了一点,好在不用向老板解释微信小程序的备案和认证流程,也省去了每年 300 的小程序认证费用。再就是省去了备案后修改小程序名称的麻烦:
“你的小程序备案名称信息与小程序名称信息不一致”。总不能修改一次小程序名字,就得重新备案一次吧。咱的时间也不是这样浪费的 这时候 H5 版本的优势就太明显了。
感兴趣的老板,可以加我微信:zhongwei
2025-11-25 11:24:44
我有两个 MySQL 数据表:
我定义的薪资 Struct 结构体,包含了 embedded 字段 Staff,用于关联员工信息:
type Salary struct {
gorm.Model
StaffId uint
Staff Staff `gorm:"foreignKey:StaffId"`
Amount float64
}
我需要在返回薪资信息列表时,同时返回员工的详细信息(通过 Preload 预加载实现),并且根据员工的某些字段进行过滤(通过 Left Join 实现)。
下面是一个示例代码,展示了如何使用 Gorm 的 Preload 和 Left Join 来实现这个需求:
func GetSalaryList(c *gin.Context) {
var items []Salary
db := models.DB.Model(&Salary{}).
Select("salary.*").
Joins("LEFT JOIN staff ON salary.staff_id = staff.id") // 使用 Left Join 关联员工表
// 根据员工姓名进行过滤
if name, isExist := c.GetQuery("name"); isExist {
db = db.Where("staff.name LIKE ?", fmt.Sprintf("%%%s%%", name))
}
// After a Chain method, Finisher Method, GORM returns an initialized
// *gorm.DB instance, which is NOT safe to reuse anymore, or new generated
// SQL might be polluted by the previous conditions.
// In order to reuse a initialized *gorm.DB instance, you can use a
// New Session Method to create a shareable *gorm.DB
db = db.Session(&gorm.Session{})
var count int64 = 0
db.Distinct("salary.id").Count(&count)
db.Preload("Staff"). // 预加载 Staff 关联
Order("salary.id desc").
Limit(limit).
Offset((page - 1) * limit).
Find(&items)
}
需要注意的两个地方:
我发现 VSCode 里的 Github Copilot 的 GPT-5 mini 模型,在有项目代码上下文的情况下,比 DeepSeek 强太多了。 不用去解释过多的前提。所以网页版的 AI 工具,效率还是差一些。
2025-11-21 13:20:22
昨天早上四点半,服务器又被刷爆了,CPU 持续百分百。从 Nginx 日志看,毫无规律。早上被一堆报警短信吵醒,眼都睁不开图片就开始设置防火墙规则。我投降了,不得已上了阿里云 ESA(边缘安全加速 Edge Security Acceleration)。因为网站在国内,用 Cloudflare 影响国内用户体验,选择阿里云 ESA 也是无奈的选择。可以看到不到 30 万的请求,只有 1 万多的有效请求,这里面还有部分是我测试时放开了规则进来了部分垃圾流量。

靠临时的 ESA WAF (即 Web 应用防火墙)规则扛住了。虽然不太严谨,但是目前还能让我喘口气 。我只能通过 WAF 里新建自定义规则,判定是广东 IP 且请求路径是 / ,且没有 referer 就直接拦截。因为用阿里云的一个好处是,至少他们的 IP 库是相对准确的。而我自己从 Nginx 日志里拿到的 IP 去网上查,其实查出来的 IP 归属地不一定准确。我也通过阿里云 ESA 看出了一些攻击流量特征:
这些刷流量的请求能绕过 ESA 的 JS 挑战。JS挑战:表示WAF向客户端返回一段正常浏览器可以自动执行的JavaScript代码。如果客户端正常执行了JavaScript代码,则WAF在一段时间(默认30分钟)内放行该客户端的所有请求(不需要重复验证),否则拦截请求。不能理解的是阿里云 ESA 的自定义规则只能设置 JS 挑战,拦截和观察。而不能设置滑块验证。因为 JS 挑战明显拦不住,为何不能提供一个滑块验证的功能呢?在 ESA 官方微信群里问了一下,客服让我提个工单,等工程师来回答图片。
我还有一个疑问:不知道是否有更好的自动识别的方式,因为理论上广东这些 IP 在阿里云的海量请求下应该能分析出特征。还是说我只能购买更高级的 ESA 套餐才能自动识别出来。
哎,昨天一冲动买了一年的基础版套餐,不过倒是很便宜 50 多,就是每个月只有 50G 的流量,这个流量明显是不够用的(平均下来一天不到2G)。但是升级套餐,就非常不划算。
我感觉这个海量广东 IP 恶意刷流量的问题,要是不能有效的防住。大部分小网站都得关站。目前用 ESA 的自定义规则也不靠谱,对方换个随机链接加伪造 referer 就能轻松绕过。然后我还得给 ESA 的流量付费,估计得被刷破产。参考前文:网站七牛 CDN 流量被刷,差点破产。不忙的时候还是提个工单问问专家吧。网上搜索 ESA 的技术文章,大部分都是软文,没几个认真讨论处理方案的。
2025-11-13 21:21:14
今天早上上班真是走了大运,先是电脑ssd硬盘io异常,卡得无法动弹。然后想用手机查查原因,发现sim卡无法识别了🥴 之前也遇到过,往常重启一下手机系统就恢复了,我以为是红米k80的品控问题,也没有在意。今天重启了几次都无法识别,😵💫,我突然慌了。
因为我突然意识到,没有sim卡,即便有WiFi,你也收不到别人的电话和各种通知短信。正好这两天有重要的短信通知要收😂 顾不上电脑硬盘了,我先去找同事借卡针,试图重新插拔 sim 卡解决。借了一圈没借到,最后一个硬件同事给了我一个小镊子,尖头的,正好可以把 sim 卡槽捅出来。插拔了几次也不行,依旧无法识别。
可能太慌乱,我认定是手机嘎了,开始在网上搜红米sim 卡无法识别的解决方案。同事说会不会是SIM卡坏了🤔,有道理啊,于是把sim卡换到了同事手机上,果然也无法识别😂。换到物联网调试工具上,也没有信号。啊哈哈,sim卡的问题实锤了,还好不是手机的问题。
本以为换卡需要去大的电信营业厅,问了才知道小区门口的小电信营业厅就能换卡。而且可以在手机电信app里申请邮寄新卡。我还是决定自己去门店现场换。因为我发现历经几次插拔之后,手机居然奇迹地有信号了📶。我猜测是不是跟电脑内存条一样,也是金手指被氧化了,导致信号不好。如果选择邮寄,当前的sim卡会立即作废,我怕邮寄时间太长,手机一刻没有信号,我都心慌得不行😟
手机高德地图上发现公司附近有个电信营业厅。正好在我每天中午散步的线路上。于是中午吃完饭,嘴都没擦,就奔向营业厅。奶奶的,去了发现只有一个移动营业厅,绕商场寻觅了两圈都没找到电信的,我厚着脸皮进移动营业厅,问出极度无耻的问题,“您好,老板,这附近有电信营业厅么” 😅 老板说那个营业厅搬去另一个地方了,离这里还挺远。。。
地图上看了一下,还挺远,今天看来是换不成卡了。家里楼下小区的店下午五点半就打烊了。看来只能祈祷手机卡还能坚持到周六。周六一早就得去换,因为周六还要出门办事,没有手机信号,就无法支付,啥也干不了🙁 据说前几次换卡是免费的,换多次之后才收费。
我感觉,平时身上还是备点现金好,遇到这种情况,至少还能顺利回家。要不真要走断腿🦵🥲
2025-11-10 11:29:04
很多客户不想用自己的服务器存储物联网硬件上报的日志,而是想通过明道云这类三方的智能多维表格的方案来存储日志。 估计是担心我们后续乱收费吧 😄 其实我感觉现在服务器反而更便宜,至少不会乱收费。麻烦的是,服务器可能有点人工运维成本。客观的说,这种三方表格类存储确实省心 😅
反正客户说的都对,让怎么搞就怎么搞吧。
这里主要记录一下,如何获取明道云数据上报 webhook 链接。自己不常用,久了就忘记从哪里查看 webhook 链接了。
首先,到明道云后台
https://www.mingdao.com
找到应用列表,选中指定的应用,查看其对应的工作流

在工作流界面,找到 webhook 菜单,点开,就能看到流程列表,选中指定的流程

在 webhook 触发中,就能看到对应的 URL 链接。

这个链接复制出来,就能添加到 EMQX MQTT 后台,或者自己搞的 golang server 后台,做数据转发。
2025-11-09 16:07:22
最近在使用 Go 开发一个新闻发布的模块,但是我为了急于看到界面效果,不想先实现后台录入功能, 想先自动创建一批测试数据,直接看 UI 效果。于是找了一个自动生成测试数据的库。 go-faker
https://github.com/go-faker/faker
非常适合网站的新闻模块或者博客模块,需要批量创建几百条测试数据的场景。也支持姓名,邮箱,手机号,IP 地址之类的数据类型。之前还专门写过一个小程序来生成测试数据,参考:随机生成身份证号,手机号,邮箱地址的微信小程序。 印象中 PHP Laravel 框架本身就内置了这个功能,但是 golang gin 还是太简陋了,需要自己动手实现。
import (
"github.com/go-faker/faker/v4"
)
type Article struct {
ID uint
Title string `faker:"sentence"`
Content string `faker:"paragraph"`
Slug string
}
// 生成 1000 条测试数据
func GenerateFakerArticles() {
for i := 0; i < 1000; i++ {
item := Article{}
faker.FakeData(&item)
// 保存到数据库或其他操作
item.Slug = utils.Slugify(item.Title)
DB.Create(&item)
}
}
看一下生成数据的效果:
mysql> select * from article order by id desc limit 1 \G;
*************************** 1. row ***************************
id: 108
title: Officia minus id quasi aliquid voluptate.
slug: officia-minus-id-quasi-aliquid-voluptate
content: Ipsa assumenda quia voluptatem maiores aut. Consequuntur officiis quod incidunt sapiente qui. Est numquam consequuntur impedit expedita placeat. Harum nostrum eos non doloribus quis. Earum nihil quas provident ut ut. Suscipit aliquam soluta incidunt et officia. Corrupti itaque autem numquam perferendis dolor.
1 row in set (0.01 sec)
type SomeStructForLanguage struct {
StringENG string `faker:"lang=eng"`
StringCHI string `faker:"lang=chi"`
StringRUS string `faker:"lang=rus"`
StringJPN string `faker:"lang=jpn"`
StringKOR string `faker:"lang=kor"`
StringEMJ string `faker:"lang=emj"`
}
但是这个不能跟一些特殊的类型使用,例如想生成句子:
Title string `faker:"sentence,lang=eng"`
Title2 string `faker:"sentence,lang=chi"`
会得到
pKwQWXQUQmYNFvIPTQIxWRGBK
征皇芒愈稉莎龑擘廦商蟔囇鹶鉄鑤肘鍱櫉綽耜冧颰氯雝唻
所以,lang 只适合随机字符串。
go get github.com/go-faker/faker/v4
比较神奇的是,我第一次遇到安装依赖会自动升级 golang 版本的情况。。。
> go get github.com/go-faker/faker/v4
go: downloading github.com/go-faker/faker/v4 v4.7.0
go: github.com/go-faker/faker/[email protected] requires go >= 1.24.0; switching to go1.24.10
go: downloading go1.24.10 (linux/amd64)
可能是我本地 golang 版本太低了,没想到 go get 会自动升级 golang 版本 😅 这也太贴心了。
> git diff go.mod
-go 1.23.0
+go 1.24.0
-toolchain go1.23.2
+toolchain go1.24.10
我自己都不知道这个电脑用的还是 go 1.23 🌚🌝。
有了这个库,批量生成测试数据就非常方便了。
当然如果对内容有要求,可能用大模型 API 生成更符合需求。或者用爬虫抓取一批真实数据来进行测试。