從 PHP 到 AI + Golang,程序員自救轉(zhuǎn)型手記(四十七):列表通用排序接口實(shí)現(xiàn)(增量重排法)
這是一個(gè)系列 Blog作者將以一個(gè) PHP 全棧工程師的身份利用 AI 工具claude code、codex、deepseek、豆包等從零開始學(xué)習(xí) golang 語言并最終完成 ai-go-admingithub | gitee開源項(xiàng)目的制作全程記錄分享。在上一期我們進(jìn)行了 “再次優(yōu)化基類”本期將完成列表通用排序接口實(shí)現(xiàn)增量重排法列表通用排序接口實(shí)現(xiàn)增量重排法實(shí)現(xiàn)初版的提示詞繼續(xù)啃BuildAdmin的老本參考../badmin-v2.3.7-full/app/admin/library/traits/Backend.php中的sortable方法在當(dāng)前項(xiàng)目的基類internal/handler/base.go和internal/repository/base.go和internal/service/base.go中實(shí)現(xiàn)sort方法并注冊(cè)路由前端傳遞的參數(shù)有move: moveRow[table.pk!], // 移動(dòng)行 target: targetRow[table.pk!], // 目標(biāo)行 sort: table.filter?.sort, // 排序字段權(quán)重字段 order: table.filter?.order, // 排序方式 direction: evt.newIndexevt.oldIndex ?down:up, // 拖拽方向忽略參考代碼中的$dataLimitAdminIds忽略參考代碼中的 “當(dāng)前是否以權(quán)重字段排序” 檢查即只檢查當(dāng)前排序和默認(rèn)排序字段不檢查有序保證字段功能需求分析前端拖動(dòng)排序如將權(quán)重為1的行排序行拖動(dòng)至權(quán)重為5的行目標(biāo)權(quán)重行或目標(biāo)行所謂增量重排法也可以稱做區(qū)間位移法實(shí)現(xiàn)的是將涉及到的行權(quán)重值全部按算法重設(shè)以達(dá)到視覺上的排序調(diào)整比起全量重排增量重排法影響范圍更小比起交換重排重排后的順序更加合理。難點(diǎn)/注意點(diǎn)如下復(fù)用List列表方法的排序和過濾規(guī)則確保執(zhí)行重新排序時(shí)查得的數(shù)據(jù)列表和前端的一樣。只支持以weigh權(quán)重字段排序時(shí)進(jìn)行重排操作字段名是可以自定義的只使用權(quán)重字段是因?yàn)橹嘏攀切薷臋?quán)重字段值實(shí)現(xiàn)的假設(shè)以創(chuàng)建時(shí)間排序重排功能不可能去修改創(chuàng)建時(shí)間。用戶當(dāng)前可能以weigh asc和weigh desc兩種方式進(jìn)行排序并且可能將排序行向上拖或者向下拖需要全部考慮到位。目標(biāo)行的權(quán)重值不只一行比如目標(biāo)行權(quán)重為5但數(shù)據(jù)表中權(quán)重值為5的行有很多。不要一個(gè) SQL 修改一行而是盡量一個(gè) SQL 完成一類權(quán)重值的全部修改比如權(quán)重值 目標(biāo)權(quán)重的行全部1不能一條一條的遍歷去改。AI 實(shí)現(xiàn)后控制器層的代碼很簡單主要是新增了Sort方法及其請(qǐng)求體結(jié)構(gòu)體定義并注冊(cè)了sort路由。主要功能實(shí)現(xiàn)是在服務(wù)層所以服務(wù)層問題也最多weigh 字段名不固定實(shí)現(xiàn)排序功能期間需要讀取目標(biāo)行的權(quán)重值但字段名是不固定的go 里邊沒有$row[$weigh]這種寫法所以 AI 使用了反射的方式去讀取權(quán)重值反射首先是實(shí)現(xiàn)復(fù)雜二是性能一般拖拽排序其實(shí)無需考慮性能但我們還是直接改為從前端傳遞目標(biāo)行權(quán)重值即可服務(wù)端直接讀取并使用去掉反射相關(guān)代碼。AI 根據(jù)需求實(shí)現(xiàn)后接受的前端變量名為target_weigh由于我們服務(wù)端不需要使用排序行的權(quán)重值只需要目標(biāo)行的權(quán)重值這里將target_weigh改名為更簡潔的weigh即可。并且AI 將weigh的類型定義為any這里直接固定為int64。改為 Generics API在這種需要比較復(fù)雜的 update 語句時(shí)AI 又開始忘記AGENTS.md中的規(guī)則了這里強(qiáng)行要求它改為Generics API// 原來的iferr:tx.Model(new(T)).Where(weighField bulkOp ?,weigh).Where(pkField ?,move).UpdateColumn(weighField,gorm.Expr(weighField updateOp ?,weighRowsCount)).Error;err!nil{returnerr}// 改為gtx:gorm.G[T](tx)iferr:gtx.Where(weighField bulkOp ?,weigh).Where(pkField ?,move).UpdateColumn(weighField,gorm.Expr(weighField updateOp ?,weighRowsCount));err!nil{returnerr}// 且 gtx 后續(xù)復(fù)用另外重排實(shí)現(xiàn)內(nèi)必需使用一下傳統(tǒng) API 的Pluck方法當(dāng)然也可以使用Generics API的Select方法去選擇字段只是這樣又需要反射讀取結(jié)構(gòu)體中數(shù)據(jù)庫列名對(duì)應(yīng)的字段值了沒必要。反轉(zhuǎn)切片代碼優(yōu)化實(shí)現(xiàn)重排時(shí)有一段反轉(zhuǎn)數(shù)組的代碼// 向下拖動(dòng)時(shí)反轉(zhuǎn)保證等權(quán)重區(qū)間內(nèi)相對(duì)順序不變ifdirectiondown{fori,j:0,len(weighIDs)-1;ij;i,ji1,j-1{weighIDs[i],weighIDs[j]weighIDs[j],weighIDs[i]}}在Go 1.25 提供了slices.Reverse方法可以直接使用簡化為// 向下拖動(dòng)時(shí)反轉(zhuǎn)保證等權(quán)重區(qū)間內(nèi)相對(duì)順序不變ifdirectiondown{slices.Reverse(weighIDs)}多余的封裝AI 幫忙封裝了一個(gè)exprOffset函數(shù)用于組裝一些排序用的查詢表達(dá)式但其對(duì)整體無益且不被Sort方法以外的地方復(fù)用這里讓它直接改為在Sort方法內(nèi)封裝為閉包函數(shù)即可不要放在Sort方法外邊。BUG我在測試前首先讓 AI 直接再寫一點(diǎn)調(diào)試代碼打印出Sort方法內(nèi)執(zhí)行的所有SQL然后前端進(jìn)行操作對(duì)比我的需求與執(zhí)行的SQL發(fā)現(xiàn)一處排序錯(cuò)誤代碼我們已經(jīng)review過了沒有發(fā)現(xiàn)明顯問題應(yīng)該是某處細(xì)節(jié)上的邏輯錯(cuò)誤這里直接把日志給 AI并加以描述提示詞好像有 BUG排序后有權(quán)重值重復(fù)的行我有權(quán)重值為1,2,3的行入?yún)ove1 target3時(shí)執(zhí)行的SQL有以下2026/07/25 00:19:34 C:/Users/yang/Desktop/admin/internal/service/base.go:148[0.709ms][rows:1]SELECTidFROMadmin_rulesWHERE weigh3ORDER BY weigh DESC,id DESC2026/07/25 00:19:34 C:/Users/yang/Desktop/admin/internal/service/base.go:171[0.525ms][rows:0]UPDATEadmin_rulesSETweighweigh -1,updated_at2026-07-25 00:19:34.578WHERE weigh3ANDid12026/07/25 00:19:34 C:/Users/yang/Desktop/admin/internal/service/base.go:201[0.628ms][rows:1]UPDATEadmin_rulesSETweigh3,updated_at2026-07-25 00:19:34.578WHEREid12026/07/25 00:19:34 C:/Users/yang/Desktop/admin/internal/service/base.go:213[0.541ms][rows:1]UPDATEadmin_rulesSETweigh2,updated_at2026-07-25 00:19:34.579WHEREid3最終結(jié)果是有兩行的權(quán)重值均為2這與目標(biāo)不符應(yīng)該不出現(xiàn)重復(fù)的權(quán)重才對(duì)對(duì)比參考代碼../badmin-v2.3.7-full/app/admin/library/traits/Backend.php的sortable方法找出原因找到原因了。對(duì)比PHP代碼的bulk update邏輯PHP正確// updateMethod dec → WHERE weigh target// updateMethod inc → WHERE weigh target-where(weigh,$updateMethoddec?:,$weigh)Go錯(cuò)誤// updateOp - → bulkOp ← 反了// updateOp → bulkOp bulkOp:ifupdateOp{bulkOp}dec權(quán)重 ?1應(yīng)該影響權(quán)重比目標(biāo)小的行讓它們?cè)贉p給拖動(dòng)行騰位置。我把 和 寫反了。嚯AI 居然還會(huì)犯這種邏輯錯(cuò)誤。

相關(guān)新聞

VisionPro中CogGraphicLabel動(dòng)態(tài)文本標(biāo)注:從原理到工業(yè)視覺實(shí)戰(zhàn)

VisionPro中CogGraphicLabel動(dòng)態(tài)文本標(biāo)注:從原理到工業(yè)視覺實(shí)戰(zhàn)

1. 項(xiàng)目概述:在VisionPro中動(dòng)態(tài)顯示文本標(biāo)簽在機(jī)器視覺項(xiàng)目開發(fā)中,尤其是在使用康耐視VisionPro這類強(qiáng)大的工具時(shí),我們經(jīng)常遇到一個(gè)看似簡單卻至關(guān)重要的需求:如何在圖像上清晰、動(dòng)態(tài)地顯示文本信息。這個(gè)信息可能是檢測結(jié)果&…

2026/8/2 5:04:57 閱讀更多
《javaweb的基礎(chǔ)》0基礎(chǔ)學(xué)習(xí)前端內(nèi)容--vue框架

《javaweb的基礎(chǔ)》0基礎(chǔ)學(xué)習(xí)前端內(nèi)容--vue框架

首先申明,這是基礎(chǔ)內(nèi)容,為的是帶大家了解vue這個(gè)內(nèi)容,嘗試學(xué)習(xí)vue基礎(chǔ)知識(shí),其實(shí)vue是一個(gè)很大的知識(shí)體系,這里我簡單的講述了一下對(duì)于前后端數(shù)據(jù)傳輸后的數(shù)據(jù)最基本的處理,不涉及生態(tài),只是對(duì)交互…

2026/8/2 5:04:57 閱讀更多
云手機(jī)設(shè)備環(huán)境隔離技術(shù)解析——以QTphone ARM原生架構(gòu)為例

云手機(jī)設(shè)備環(huán)境隔離技術(shù)解析——以QTphone ARM原生架構(gòu)為例

在出海應(yīng)用測試、社交媒體矩陣運(yùn)營及移動(dòng)端自動(dòng)化等場景中,多賬號(hào)環(huán)境隔離是規(guī)避平臺(tái)風(fēng)控關(guān)聯(lián)檢測的核心前提。傳統(tǒng)x86模擬器因底層架構(gòu)差異,難以提供真實(shí)的硬件指紋與環(huán)境參數(shù),極易被風(fēng)控系統(tǒng)識(shí)別。本文以QTphone云手機(jī)為例,從AR…

2026/8/2 13:26:10 閱讀更多
Excel性能優(yōu)化與系統(tǒng)化問題解決框架:從讀取瓶頸到數(shù)據(jù)管理

Excel性能優(yōu)化與系統(tǒng)化問題解決框架:從讀取瓶頸到數(shù)據(jù)管理

1. 項(xiàng)目概述:從“問題”到“系統(tǒng)化解決” 干了這么多年數(shù)據(jù)分析,我敢說,90%以上的人對(duì)Excel的認(rèn)知,都停留在“會(huì)用”和“精通”之間那片巨大的灰色地帶。你可能會(huì)用VLOOKUP,知道透視表,甚至寫過幾個(gè)宏&…

2026/8/2 13:26:10 閱讀更多
Conjugate Expression

Conjugate Expression

將數(shù)學(xué)中的**“共軛式”(Conjugate Expression)**概念遷移到工作、生活和股票投資中,是一個(gè)非常有深度且極具跨界想象力的思維嘗試。 在數(shù)學(xué)中,共軛式(如 ababab 與 a?ba-ba?b)的核心作用是:通…

2026/8/2 13:16:10 閱讀更多
MoneyPrinterPlus實(shí)戰(zhàn)指南:AI視頻批量生成與自動(dòng)化發(fā)布完整解決方案

MoneyPrinterPlus實(shí)戰(zhàn)指南:AI視頻批量生成與自動(dòng)化發(fā)布完整解決方案

MoneyPrinterPlus實(shí)戰(zhàn)指南:AI視頻批量生成與自動(dòng)化發(fā)布完整解決方案 【免費(fèi)下載鏈接】MoneyPrinterPlus AI一鍵批量生成各類短視頻,自動(dòng)批量混剪短視頻,自動(dòng)把視頻發(fā)布到抖音,快手,小紅書,視頻號(hào)上,賺錢從來沒有這么容易過! 支持本地語音模型chatTTS,fasterwhisper,…

2026/8/2 0:04:00 閱讀更多
3分鐘搞定!QQ空間歷史說說完整備份終極指南

3分鐘搞定!QQ空間歷史說說完整備份終極指南

3分鐘搞定!QQ空間歷史說說完整備份終極指南 【免費(fèi)下載鏈接】GetQzonehistory 獲取QQ空間發(fā)布的歷史說說 項(xiàng)目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否曾想過,那些年發(fā)過的QQ空間說說,那些記錄青春的文字…

2026/8/2 0:04:01 閱讀更多
MoneyPrinterPlus實(shí)戰(zhàn)指南:AI視頻批量生成與自動(dòng)化發(fā)布完整解決方案

MoneyPrinterPlus實(shí)戰(zhàn)指南:AI視頻批量生成與自動(dòng)化發(fā)布完整解決方案

MoneyPrinterPlus實(shí)戰(zhàn)指南:AI視頻批量生成與自動(dòng)化發(fā)布完整解決方案 【免費(fèi)下載鏈接】MoneyPrinterPlus AI一鍵批量生成各類短視頻,自動(dòng)批量混剪短視頻,自動(dòng)把視頻發(fā)布到抖音,快手,小紅書,視頻號(hào)上,賺錢從來沒有這么容易過! 支持本地語音模型chatTTS,fasterwhisper,…

2026/8/2 0:04:00 閱讀更多
3分鐘搞定!QQ空間歷史說說完整備份終極指南

3分鐘搞定!QQ空間歷史說說完整備份終極指南

3分鐘搞定!QQ空間歷史說說完整備份終極指南 【免費(fèi)下載鏈接】GetQzonehistory 獲取QQ空間發(fā)布的歷史說說 項(xiàng)目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否曾想過,那些年發(fā)過的QQ空間說說,那些記錄青春的文字…

2026/8/2 0:04:01 閱讀更多
AMAT 0100-02186 I/O 分配 PCB

AMAT 0100-02186 I/O 分配 PCB

AMAT 0100-02186 I/O分配PCB板是應(yīng)用材料(Applied Materials)公司生產(chǎn)的一款用于半導(dǎo)體設(shè)備的I/O信號(hào)分配電路板。該型號(hào)(0100-02186)的核心特點(diǎn)如下:專用于Endura等半導(dǎo)體工藝腔室。集成信號(hào)路由與分配功能。連接控制…

2026/8/2 2:51:21 閱讀更多
Nissei Corp FFMN-32L-10-T0 40AX 三相異步電動(dòng)機(jī)

Nissei Corp FFMN-32L-10-T0 40AX 三相異步電動(dòng)機(jī)

Nissei Corp FFMN-32L-10-T0 40AX 三相異步電動(dòng)機(jī)是日本日清(Nissei)品牌的一款工業(yè)用三相異步電機(jī),適用于自動(dòng)化設(shè)備及通用機(jī)械驅(qū)動(dòng)。該型號(hào)(FFMN-32L-10-T0 40AX)的核心特點(diǎn)如下:三相交流異步電動(dòng)機(jī)。額定…

2026/8/2 2:52:49 閱讀更多