diff --git a/internal/admin/service.go b/internal/admin/service.go index 79fba69955..555cd2817e 100644 --- a/internal/admin/service.go +++ b/internal/admin/service.go @@ -45,13 +45,15 @@ var ( // Service admin service layer type Service struct { - userDAO *dao.UserDAO + userDAO *dao.UserDAO + licenseDAO *dao.LicenseDAO } // NewService create admin service func NewService() *Service { return &Service{ - userDAO: dao.NewUserDAO(), + userDAO: dao.NewUserDAO(), + licenseDAO: dao.NewLicenseDAO(), } } diff --git a/internal/dao/database.go b/internal/dao/database.go index b35e79c80c..7c5e002394 100644 --- a/internal/dao/database.go +++ b/internal/dao/database.go @@ -140,6 +140,8 @@ func InitDB() error { &model.EvaluationCase{}, &model.EvaluationRun{}, &model.EvaluationResult{}, + &model.TimeRecord{}, + &model.License{}, } for _, m := range models { diff --git a/internal/dao/license.go b/internal/dao/license.go new file mode 100644 index 0000000000..4108d6c9d9 --- /dev/null +++ b/internal/dao/license.go @@ -0,0 +1,50 @@ +// +// Copyright 2026 The InfiniFlow Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package dao + +import ( + "ragflow/internal/model" + "time" +) + +// LicenseDAO license data access object +type LicenseDAO struct{} + +// NewLicenseDAO create license DAO +func NewLicenseDAO() *LicenseDAO { + return &LicenseDAO{} +} + +// Create creates a new license record +func (dao *LicenseDAO) Create(licenseID, licenseStr string) error { + license := model.License{ + ID: licenseID, + License: licenseStr, + CreatedAt: time.Now(), + } + return DB.Create(license).Error +} + +// GetLatest gets the latest license record by creation time +func (dao *LicenseDAO) GetLatest() (*model.License, error) { + var license model.License + err := DB.Order("created_at DESC").First(&license).Error + if err != nil { + return nil, err + } + return &license, nil +} diff --git a/internal/dao/time_record.go b/internal/dao/time_record.go new file mode 100644 index 0000000000..18387b945f --- /dev/null +++ b/internal/dao/time_record.go @@ -0,0 +1,66 @@ +// +// Copyright 2026 The InfiniFlow Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package dao + +import ( + "ragflow/internal/model" +) + +// TimeRecordDAO time record data access object +type TimeRecordDAO struct{} + +// NewTimeRecordDAO create TimeRecord DAO +func NewTimeRecordDAO() *TimeRecordDAO { + return &TimeRecordDAO{} +} + +// Create inserts a new record +func (dao *TimeRecordDAO) Create(record *model.TimeRecord) error { + return DB.Create(record).Error +} + +// GetRecent retrieves the most recently inserted records (ordered by ID descending) +func (dao *TimeRecordDAO) GetRecent(limit int) ([]*model.TimeRecord, error) { + var records []*model.TimeRecord + err := DB.Order("id DESC").Limit(limit).Find(&records).Error + if err != nil { + return nil, err + } + return records, nil +} + +// GetCount returns the total number of records +func (dao *TimeRecordDAO) GetCount() (int64, error) { + var count int64 + err := DB.Model(&model.TimeRecord{}).Count(&count).Error + return count, err +} + +// DeleteOldest removes the oldest records (smallest ID) with limit +func (dao *TimeRecordDAO) DeleteOldest(limit int64) error { + return DB.Exec("DELETE FROM time_records ORDER BY id ASC LIMIT ?", limit).Error +} + +// GetByID retrieves a single record by its ID +func (dao *TimeRecordDAO) GetByID(id int64) (*model.TimeRecord, error) { + var record model.TimeRecord + err := DB.First(&record, id).Error + if err != nil { + return nil, err + } + return &record, nil +} diff --git a/internal/model/license.go b/internal/model/license.go new file mode 100644 index 0000000000..f82b5d1216 --- /dev/null +++ b/internal/model/license.go @@ -0,0 +1,33 @@ +// +// Copyright 2026 The InfiniFlow Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package model + +import ( + "time" +) + +// License time record model +type License struct { + ID string `gorm:"column:id;size:128;not null;primaryKey" json:"id"` + License string `gorm:"column:encrypted_data;type:longtext;not null" json:"encrypted_data"` + CreatedAt time.Time `gorm:"column:created_at;type:timestamp;default:CURRENT_TIMESTAMP" json:"created_at"` +} + +// TableName specify table name +func (License) TableName() string { + return "license" +} diff --git a/internal/model/time_record.go b/internal/model/time_record.go new file mode 100644 index 0000000000..6ff3af4c20 --- /dev/null +++ b/internal/model/time_record.go @@ -0,0 +1,33 @@ +// +// Copyright 2026 The InfiniFlow Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package model + +import ( + "time" +) + +// TimeRecord time record model +type TimeRecord struct { + ID int64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + Data string `gorm:"column:data;type:longtext;not null" json:"data"` + CreatedAt time.Time `gorm:"column:created_at;type:timestamp;default:CURRENT_TIMESTAMP" json:"created_at"` +} + +// TableName specify table name +func (TimeRecord) TableName() string { + return "time_records" +} diff --git a/internal/server/config.go b/internal/server/config.go index b028ae76ce..6db21f9b9e 100644 --- a/internal/server/config.go +++ b/internal/server/config.go @@ -378,8 +378,8 @@ func Init(configPath string) error { if v.IsSet("ragflow") { ragflowConfig := v.Sub("ragflow") if ragflowConfig != nil { - //globalConfig.Server.Port = ragflowConfig.GetInt("http_port") + 2 // 9382, by default - globalConfig.Server.Port = ragflowConfig.GetInt("http_port") // Correct + globalConfig.Server.Port = ragflowConfig.GetInt("http_port") + 2 // 9382, by default + //globalConfig.Server.Port = ragflowConfig.GetInt("http_port") // Correct // If mode is not set, default to debug if globalConfig.Server.Mode == "" { globalConfig.Server.Mode = "release" diff --git a/test/testcases/conftest.py b/test/testcases/conftest.py index 69c6a394bb..158c11f50f 100644 --- a/test/testcases/conftest.py +++ b/test/testcases/conftest.py @@ -165,7 +165,8 @@ def token(auth): response = requests.post(url=url, headers=auth) res = response.json() if res.get("code") != 0: - raise Exception(res.get("message")) + error_msg = f"access: {url}, POST method, error code: {res.get("code")}, message: {res.get('message')}" + raise Exception(error_msg) return res["data"].get("token")