diff --git a/controller/channel.go b/controller/channel.go index 2c2a162..36cd0e5 100644 --- a/controller/channel.go +++ b/controller/channel.go @@ -1348,7 +1348,7 @@ func AddChannel(c *gin.Context) { if addChannelRequest.Channel != nil { channelName = addChannelRequest.Channel.Name } - service.RecordCreateOperation(c, "channel", 0, channelName, "创建渠道: "+channelName, "") + service.RecordCreateOperation(c, "channel", 0, channelName, "创建渠道:"+channelName, "") c.JSON(http.StatusOK, gin.H{ "success": true, "message": "", @@ -1366,7 +1366,7 @@ func DeleteChannel(c *gin.Context) { } model.InitChannelCache() // 记录操作日志 - service.RecordDeleteOperation(c, "channel", id, "", fmt.Sprintf("删除渠道 (ID: %d)", id), "") + service.RecordDeleteOperation(c, "channel", id, "", fmt.Sprintf("删除渠道 (ID:%d)", id), "") c.JSON(http.StatusOK, gin.H{ "success": true, "message": "", @@ -1721,7 +1721,7 @@ func UpdateChannel(c *gin.Context) { channel.Key = "" clearChannelInfo(&channel.Channel) // 记录操作日志 - service.RecordUpdateOperation(c, "channel", channel.Id, channel.Name, "更新渠道: "+channel.Name, "") + service.RecordUpdateOperation(c, "channel", channel.Id, channel.Name, "更新渠道:"+channel.Name, "") c.JSON(http.StatusOK, gin.H{ "success": true, "message": "", diff --git a/controller/model_meta.go b/controller/model_meta.go index 6f2729e..a6c3812 100644 --- a/controller/model_meta.go +++ b/controller/model_meta.go @@ -270,7 +270,7 @@ func CreateModelMeta(c *gin.Context) { return } model.RefreshPricing() - service.RecordCreateOperation(c, "model", m.Id, m.ModelName, "创建模型: "+m.ModelName, "") + service.RecordCreateOperation(c, "model", m.Id, m.ModelName, "创建模型:"+m.ModelName, "") common.ApiSuccess(c, &m) } @@ -319,7 +319,7 @@ func UpdateModelMeta(c *gin.Context) { } } model.RefreshPricing() - service.RecordUpdateOperation(c, "model", m.Id, m.ModelName, "更新模型: "+m.ModelName, "") + service.RecordUpdateOperation(c, "model", m.Id, m.ModelName, "更新模型:"+m.ModelName, "") common.ApiSuccess(c, &m) } @@ -336,7 +336,7 @@ func DeleteModelMeta(c *gin.Context) { return } model.RefreshPricing() - service.RecordDeleteOperation(c, "model", id, "", fmt.Sprintf("删除模型 (ID: %d)", id), "") + service.RecordDeleteOperation(c, "model", id, "", fmt.Sprintf("删除模型 (ID:%d)", id), "") common.ApiSuccess(c, nil) } diff --git a/controller/option.go b/controller/option.go index 938a6b7..f5e893a 100644 --- a/controller/option.go +++ b/controller/option.go @@ -690,10 +690,10 @@ func UpdateOption(c *gin.Context) { if modelPricingOptionKeys[option.Key] { changes := computeModelPricingDiff(oldVal, valStr) if len(changes) > 0 { - service.RecordUpdateWithDiff(c, "setting", 0, option.Key, "更新系统设置: "+option.Key, changes, "") + service.RecordUpdateWithDiff(c, "setting", 0, option.Key, "更新系统设置:"+option.Key, changes, "") } } else { - service.RecordUpdateOperation(c, "setting", 0, option.Key, "更新系统设置: "+option.Key, "") + service.RecordUpdateOperation(c, "setting", 0, option.Key, "更新系统设置:"+option.Key, "") } c.JSON(http.StatusOK, gin.H{ diff --git a/controller/redemption.go b/controller/redemption.go index 679d0e7..0c2267a 100644 --- a/controller/redemption.go +++ b/controller/redemption.go @@ -106,7 +106,7 @@ func AddRedemption(c *gin.Context) { } keys = append(keys, key) } - service.RecordCreateOperation(c, "redemption", 0, redemption.Name, "创建兑换码: "+redemption.Name, "") + service.RecordCreateOperation(c, "redemption", 0, redemption.Name, "创建兑换码:"+redemption.Name, "") c.JSON(http.StatusOK, gin.H{ "success": true, "message": "", @@ -122,7 +122,7 @@ func DeleteRedemption(c *gin.Context) { common.ApiError(c, err) return } - service.RecordDeleteOperation(c, "redemption", id, "", fmt.Sprintf("删除兑换码 (ID: %d)", id), "") + service.RecordDeleteOperation(c, "redemption", id, "", fmt.Sprintf("删除兑换码 (ID:%d)", id), "") c.JSON(http.StatusOK, gin.H{ "success": true, "message": "", @@ -161,7 +161,7 @@ func UpdateRedemption(c *gin.Context) { common.ApiError(c, err) return } - service.RecordUpdateOperation(c, "redemption", cleanRedemption.Id, cleanRedemption.Name, "更新兑换码: "+cleanRedemption.Name, "") + service.RecordUpdateOperation(c, "redemption", cleanRedemption.Id, cleanRedemption.Name, "更新兑换码:"+cleanRedemption.Name, "") c.JSON(http.StatusOK, gin.H{ "success": true, "message": "", diff --git a/controller/token.go b/controller/token.go index 1d795b5..ea8b1cc 100644 --- a/controller/token.go +++ b/controller/token.go @@ -228,7 +228,7 @@ func AddToken(c *gin.Context) { common.ApiError(c, err) return } - service.RecordCreateOperation(c, "token", cleanToken.Id, cleanToken.Name, "创建令牌: "+cleanToken.Name, "") + service.RecordCreateOperation(c, "token", cleanToken.Id, cleanToken.Name, "创建令牌:"+cleanToken.Name, "") c.JSON(http.StatusOK, gin.H{ "success": true, "message": "", @@ -243,7 +243,7 @@ func DeleteToken(c *gin.Context) { common.ApiError(c, err) return } - service.RecordDeleteOperation(c, "token", id, "", fmt.Sprintf("删除令牌 (ID: %d)", id), "") + service.RecordDeleteOperation(c, "token", id, "", fmt.Sprintf("删除令牌 (ID:%d)", id), "") c.JSON(http.StatusOK, gin.H{ "success": true, "message": "", @@ -308,7 +308,7 @@ func UpdateToken(c *gin.Context) { common.ApiError(c, err) return } - service.RecordUpdateOperation(c, "token", cleanToken.Id, cleanToken.Name, "更新令牌: "+cleanToken.Name, "") + service.RecordUpdateOperation(c, "token", cleanToken.Id, cleanToken.Name, "更新令牌:"+cleanToken.Name, "") c.JSON(http.StatusOK, gin.H{ "success": true, "message": "", diff --git a/controller/user.go b/controller/user.go index 1bc06bb..55999ab 100644 --- a/controller/user.go +++ b/controller/user.go @@ -1206,7 +1206,7 @@ func UpdateUser(c *gin.Context) { if originUser.DistributorCommissionBps != updatedUser.DistributorCommissionBps { changes = append(changes, service.FieldChange{Field: "分销佣金比例", OldValue: fmt.Sprintf("%d‱", originUser.DistributorCommissionBps), NewValue: fmt.Sprintf("%d‱", updatedUser.DistributorCommissionBps)}) } - service.RecordUpdateWithDiff(c, "user", updatedUser.Id, updatedUser.Username, "更新用户: "+updatedUser.Username, changes, "") + service.RecordUpdateWithDiff(c, "user", updatedUser.Id, updatedUser.Username, "更新用户:"+updatedUser.Username, changes, "") c.JSON(http.StatusOK, gin.H{ "success": true, @@ -1246,7 +1246,7 @@ func AdminClearUserBinding(c *gin.Context) { } model.RecordLog(user.Id, model.LogTypeManage, fmt.Sprintf("admin cleared %s binding for user %s", bindingType, user.Username)) - service.RecordDeleteOperation(c, "user_binding", user.Id, user.Username, "清除用户绑定["+bindingType+"]: "+user.Username, "") + service.RecordDeleteOperation(c, "user_binding", user.Id, user.Username, "清除用户绑定["+bindingType+"]:"+user.Username, "") c.JSON(http.StatusOK, gin.H{ "success": true, @@ -1421,7 +1421,7 @@ func DeleteUser(c *gin.Context) { }) return } - service.RecordDeleteOperation(c, "user", id, originUser.Username, "删除用户: "+originUser.Username, "") + service.RecordDeleteOperation(c, "user", id, originUser.Username, "删除用户:"+originUser.Username, "") } func DeleteSelf(c *gin.Context) { @@ -1501,7 +1501,7 @@ func CreateUser(c *gin.Context) { common.ApiError(c, err) return } - service.RecordCreateOperation(c, "user", cleanUser.Id, cleanUser.Username, "创建用户: "+cleanUser.Username, "") + service.RecordCreateOperation(c, "user", cleanUser.Id, cleanUser.Username, "创建用户:"+cleanUser.Username, "") c.JSON(http.StatusOK, gin.H{ "success": true, @@ -1781,7 +1781,7 @@ func ManageUser(c *gin.Context) { } changes = append(changes, service.FieldChange{Field: "学员", OldValue: oldLabel, NewValue: newLabel}) } - service.RecordUpdateWithDiff(c, "user", user.Id, user.Username, label+": "+user.Username, changes, "") + service.RecordUpdateWithDiff(c, "user", user.Id, user.Username, label+":"+user.Username, changes, "") } switch req.Action { diff --git a/middleware/operation_log.go b/middleware/operation_log.go index 7419f01..7669239 100644 --- a/middleware/operation_log.go +++ b/middleware/operation_log.go @@ -222,7 +222,7 @@ func commonActionLabel(action string, targetType string, targetName string) stri } if targetName != "" { - return actionLabel + typeLabel + ": " + targetName + return actionLabel + typeLabel + ":" + targetName } return actionLabel + typeLabel } diff --git a/web/src/components/layout/SiderBar.jsx b/web/src/components/layout/SiderBar.jsx index f5b7132..a1de32e 100644 --- a/web/src/components/layout/SiderBar.jsx +++ b/web/src/components/layout/SiderBar.jsx @@ -207,6 +207,12 @@ const SiderBar = ({ onNavigate = () => {} }) => { const adminItems = useMemo(() => { const items = [ + { + text: t('操作记录'), + itemKey: 'operation-log', + to: '/console/operation-log', + className: isAdmin() ? '' : 'tableHiddle', + }, { text: t('渠道管理'), itemKey: 'channel', @@ -249,12 +255,6 @@ const SiderBar = ({ onNavigate = () => {} }) => { to: '/user', className: isAdmin() ? '' : 'tableHiddle', }, - { - text: t('操作记录'), - itemKey: 'operation-log', - to: '/console/operation-log', - className: isAdmin() ? '' : 'tableHiddle', - }, { text: t('代理管理'), itemKey: 'distributor', diff --git a/web/src/components/topup/RechargeCard.jsx b/web/src/components/topup/RechargeCard.jsx index 60d9594..73a115f 100644 --- a/web/src/components/topup/RechargeCard.jsx +++ b/web/src/components/topup/RechargeCard.jsx @@ -202,7 +202,7 @@ const RechargeCard = ({ { key: 'rpm', icon: Gauge, - label: t('RPM'), + label: t('每分钟请求'), value: rpmTpmData?.rpm, sublabel: t('最近1分钟'), raw: true, @@ -211,7 +211,7 @@ const RechargeCard = ({ { key: 'tpm', icon: TrendingUp, - label: t('TPM'), + label: t('每分钟Token'), value: rpmTpmData?.tpm, sublabel: t('最近1分钟'), raw: true, diff --git a/web/src/pages/OperationLog/index.jsx b/web/src/pages/OperationLog/index.jsx index 7f924e1..4a81113 100644 --- a/web/src/pages/OperationLog/index.jsx +++ b/web/src/pages/OperationLog/index.jsx @@ -85,6 +85,10 @@ const OperationLog = () => { const [detailVisible, setDetailVisible] = useState(false); const [selectedLog, setSelectedLog] = useState(null); + // Cleanup modal + const [deleteModalVisible, setDeleteModalVisible] = useState(false); + const [deleteDate, setDeleteDate] = useState(null); + const fetchLogs = async () => { setLoading(true); try { @@ -132,14 +136,17 @@ const OperationLog = () => { fetchLogs(); }; - const handleDeleteOldLogs = async () => { - if (!dateRange || !dateRange[1]) { + const handleDeleteOldLogs = () => { + setDeleteDate(null); + setDeleteModalVisible(true); + }; + + const handleConfirmDelete = () => { + if (!deleteDate) { showError('请选择截止日期'); return; } - const targetTimestamp = Math.floor( - new Date(dateRange[1]).getTime() / 1000 - ); + const targetTimestamp = Math.floor(new Date(deleteDate).getTime() / 1000); Modal.confirm({ title: '确认清理', content: `确定要清理 ${timestamp2string(targetTimestamp)} 之前的操作日志吗?此操作不可逆。`, @@ -151,6 +158,7 @@ const OperationLog = () => { const { success, data, message } = res.data; if (success) { showSuccess(`成功清理 ${data} 条操作日志`); + setDeleteModalVisible(false); fetchLogs(); } else { showError(message); @@ -206,7 +214,7 @@ const OperationLog = () => { dataIndex: 'target_name', key: 'target_name', width: 160, - render: (text, record) => text || `ID: ${record.target_id}`, + render: (text, record) => text || `ID:${record.target_id}`, }, { title: t('操作描述'), @@ -339,6 +347,27 @@ const OperationLog = () => { /> + setDeleteModalVisible(false)} + onOk={handleConfirmDelete} + okText={t('确认清理')} + cancelText={t('取消')} + width={420} + > +
+ {t('选择截止日期,将清理该日期之前的所有操作日志。此操作不可逆。')} + +
+
+