初始化

This commit is contained in:
李琦
2026-01-15 13:51:44 +08:00
commit b7b6d3e39e
156 changed files with 38913 additions and 0 deletions

View File

@@ -0,0 +1,109 @@
package repositories
import (
"log"
"github.com/niangaodev/art-code/config"
"github.com/niangaodev/art-code/models"
)
// CreateOperationLog 创建操作日志
func CreateOperationLog(operationLog *models.OperationLog) error {
query := `
INSERT INTO operation_logs (user_id, username, ip, path, method, params, status, duration, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, NOW())
`
_, err := config.DB.Exec(
query,
operationLog.UserID,
operationLog.Username,
operationLog.IP,
operationLog.Path,
operationLog.Method,
operationLog.Params,
operationLog.Status,
operationLog.Duration,
)
if err != nil {
log.Printf("Error creating operation log: %v", err)
return err
}
return nil
}
// GetOperationLogs 获取操作日志列表
func GetOperationLogs(page, pageSize int) ([]models.OperationLog, int64, error) {
// 计算偏移量
offset := (page - 1) * pageSize
// 获取总记录数
var total int64
countQuery := "SELECT COUNT(*) FROM operation_logs"
if err := config.DB.QueryRow(countQuery).Scan(&total); err != nil {
log.Printf("Error counting operation logs: %v", err)
return nil, 0, err
}
// 获取分页数据
query := `
SELECT id, user_id, username, ip, path, method, params, status, duration, created_at
FROM operation_logs
ORDER BY created_at DESC
LIMIT ? OFFSET ?
`
rows, err := config.DB.Query(query, pageSize, offset)
if err != nil {
log.Printf("Error querying operation logs: %v", err)
return nil, 0, err
}
defer rows.Close()
var logs []models.OperationLog
for rows.Next() {
var operationLog models.OperationLog
if err := rows.Scan(
&operationLog.ID,
&operationLog.UserID,
&operationLog.Username,
&operationLog.IP,
&operationLog.Path,
&operationLog.Method,
&operationLog.Params,
&operationLog.Status,
&operationLog.Duration,
&operationLog.CreatedAt,
); err != nil {
log.Printf("Error scanning operation log: %v", err)
continue
}
logs = append(logs, operationLog)
}
return logs, total, nil
}
// BuildOperationLogResponse 构建操作日志响应
func BuildOperationLogResponse(log *models.OperationLog) *models.OperationLogResponse {
return &models.OperationLogResponse{
ID: log.ID,
UserID: log.UserID,
Username: log.Username,
IP: log.IP,
Path: log.Path,
Method: log.Method,
Params: log.Params,
Status: log.Status,
Duration: log.Duration,
CreatedAt: log.CreatedAt.Format("2006-01-02 15:04:05"),
}
}
// BuildOperationLogsResponse 构建操作日志列表响应
func BuildOperationLogsResponse(logs []models.OperationLog) []models.OperationLogResponse {
var responses []models.OperationLogResponse
for _, log := range logs {
responses = append(responses, *BuildOperationLogResponse(&log))
}
return responses
}

View File

@@ -0,0 +1,80 @@
package repositories
import (
"log"
"github.com/niangaodev/art-code/config"
"github.com/niangaodev/art-code/models"
)
// GetPermissions 获取所有权限
func GetPermissions() ([]models.Permission, error) {
query := "SELECT id, name, resource, action, created_at, updated_at FROM permissions"
rows, err := config.DB.Query(query)
if err != nil {
log.Printf("Error getting permissions: %v", err)
return nil, err
}
defer rows.Close()
var permissions []models.Permission
for rows.Next() {
var permission models.Permission
if err := rows.Scan(&permission.ID, &permission.Name, &permission.Resource, &permission.Action, &permission.CreatedAt, &permission.UpdatedAt); err != nil {
log.Printf("Error scanning permission: %v", err)
continue
}
permissions = append(permissions, permission)
}
return permissions, nil
}
// GetPermissionsByRoleID 获取指定角色的权限
func GetPermissionsByRoleID(roleID uint) ([]models.Permission, error) {
query := `
SELECT p.id, p.name, p.resource, p.action, p.created_at, p.updated_at
FROM permissions p
JOIN role_permissions rp ON p.id = rp.permission_id
WHERE rp.role_id = ?
`
rows, err := config.DB.Query(query, roleID)
if err != nil {
log.Printf("Error getting permissions by role id: %v", err)
return nil, err
}
defer rows.Close()
var permissions []models.Permission
for rows.Next() {
var permission models.Permission
if err := rows.Scan(&permission.ID, &permission.Name, &permission.Resource, &permission.Action, &permission.CreatedAt, &permission.UpdatedAt); err != nil {
log.Printf("Error scanning permission: %v", err)
continue
}
permissions = append(permissions, permission)
}
return permissions, nil
}
// BuildPermissionResponse 构建权限响应
func BuildPermissionResponse(permission *models.Permission) *models.PermissionResponse {
return &models.PermissionResponse{
ID: permission.ID,
Name: permission.Name,
Resource: permission.Resource,
Action: permission.Action,
CreatedAt: permission.CreatedAt.Format("2006-01-02 15:04:05"),
UpdatedAt: permission.UpdatedAt.Format("2006-01-02 15:04:05"),
}
}
// BuildPermissionsResponse 构建权限列表响应
func BuildPermissionsResponse(permissions []models.Permission) []models.PermissionResponse {
var responses []models.PermissionResponse
for _, permission := range permissions {
responses = append(responses, *BuildPermissionResponse(&permission))
}
return responses
}

View File

@@ -0,0 +1,351 @@
package repositories
import (
"database/sql"
"log"
"github.com/niangaodev/art-code/config"
"github.com/niangaodev/art-code/models"
)
// GetPosts 获取所有博客文章
func GetPosts() ([]models.Post, error) {
query := "SELECT id, title, category, date, excerpt, content, read_count, is_published, created_at, updated_at FROM posts WHERE is_published = 1 ORDER BY date DESC"
rows, err := config.DB.Query(query)
if err != nil {
log.Printf("Error querying posts: %v", err)
return nil, err
}
defer rows.Close()
var posts []models.Post
for rows.Next() {
var post models.Post
if err := rows.Scan(
&post.ID,
&post.Title,
&post.Category,
&post.Date,
&post.Excerpt,
&post.Content,
&post.ReadCount,
&post.IsPublished,
&post.CreatedAt,
&post.UpdatedAt,
); err != nil {
log.Printf("Error scanning post: %v", err)
continue
}
posts = append(posts, post)
}
return posts, nil
}
// GetPostByID 根据ID获取博客文章
func GetPostByID(id string) (*models.Post, error) {
query := "SELECT id, title, category, date, excerpt, content, read_count, is_published, created_at, updated_at FROM posts WHERE id = ? AND is_published = 1"
row := config.DB.QueryRow(query, id)
var post models.Post
if err := row.Scan(
&post.ID,
&post.Title,
&post.Category,
&post.Date,
&post.Excerpt,
&post.Content,
&post.ReadCount,
&post.IsPublished,
&post.CreatedAt,
&post.UpdatedAt,
); err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
log.Printf("Error scanning post by ID: %v", err)
return nil, err
}
// 更新阅读量
updateReadCountQuery := "UPDATE posts SET read_count = read_count + 1 WHERE id = ?"
if _, err := config.DB.Exec(updateReadCountQuery, id); err != nil {
log.Printf("Error updating post read count: %v", err)
}
return &post, nil
}
// GetAllPosts 获取所有博客文章(包括未发布的)
func GetAllPosts() ([]models.Post, error) {
query := "SELECT id, title, category, date, excerpt, content, read_count, is_published, created_at, updated_at FROM posts ORDER BY date DESC"
rows, err := config.DB.Query(query)
if err != nil {
log.Printf("Error querying all posts: %v", err)
return nil, err
}
defer rows.Close()
var posts []models.Post
for rows.Next() {
var post models.Post
if err := rows.Scan(
&post.ID,
&post.Title,
&post.Category,
&post.Date,
&post.Excerpt,
&post.Content,
&post.ReadCount,
&post.IsPublished,
&post.CreatedAt,
&post.UpdatedAt,
); err != nil {
log.Printf("Error scanning post: %v", err)
continue
}
posts = append(posts, post)
}
return posts, nil
}
// CreatePost 创建博客文章
func CreatePost(post *models.Post) error {
query := `
INSERT INTO posts (id, title, category, date, excerpt, content, is_published, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, NOW(), NOW())
`
_, err := config.DB.Exec(
query,
post.ID,
post.Title,
post.Category,
post.Date,
post.Excerpt,
post.Content,
post.IsPublished,
)
if err != nil {
log.Printf("Error creating post: %v", err)
return err
}
return nil
}
// UpdatePost 更新博客文章
func UpdatePost(post *models.Post) error {
query := `
UPDATE posts SET title = ?, category = ?, date = ?, excerpt = ?, content = ?, is_published = ?, updated_at = NOW()
WHERE id = ?
`
_, err := config.DB.Exec(
query,
post.Title,
post.Category,
post.Date,
post.Excerpt,
post.Content,
post.IsPublished,
post.ID,
)
if err != nil {
log.Printf("Error updating post: %v", err)
return err
}
return nil
}
// DeletePost 删除博客文章
func DeletePost(id string) error {
query := "DELETE FROM posts WHERE id = ?"
_, err := config.DB.Exec(query, id)
if err != nil {
log.Printf("Error deleting post: %v", err)
return err
}
return nil
}
// GetPostCount 获取文章总数
func GetPostCount() (int, error) {
var count int
query := "SELECT COUNT(*) FROM posts"
row := config.DB.QueryRow(query)
err := row.Scan(&count)
if err != nil {
log.Printf("Error getting post count: %v", err)
return 0, err
}
return count, nil
}
// BuildPostResponse 构建博客文章响应
func BuildPostResponse(post *models.Post, includeContent bool) *models.PostResponse {
response := &models.PostResponse{
ID: post.ID,
Title: post.Title,
Category: post.Category,
Date: post.Date.Format("2006-01-02"),
Excerpt: post.Excerpt,
}
if includeContent {
response.Content = post.Content
}
return response
}
// BuildPostsResponse 构建博客文章列表响应
func BuildPostsResponse(posts []models.Post) []models.PostResponse {
var responses []models.PostResponse
for _, post := range posts {
responses = append(responses, *BuildPostResponse(&post, false))
}
return responses
}
// SavePostHistory 保存文章历史记录
func SavePostHistory(post *models.Post, modifiedBy uint) error {
// 获取当前最大版本号
var maxVersion uint
query := "SELECT COALESCE(MAX(version), 0) FROM post_history WHERE post_id = ?"
if err := config.DB.QueryRow(query, post.ID).Scan(&maxVersion); err != nil {
log.Printf("Error getting max version: %v", err)
return err
}
// 插入新的历史记录
insertQuery := `
INSERT INTO post_history (
post_id, version, title, category, date, excerpt, content,
is_published, modified_by, modified_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())
`
_, err := config.DB.Exec(
insertQuery,
post.ID,
maxVersion+1,
post.Title,
post.Category,
post.Date,
post.Excerpt,
post.Content,
post.IsPublished,
modifiedBy,
)
if err != nil {
log.Printf("Error saving post history: %v", err)
return err
}
return nil
}
// GetPostHistory 获取文章历史记录
func GetPostHistory(postID string) ([]models.PostHistory, error) {
query := `
SELECT id, post_id, version, title, category, date, excerpt, content,
is_published, modified_by, modified_at, created_at
FROM post_history
WHERE post_id = ?
ORDER BY version DESC
`
rows, err := config.DB.Query(query, postID)
if err != nil {
log.Printf("Error querying post history: %v", err)
return nil, err
}
defer rows.Close()
var history []models.PostHistory
for rows.Next() {
var h models.PostHistory
if err := rows.Scan(
&h.ID,
&h.PostID,
&h.Version,
&h.Title,
&h.Category,
&h.Date,
&h.Excerpt,
&h.Content,
&h.IsPublished,
&h.ModifiedBy,
&h.ModifiedAt,
&h.CreatedAt,
); err != nil {
log.Printf("Error scanning post history: %v", err)
continue
}
history = append(history, h)
}
return history, nil
}
// GetPostHistoryByVersion 获取指定版本的文章历史记录
func GetPostHistoryByVersion(postID string, version uint) (*models.PostHistory, error) {
query := `
SELECT id, post_id, version, title, category, date, excerpt, content,
is_published, modified_by, modified_at, created_at
FROM post_history
WHERE post_id = ? AND version = ?
`
row := config.DB.QueryRow(query, postID, version)
var h models.PostHistory
if err := row.Scan(
&h.ID,
&h.PostID,
&h.Version,
&h.Title,
&h.Category,
&h.Date,
&h.Excerpt,
&h.Content,
&h.IsPublished,
&h.ModifiedBy,
&h.ModifiedAt,
&h.CreatedAt,
); err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
log.Printf("Error scanning post history by version: %v", err)
return nil, err
}
return &h, nil
}
// BuildPostHistoryResponse 构建文章历史记录响应
func BuildPostHistoryResponse(history *models.PostHistory) *models.PostHistoryResponse {
return &models.PostHistoryResponse{
ID: history.ID,
PostID: history.PostID,
Version: history.Version,
Title: history.Title,
Category: history.Category,
Date: history.Date.Format("2006-01-02"),
IsPublished: history.IsPublished,
ModifiedBy: history.ModifiedBy,
ModifiedAt: history.ModifiedAt.Format("2006-01-02 15:04:05"),
CreatedAt: history.CreatedAt.Format("2006-01-02 15:04:05"),
}
}
// BuildPostHistoryResponses 构建文章历史记录列表响应
func BuildPostHistoryResponses(history []models.PostHistory) []models.PostHistoryResponse {
var responses []models.PostHistoryResponse
for _, h := range history {
responses = append(responses, *BuildPostHistoryResponse(&h))
}
return responses
}

View File

@@ -0,0 +1,166 @@
package repositories
import (
"log"
"time"
"github.com/niangaodev/art-code/config"
"github.com/niangaodev/art-code/models"
)
// GetRoles 获取所有角色
func GetRoles() ([]models.Role, error) {
query := "SELECT id, name, description, created_at, updated_at FROM roles"
rows, err := config.DB.Query(query)
if err != nil {
log.Printf("Error getting roles: %v", err)
return nil, err
}
defer rows.Close()
var roles []models.Role
for rows.Next() {
var role models.Role
if err := rows.Scan(&role.ID, &role.Name, &role.Description, &role.CreatedAt, &role.UpdatedAt); err != nil {
log.Printf("Error scanning role: %v", err)
continue
}
// 获取权限
permissions, _ := GetPermissionsByRoleID(role.ID)
role.Permissions = permissions
roles = append(roles, role)
}
return roles, nil
}
// GetRoleByID 根据ID获取角色
func GetRoleByID(id uint) (*models.Role, error) {
query := "SELECT id, name, description, created_at, updated_at FROM roles WHERE id = ?"
row := config.DB.QueryRow(query, id)
var role models.Role
if err := row.Scan(&role.ID, &role.Name, &role.Description, &role.CreatedAt, &role.UpdatedAt); err != nil {
log.Printf("Error getting role by ID: %v", err)
return nil, err
}
// 获取权限
permissions, _ := GetPermissionsByRoleID(role.ID)
role.Permissions = permissions
return &role, nil
}
// GetRoleByName 根据名称获取角色
func GetRoleByName(name string) (*models.Role, error) {
query := "SELECT id, name, description, created_at, updated_at FROM roles WHERE name = ?"
row := config.DB.QueryRow(query, name)
var role models.Role
if err := row.Scan(&role.ID, &role.Name, &role.Description, &role.CreatedAt, &role.UpdatedAt); err != nil {
log.Printf("Error getting role by name: %v", err)
return nil, err
}
return &role, nil
}
// CreateRole 创建角色
func CreateRole(role *models.Role) error {
query := "INSERT INTO roles (name, description, created_at, updated_at) VALUES (?, ?, NOW(), NOW())"
result, err := config.DB.Exec(query, role.Name, role.Description)
if err != nil {
log.Printf("Error creating role: %v", err)
return err
}
id, err := result.LastInsertId()
if err != nil {
return err
}
role.ID = uint(id)
role.CreatedAt = time.Now()
role.UpdatedAt = time.Now()
return nil
}
// UpdateRole 更新角色
func UpdateRole(role *models.Role) error {
query := "UPDATE roles SET name = ?, description = ?, updated_at = NOW() WHERE id = ?"
_, err := config.DB.Exec(query, role.Name, role.Description, role.ID)
if err != nil {
log.Printf("Error updating role: %v", err)
return err
}
return nil
}
// DeleteRole 删除角色
func DeleteRole(id uint) error {
query := "DELETE FROM roles WHERE id = ?"
_, err := config.DB.Exec(query, id)
if err != nil {
log.Printf("Error deleting role: %v", err)
return err
}
return nil
}
// AssignPermissionsToRole 给角色分配权限
func AssignPermissionsToRole(roleID uint, permissionIDs []uint) error {
// 开启事务
tx, err := config.DB.Begin()
if err != nil {
return err
}
// 先删除旧权限
_, err = tx.Exec("DELETE FROM role_permissions WHERE role_id = ?", roleID)
if err != nil {
tx.Rollback()
return err
}
// 插入新权限
stmt, err := tx.Prepare("INSERT INTO role_permissions (role_id, permission_id) VALUES (?, ?)")
if err != nil {
tx.Rollback()
return err
}
defer stmt.Close()
for _, permID := range permissionIDs {
_, err = stmt.Exec(roleID, permID)
if err != nil {
tx.Rollback()
return err
}
}
return tx.Commit()
}
// BuildRoleResponse 构建角色响应
func BuildRoleResponse(role *models.Role) *models.RoleResponse {
return &models.RoleResponse{
ID: role.ID,
Name: role.Name,
Description: role.Description,
Permissions: BuildPermissionsResponse(role.Permissions),
CreatedAt: role.CreatedAt.Format("2006-01-02 15:04:05"),
UpdatedAt: role.UpdatedAt.Format("2006-01-02 15:04:05"),
}
}
// BuildRolesResponse 构建角色列表响应
func BuildRolesResponse(roles []models.Role) []models.RoleResponse {
var responses []models.RoleResponse
for _, role := range roles {
responses = append(responses, *BuildRoleResponse(&role))
}
return responses
}

View File

@@ -0,0 +1,144 @@
package repositories
import (
"database/sql"
"log"
"github.com/niangaodev/art-code/config"
"github.com/niangaodev/art-code/models"
)
// GetSettings 获取所有系统配置
func GetSettings() ([]models.Setting, error) {
query := "SELECT id, key_name, value, description, created_at, updated_at FROM settings ORDER BY key_name"
rows, err := config.DB.Query(query)
if err != nil {
log.Printf("Error querying settings: %v", err)
return nil, err
}
defer rows.Close()
var settings []models.Setting
for rows.Next() {
var setting models.Setting
if err := rows.Scan(
&setting.ID,
&setting.KeyName,
&setting.Value,
&setting.Description,
&setting.CreatedAt,
&setting.UpdatedAt,
); err != nil {
log.Printf("Error scanning setting: %v", err)
continue
}
settings = append(settings, setting)
}
return settings, nil
}
// GetSettingByKey 根据键名获取系统配置
func GetSettingByKey(keyName string) (*models.Setting, error) {
query := "SELECT id, key_name, value, description, created_at, updated_at FROM settings WHERE key_name = ?"
row := config.DB.QueryRow(query, keyName)
var setting models.Setting
if err := row.Scan(
&setting.ID,
&setting.KeyName,
&setting.Value,
&setting.Description,
&setting.CreatedAt,
&setting.UpdatedAt,
); err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
log.Printf("Error scanning setting by key: %v", err)
return nil, err
}
return &setting, nil
}
// UpdateSetting 更新系统配置
func UpdateSetting(setting *models.Setting) error {
query := `
UPDATE settings SET value = ?, description = ?, updated_at = NOW()
WHERE key_name = ?
`
_, err := config.DB.Exec(
query,
setting.Value,
setting.Description,
setting.KeyName,
)
if err != nil {
log.Printf("Error updating setting: %v", err)
return err
}
return nil
}
// CreateSetting 创建系统配置
func CreateSetting(setting *models.Setting) error {
query := `
INSERT INTO settings (key_name, value, description, created_at, updated_at)
VALUES (?, ?, ?, NOW(), NOW())
`
result, err := config.DB.Exec(
query,
setting.KeyName,
setting.Value,
setting.Description,
)
if err != nil {
log.Printf("Error creating setting: %v", err)
return err
}
// 获取自增ID
id, err := result.LastInsertId()
if err != nil {
log.Printf("Error getting last insert ID: %v", err)
return err
}
setting.ID = uint(id)
return nil
}
// DeleteSetting 删除系统配置
func DeleteSetting(keyName string) error {
query := "DELETE FROM settings WHERE key_name = ?"
_, err := config.DB.Exec(query, keyName)
if err != nil {
log.Printf("Error deleting setting: %v", err)
return err
}
return nil
}
// BuildSettingResponse 构建系统配置响应
func BuildSettingResponse(setting *models.Setting) *models.SettingResponse {
return &models.SettingResponse{
ID: setting.ID,
KeyName: setting.KeyName,
Value: setting.Value,
Description: setting.Description,
CreatedAt: setting.CreatedAt.Format("2006-01-02 15:04:05"),
UpdatedAt: setting.UpdatedAt.Format("2006-01-02 15:04:05"),
}
}
// BuildSettingsResponse 构建系统配置列表响应
func BuildSettingsResponse(settings []models.Setting) []models.SettingResponse {
var responses []models.SettingResponse
for _, setting := range settings {
responses = append(responses, *BuildSettingResponse(&setting))
}
return responses
}

View File

@@ -0,0 +1,163 @@
package repositories
import (
"database/sql"
"log"
"github.com/niangaodev/art-code/config"
"github.com/niangaodev/art-code/models"
)
// GetSnippets 获取所有代码片段
func GetSnippets() ([]models.Snippet, error) {
query := "SELECT id, title, code, type, description, view_count, created_at, updated_at FROM snippets ORDER BY created_at DESC"
rows, err := config.DB.Query(query)
if err != nil {
log.Printf("Error querying snippets: %v", err)
return nil, err
}
defer rows.Close()
var snippets []models.Snippet
for rows.Next() {
var snippet models.Snippet
if err := rows.Scan(
&snippet.ID,
&snippet.Title,
&snippet.Code,
&snippet.Type,
&snippet.Description,
&snippet.ViewCount,
&snippet.CreatedAt,
&snippet.UpdatedAt,
); err != nil {
log.Printf("Error scanning snippet: %v", err)
continue
}
snippets = append(snippets, snippet)
}
return snippets, nil
}
// GetSnippetByID 根据ID获取代码片段
func GetSnippetByID(id string) (*models.Snippet, error) {
query := "SELECT id, title, code, type, description, view_count, created_at, updated_at FROM snippets WHERE id = ?"
row := config.DB.QueryRow(query, id)
var snippet models.Snippet
if err := row.Scan(
&snippet.ID,
&snippet.Title,
&snippet.Code,
&snippet.Type,
&snippet.Description,
&snippet.ViewCount,
&snippet.CreatedAt,
&snippet.UpdatedAt,
); err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
log.Printf("Error scanning snippet by ID: %v", err)
return nil, err
}
// 更新查看次数
updateViewCountQuery := "UPDATE snippets SET view_count = view_count + 1 WHERE id = ?"
if _, err := config.DB.Exec(updateViewCountQuery, id); err != nil {
log.Printf("Error updating snippet view count: %v", err)
}
return &snippet, nil
}
// BuildSnippetResponse 构建代码片段响应
func BuildSnippetResponse(snippet *models.Snippet) *models.SnippetResponse {
return &models.SnippetResponse{
ID: snippet.ID,
Title: snippet.Title,
Code: snippet.Code,
Type: snippet.Type,
}
}
// BuildSnippetsResponse 构建代码片段列表响应
func BuildSnippetsResponse(snippets []models.Snippet) []models.SnippetResponse {
var responses []models.SnippetResponse
for _, snippet := range snippets {
responses = append(responses, *BuildSnippetResponse(&snippet))
}
return responses
}
// CreateSnippet 创建代码片段
func CreateSnippet(snippet *models.Snippet) error {
query := `
INSERT INTO snippets (id, title, code, type, description, view_count, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, 0, NOW(), NOW())
`
_, err := config.DB.Exec(
query,
snippet.ID,
snippet.Title,
snippet.Code,
snippet.Type,
snippet.Description,
)
if err != nil {
log.Printf("Error creating snippet: %v", err)
return err
}
return nil
}
// UpdateSnippet 更新代码片段
func UpdateSnippet(snippet *models.Snippet) error {
query := `
UPDATE snippets SET title = ?, code = ?, type = ?, description = ?, updated_at = NOW()
WHERE id = ?
`
_, err := config.DB.Exec(
query,
snippet.Title,
snippet.Code,
snippet.Type,
snippet.Description,
snippet.ID,
)
if err != nil {
log.Printf("Error updating snippet: %v", err)
return err
}
return nil
}
// DeleteSnippet 删除代码片段
func DeleteSnippet(id string) error {
query := "DELETE FROM snippets WHERE id = ?"
_, err := config.DB.Exec(query, id)
if err != nil {
log.Printf("Error deleting snippet: %v", err)
return err
}
return nil
}
// GetSnippetCount 获取代码片段总数
func GetSnippetCount() (int, error) {
var count int
query := "SELECT COUNT(*) FROM snippets"
row := config.DB.QueryRow(query)
err := row.Scan(&count)
if err != nil {
log.Printf("Error getting snippet count: %v", err)
return 0, err
}
return count, nil
}

View File

@@ -0,0 +1,264 @@
package repositories
import (
"database/sql"
"log"
"github.com/niangaodev/art-code/config"
"github.com/niangaodev/art-code/models"
)
// GetTags 获取所有标签
func GetTags() ([]models.Tag, error) {
query := "SELECT id, name, slug, created_at, updated_at FROM tags ORDER BY name ASC"
rows, err := config.DB.Query(query)
if err != nil {
log.Printf("Error querying tags: %v", err)
return nil, err
}
defer rows.Close()
var tags []models.Tag
for rows.Next() {
var tag models.Tag
if err := rows.Scan(
&tag.ID,
&tag.Name,
&tag.Slug,
&tag.CreatedAt,
&tag.UpdatedAt,
); err != nil {
log.Printf("Error scanning tag: %v", err)
continue
}
tags = append(tags, tag)
}
return tags, nil
}
// GetTagByID 根据ID获取标签
func GetTagByID(id uint) (*models.Tag, error) {
query := "SELECT id, name, slug, created_at, updated_at FROM tags WHERE id = ?"
row := config.DB.QueryRow(query, id)
var tag models.Tag
if err := row.Scan(
&tag.ID,
&tag.Name,
&tag.Slug,
&tag.CreatedAt,
&tag.UpdatedAt,
); err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
log.Printf("Error scanning tag by ID: %v", err)
return nil, err
}
return &tag, nil
}
// GetTagBySlug 根据Slug获取标签
func GetTagBySlug(slug string) (*models.Tag, error) {
query := "SELECT id, name, slug, created_at, updated_at FROM tags WHERE slug = ?"
row := config.DB.QueryRow(query, slug)
var tag models.Tag
if err := row.Scan(
&tag.ID,
&tag.Name,
&tag.Slug,
&tag.CreatedAt,
&tag.UpdatedAt,
); err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
log.Printf("Error scanning tag by slug: %v", err)
return nil, err
}
return &tag, nil
}
// CreateTag 创建标签
func CreateTag(tag *models.Tag) error {
query := `
INSERT INTO tags (name, slug, created_at, updated_at)
VALUES (?, ?, NOW(), NOW())
`
result, err := config.DB.Exec(
query,
tag.Name,
tag.Slug,
)
if err != nil {
log.Printf("Error creating tag: %v", err)
return err
}
// 获取自增ID
id, err := result.LastInsertId()
if err != nil {
log.Printf("Error getting last insert ID: %v", err)
return err
}
tag.ID = uint(id)
return nil
}
// UpdateTag 更新标签
func UpdateTag(tag *models.Tag) error {
query := `
UPDATE tags SET name = ?, slug = ?, updated_at = NOW()
WHERE id = ?
`
_, err := config.DB.Exec(
query,
tag.Name,
tag.Slug,
tag.ID,
)
if err != nil {
log.Printf("Error updating tag: %v", err)
return err
}
return nil
}
// DeleteTag 删除标签
func DeleteTag(id uint) error {
// 先删除关联的文章标签关系
query := "DELETE FROM post_tags WHERE tag_id = ?"
_, err := config.DB.Exec(query, id)
if err != nil {
log.Printf("Error deleting post-tag relationships: %v", err)
return err
}
// 再删除标签
query = "DELETE FROM tags WHERE id = ?"
_, err = config.DB.Exec(query, id)
if err != nil {
log.Printf("Error deleting tag: %v", err)
return err
}
return nil
}
// GetTagsByPostID 根据文章ID获取标签
func GetTagsByPostID(postID string) ([]models.Tag, error) {
query := `
SELECT t.id, t.name, t.slug, t.created_at, t.updated_at
FROM tags t
JOIN post_tags pt ON t.id = pt.tag_id
WHERE pt.post_id = ?
ORDER BY t.name ASC
`
rows, err := config.DB.Query(query, postID)
if err != nil {
log.Printf("Error querying tags by post ID: %v", err)
return nil, err
}
defer rows.Close()
var tags []models.Tag
for rows.Next() {
var tag models.Tag
if err := rows.Scan(
&tag.ID,
&tag.Name,
&tag.Slug,
&tag.CreatedAt,
&tag.UpdatedAt,
); err != nil {
log.Printf("Error scanning tag: %v", err)
continue
}
tags = append(tags, tag)
}
return tags, nil
}
// AddTagToPost 为文章添加标签
func AddTagToPost(postID string, tagID uint) error {
query := `
INSERT IGNORE INTO post_tags (post_id, tag_id, created_at)
VALUES (?, ?, NOW())
`
_, err := config.DB.Exec(query, postID, tagID)
if err != nil {
log.Printf("Error adding tag to post: %v", err)
return err
}
return nil
}
// RemoveTagFromPost 从文章移除标签
func RemoveTagFromPost(postID string, tagID uint) error {
query := "DELETE FROM post_tags WHERE post_id = ? AND tag_id = ?"
_, err := config.DB.Exec(query, postID, tagID)
if err != nil {
log.Printf("Error removing tag from post: %v", err)
return err
}
return nil
}
// GetPostsByTagID 根据标签ID获取文章
func GetPostsByTagID(tagID uint) ([]models.Post, error) {
query := `
SELECT p.id, p.title, p.category, p.date, p.excerpt, p.content, p.read_count, p.is_published, p.created_at, p.updated_at
FROM posts p
JOIN post_tags pt ON p.id = pt.post_id
WHERE pt.tag_id = ? AND p.is_published = 1
ORDER BY p.date DESC
`
rows, err := config.DB.Query(query, tagID)
if err != nil {
log.Printf("Error querying posts by tag ID: %v", err)
return nil, err
}
defer rows.Close()
var posts []models.Post
for rows.Next() {
var post models.Post
if err := rows.Scan(
&post.ID,
&post.Title,
&post.Category,
&post.Date,
&post.Excerpt,
&post.Content,
&post.ReadCount,
&post.IsPublished,
&post.CreatedAt,
&post.UpdatedAt,
); err != nil {
log.Printf("Error scanning post: %v", err)
continue
}
posts = append(posts, post)
}
return posts, nil
}
// BuildTagsResponse 构建标签列表响应
func BuildTagsResponse(tags []models.Tag) []models.Tag {
return tags
}
// BuildTagResponse 构建标签响应
func BuildTagResponse(tag *models.Tag) *models.Tag {
return tag
}

View File

@@ -0,0 +1,293 @@
package repositories
import (
"database/sql"
"log"
"github.com/niangaodev/art-code/config"
"github.com/niangaodev/art-code/models"
)
// GetUserByUsername 根据用户名获取用户
func GetUserByUsername(username string) (*models.User, error) {
query := `
SELECT u.id, u.username, u.email, u.password_hash, u.role_id, COALESCE(r.name, u.role), u.is_active, u.created_at, u.updated_at
FROM users u
LEFT JOIN roles r ON u.role_id = r.id
WHERE u.username = ?
`
row := config.DB.QueryRow(query, username)
var user models.User
var roleID sql.NullInt64 // Handle nullable role_id
var roleName sql.NullString // Handle nullable role name
if err := row.Scan(
&user.ID,
&user.Username,
&user.Email,
&user.PasswordHash,
&roleID,
&roleName,
&user.IsActive,
&user.CreatedAt,
&user.UpdatedAt,
); err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
log.Printf("Error scanning user by username: %v", err)
return nil, err
}
if roleID.Valid {
user.RoleID = uint(roleID.Int64)
}
if roleName.Valid {
user.Role = roleName.String
}
return &user, nil
}
// GetUserByID 根据ID获取用户
func GetUserByID(id uint) (*models.User, error) {
query := `
SELECT u.id, u.username, u.email, u.password_hash, u.role_id, COALESCE(r.name, u.role), u.is_active, u.created_at, u.updated_at
FROM users u
LEFT JOIN roles r ON u.role_id = r.id
WHERE u.id = ?
`
row := config.DB.QueryRow(query, id)
var user models.User
var roleID sql.NullInt64
var roleName sql.NullString
if err := row.Scan(
&user.ID,
&user.Username,
&user.Email,
&user.PasswordHash,
&roleID,
&roleName,
&user.IsActive,
&user.CreatedAt,
&user.UpdatedAt,
); err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
log.Printf("Error scanning user by ID: %v", err)
return nil, err
}
if roleID.Valid {
user.RoleID = uint(roleID.Int64)
}
if roleName.Valid {
user.Role = roleName.String
}
return &user, nil
}
// GetUsers 获取所有用户
func GetUsers() ([]models.User, error) {
query := `
SELECT u.id, u.username, u.email, u.password_hash, u.role_id, COALESCE(r.name, u.role), u.is_active, u.created_at, u.updated_at
FROM users u
LEFT JOIN roles r ON u.role_id = r.id
ORDER BY u.created_at DESC
`
rows, err := config.DB.Query(query)
if err != nil {
log.Printf("Error querying users: %v", err)
return nil, err
}
defer rows.Close()
var users []models.User
for rows.Next() {
var user models.User
var roleID sql.NullInt64
var roleName sql.NullString
if err := rows.Scan(
&user.ID,
&user.Username,
&user.Email,
&user.PasswordHash,
&roleID,
&roleName,
&user.IsActive,
&user.CreatedAt,
&user.UpdatedAt,
); err != nil {
log.Printf("Error scanning user: %v", err)
continue
}
if roleID.Valid {
user.RoleID = uint(roleID.Int64)
}
if roleName.Valid {
user.Role = roleName.String
}
users = append(users, user)
}
return users, nil
}
// CreateUser 创建用户
func CreateUser(user *models.User) error {
// 如果提供了RoleID确保它有效。如果没有RoleID但有Role name尝试查找RoleID
if user.RoleID == 0 && user.Role != "" {
role, err := GetRoleByName(user.Role)
if err == nil && role != nil {
user.RoleID = role.ID
}
}
query := `
INSERT INTO users (username, email, password_hash, role_id, role, is_active, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, NOW(), NOW())
`
var roleID interface{}
if user.RoleID != 0 {
roleID = user.RoleID
} else {
roleID = nil
}
result, err := config.DB.Exec(
query,
user.Username,
user.Email,
user.PasswordHash,
roleID,
user.Role, // Fallback legacy column
user.IsActive,
)
if err != nil {
log.Printf("Error creating user: %v", err)
return err
}
// 获取自增ID
id, err := result.LastInsertId()
if err != nil {
log.Printf("Error getting last insert ID: %v", err)
return err
}
user.ID = uint(id)
return nil
}
// UpdateUser 更新用户
func UpdateUser(user *models.User) error {
// 同样尝试解析RoleID
if user.RoleID == 0 && user.Role != "" {
role, err := GetRoleByName(user.Role)
if err == nil && role != nil {
user.RoleID = role.ID
}
}
query := `
UPDATE users SET username = ?, email = ?, role_id = ?, role = ?, is_active = ?, updated_at = NOW()
WHERE id = ?
`
var roleID interface{}
if user.RoleID != 0 {
roleID = user.RoleID
} else {
roleID = nil
}
_, err := config.DB.Exec(
query,
user.Username,
user.Email,
roleID,
user.Role,
user.IsActive,
user.ID,
)
if err != nil {
log.Printf("Error updating user: %v", err)
return err
}
return nil
}
// UpdateUserPassword 更新用户密码
func UpdateUserPassword(id uint, passwordHash string) error {
query := `
UPDATE users SET password_hash = ?, updated_at = NOW()
WHERE id = ?
`
_, err := config.DB.Exec(query, passwordHash, id)
if err != nil {
log.Printf("Error updating user password: %v", err)
return err
}
return nil
}
// DeleteUser 删除用户
func DeleteUser(id uint) error {
query := "DELETE FROM users WHERE id = ?"
_, err := config.DB.Exec(query, id)
if err != nil {
log.Printf("Error deleting user: %v", err)
return err
}
return nil
}
// GetUserCount 获取用户总数
func GetUserCount() (int, error) {
var count int
query := "SELECT COUNT(*) FROM users"
row := config.DB.QueryRow(query)
err := row.Scan(&count)
if err != nil {
log.Printf("Error getting user count: %v", err)
return 0, err
}
return count, nil
}
// BuildUserResponse 构建用户响应
func BuildUserResponse(user *models.User) *models.UserResponse {
return &models.UserResponse{
ID: user.ID,
Username: user.Username,
Email: user.Email,
RoleID: user.RoleID,
Role: user.Role,
IsActive: user.IsActive,
CreatedAt: user.CreatedAt.Format("2006-01-02 15:04:05"),
UpdatedAt: user.UpdatedAt.Format("2006-01-02 15:04:05"),
}
}
// BuildUsersResponse 构建用户列表响应
func BuildUsersResponse(users []models.User) []models.UserResponse {
var responses []models.UserResponse
for _, user := range users {
responses = append(responses, *BuildUserResponse(&user))
}
return responses
}

View File

@@ -0,0 +1,301 @@
package repositories
import (
"database/sql"
"log"
"github.com/niangaodev/art-code/config"
"github.com/niangaodev/art-code/models"
)
// GetWorks 获取所有作品
func GetWorks() ([]models.Work, error) {
query := "SELECT id, title, category, year, hero_img, description, is_featured, created_at, updated_at FROM works"
rows, err := config.DB.Query(query)
if err != nil {
log.Printf("Error querying works: %v", err)
return nil, err
}
defer rows.Close()
var works []models.Work
for rows.Next() {
var work models.Work
if err := rows.Scan(
&work.ID,
&work.Title,
&work.Category,
&work.Year,
&work.HeroImg,
&work.Description,
&work.IsFeatured,
&work.CreatedAt,
&work.UpdatedAt,
); err != nil {
log.Printf("Error scanning work: %v", err)
continue
}
works = append(works, work)
}
return works, nil
}
// GetWorkByID 根据ID获取作品
func GetWorkByID(id string) (*models.Work, error) {
query := "SELECT id, title, category, year, hero_img, description, is_featured, created_at, updated_at FROM works WHERE id = ?"
row := config.DB.QueryRow(query, id)
var work models.Work
if err := row.Scan(
&work.ID,
&work.Title,
&work.Category,
&work.Year,
&work.HeroImg,
&work.Description,
&work.IsFeatured,
&work.CreatedAt,
&work.UpdatedAt,
); err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
log.Printf("Error scanning work by ID: %v", err)
return nil, err
}
return &work, nil
}
// GetWorkTechStack 获取作品的技术栈
func GetWorkTechStack(workID string) ([]models.WorkTechStack, error) {
query := "SELECT id, work_id, category, item, created_at FROM work_tech_stack WHERE work_id = ?"
rows, err := config.DB.Query(query, workID)
if err != nil {
log.Printf("Error querying work tech stack: %v", err)
return nil, err
}
defer rows.Close()
var techStacks []models.WorkTechStack
for rows.Next() {
var techStack models.WorkTechStack
if err := rows.Scan(
&techStack.ID,
&techStack.WorkID,
&techStack.Category,
&techStack.Item,
&techStack.CreatedAt,
); err != nil {
log.Printf("Error scanning work tech stack: %v", err)
continue
}
techStacks = append(techStacks, techStack)
}
return techStacks, nil
}
// GetWorkGallery 获取作品的图库
func GetWorkGallery(workID string) ([]models.WorkGallery, error) {
query := "SELECT id, work_id, image_url, sort_order, description, created_at FROM work_gallery WHERE work_id = ? ORDER BY sort_order"
rows, err := config.DB.Query(query, workID)
if err != nil {
log.Printf("Error querying work gallery: %v", err)
return nil, err
}
defer rows.Close()
var galleries []models.WorkGallery
for rows.Next() {
var gallery models.WorkGallery
if err := rows.Scan(
&gallery.ID,
&gallery.WorkID,
&gallery.ImageURL,
&gallery.SortOrder,
&gallery.Description,
&gallery.CreatedAt,
); err != nil {
log.Printf("Error scanning work gallery: %v", err)
continue
}
galleries = append(galleries, gallery)
}
return galleries, nil
}
// BuildWorkResponse 构建作品响应,包含关联数据
func BuildWorkResponse(work *models.Work) (*models.WorkResponse, error) {
// 获取技术栈
techStacks, err := GetWorkTechStack(work.ID)
if err != nil {
return nil, err
}
// 按类别分组技术栈
techStackMap := make(map[string][]string)
for _, ts := range techStacks {
techStackMap[ts.Category] = append(techStackMap[ts.Category], ts.Item)
}
// 转换为前端期望的格式
var techStackResponse []map[string]interface{}
for category, items := range techStackMap {
techStackResponse = append(techStackResponse, map[string]interface{}{
"category": category,
"items": items,
})
}
// 获取图库
galleries, err := GetWorkGallery(work.ID)
if err != nil {
return nil, err
}
// 提取图片URL
var galleryImages []string
for _, g := range galleries {
galleryImages = append(galleryImages, g.ImageURL)
}
// 获取下一个作品ID
nextWorkID, err := GetNextWorkID(work.ID)
if err != nil {
log.Printf("Error getting next work ID: %v", err)
nextWorkID = ""
}
return &models.WorkResponse{
ID: work.ID,
Title: work.Title,
Category: work.Category,
Year: work.Year,
HeroImg: work.HeroImg,
Desc: work.Description,
TechStack: techStackResponse,
Gallery: galleryImages,
Links: map[string]interface{}{
"live": "#",
},
Next: nextWorkID,
}, nil
}
// GetNextWorkID 获取下一个作品ID简单实现实际可能需要更复杂的逻辑
func GetNextWorkID(currentID string) (string, error) {
// 获取所有作品ID
query := "SELECT id FROM works"
rows, err := config.DB.Query(query)
if err != nil {
return "", err
}
defer rows.Close()
var ids []string
for rows.Next() {
var id string
if err := rows.Scan(&id); err != nil {
continue
}
ids = append(ids, id)
}
// 找到当前ID的索引
index := -1
for i, id := range ids {
if id == currentID {
index = i
break
}
}
// 如果没找到或者是最后一个,返回第一个
if index == -1 || index == len(ids)-1 {
if len(ids) > 0 {
return ids[0], nil
}
return "", nil
}
// 返回下一个
return ids[index+1], nil
}
// CreateWork 创建作品
func CreateWork(work *models.Work) error {
query := `
INSERT INTO works (id, title, category, year, hero_img, description, is_featured, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, NOW(), NOW())
`
_, err := config.DB.Exec(
query,
work.ID,
work.Title,
work.Category,
work.Year,
work.HeroImg,
work.Description,
work.IsFeatured,
)
if err != nil {
log.Printf("Error creating work: %v", err)
return err
}
return nil
}
// UpdateWork 更新作品
func UpdateWork(work *models.Work) error {
query := `
UPDATE works SET title = ?, category = ?, year = ?, hero_img = ?, description = ?, is_featured = ?, updated_at = NOW()
WHERE id = ?
`
_, err := config.DB.Exec(
query,
work.Title,
work.Category,
work.Year,
work.HeroImg,
work.Description,
work.IsFeatured,
work.ID,
)
if err != nil {
log.Printf("Error updating work: %v", err)
return err
}
return nil
}
// DeleteWork 删除作品
func DeleteWork(id string) error {
query := "DELETE FROM works WHERE id = ?"
_, err := config.DB.Exec(query, id)
if err != nil {
log.Printf("Error deleting work: %v", err)
return err
}
return nil
}
// GetWorkCount 获取作品总数
func GetWorkCount() (int, error) {
var count int
query := "SELECT COUNT(*) FROM works"
row := config.DB.QueryRow(query)
err := row.Scan(&count)
if err != nil {
log.Printf("Error getting work count: %v", err)
return 0, err
}
return count, nil
}