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

相關(guān)新聞

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

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

1. 項目概述:在VisionPro中動態(tài)顯示文本標(biāo)簽在機器視覺項目開發(fā)中,尤其是在使用康耐視VisionPro這類強大的工具時,我們經(jīng)常遇到一個看似簡單卻至關(guān)重要的需求:如何在圖像上清晰、動態(tài)地顯示文本信息。這個信息可能是檢測結(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這個內(nèi)容,嘗試學(xué)習(xí)vue基礎(chǔ)知識,其實vue是一個很大的知識體系,這里我簡單的講述了一下對于前后端數(shù)據(jù)傳輸后的數(shù)據(jù)最基本的處理,不涉及生態(tài),只是對交互…

2026/8/2 5:04:57 閱讀更多
攪拌設(shè)備機架各材質(zhì)優(yōu)缺點詳解

攪拌設(shè)備機架各材質(zhì)優(yōu)缺點詳解

結(jié)合豐享攪拌設(shè)備落地工況,針對以上五種常用機架材質(zhì),逐一拆解真實優(yōu)點、行業(yè)短板、適用邊界,解決選型低配生銹、高配浪費、材質(zhì)用錯變形腐蝕等問題。1、普通噴漆碳鋼 Q235-B優(yōu)點:成本最低、焊接性能好、整體剛性穩(wěn)定、不易變形、…

2026/8/2 6:05:00 閱讀更多
BuildArena:基于物理仿真的LLM智能體工程基準(zhǔn)測試平臺

BuildArena:基于物理仿真的LLM智能體工程基準(zhǔn)測試平臺

1. 項目緣起:當(dāng)大模型遇上物理世界,我們到底在測什么?最近兩年,大語言模型(LLM)在文本生成、代碼編寫、邏輯推理上的表現(xiàn)讓人眼花繚亂。但如果你問一個在建筑工地、工廠產(chǎn)線或者復(fù)雜設(shè)備裝配現(xiàn)場摸爬滾打多…

2026/8/2 6:05:00 閱讀更多
OpenClaw與OPC浪潮:技術(shù)架構(gòu)演進、風(fēng)險識別與理性實踐指南

OpenClaw與OPC浪潮:技術(shù)架構(gòu)演進、風(fēng)險識別與理性實踐指南

1. 項目概述:當(dāng)“OpenClaw”成為現(xiàn)象,我們該如何看待?最近,一個名為“OpenClaw”的概念在圈內(nèi)迅速升溫,連帶“OPC”這個縮寫也頻繁出現(xiàn)在各種討論和報道中。作為一個長期關(guān)注技術(shù)趨勢和產(chǎn)業(yè)動態(tài)的從業(yè)者,我…

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

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

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

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

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

3分鐘搞定!QQ空間歷史說說完整備份終極指南 【免費下載鏈接】GetQzonehistory 獲取QQ空間發(fā)布的歷史說說 項目地址: 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信號分配電路板。該型號(0100-02186)的核心特點如下:專用于Endura等半導(dǎo)體工藝腔室。集成信號路由與分配功能。連接控制…

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

Nissei Corp FFMN-32L-10-T0 40AX 三相異步電動機

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

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