Initial commit: GovAI 政务AI平台

This commit is contained in:
freedakgmail
2026-06-15 23:48:37 +08:00
commit 0f490f72a9
245 changed files with 51669 additions and 0 deletions
+122
View File
@@ -0,0 +1,122 @@
-- name: CreateApplication :one
INSERT INTO applications (
name, slug, description, long_description, icon_url,
category_id, creator_id, dept_id,
dify_app_id, dify_app_type, dify_api_key,
app_config, welcome_message, suggested_prompts,
max_tokens, temperature, status, visibility, is_template
) VALUES (
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19
) RETURNING *;
-- name: GetApplicationByID :one
SELECT * FROM applications WHERE id = $1;
-- name: GetApplicationBySlug :one
SELECT * FROM applications WHERE slug = $1;
-- name: UpdateApplication :one
UPDATE applications
SET name = COALESCE(sqlc.narg('name'), name),
description = COALESCE(sqlc.narg('description'), description),
long_description = COALESCE(sqlc.narg('long_description'), long_description),
icon_url = COALESCE(sqlc.narg('icon_url'), icon_url),
category_id = COALESCE(sqlc.narg('category_id'), category_id),
app_config = COALESCE(sqlc.narg('app_config'), app_config),
welcome_message = COALESCE(sqlc.narg('welcome_message'), welcome_message),
suggested_prompts = COALESCE(sqlc.narg('suggested_prompts'), suggested_prompts),
max_tokens = COALESCE(sqlc.narg('max_tokens'), max_tokens),
temperature = COALESCE(sqlc.narg('temperature'), temperature),
visibility = COALESCE(sqlc.narg('visibility'), visibility)
WHERE id = $1
RETURNING *;
-- name: UpdateApplicationStatus :exec
UPDATE applications SET status = $2 WHERE id = $1;
-- name: DeleteApplication :exec
DELETE FROM applications WHERE id = $1 AND status = 'draft';
-- name: ListStoreApps :many
SELECT a.*, c.name as category_name, c.slug as category_slug, u.name as creator_name
FROM applications a
LEFT JOIN categories c ON a.category_id = c.id
LEFT JOIN users u ON a.creator_id = u.id
WHERE a.status = 'approved'
AND a.visibility = 'public'
AND (sqlc.narg('category_slug')::VARCHAR IS NULL OR c.slug = sqlc.narg('category_slug'))
AND (sqlc.narg('search')::VARCHAR IS NULL
OR to_tsvector('simple', a.name || ' ' || COALESCE(a.description, ''))
@@ plainto_tsquery('simple', sqlc.narg('search')))
ORDER BY
CASE WHEN sqlc.narg('sort')::VARCHAR = 'popular' THEN a.usage_count END DESC,
CASE WHEN sqlc.narg('sort')::VARCHAR = 'rating' THEN a.avg_rating END DESC,
CASE WHEN sqlc.narg('sort')::VARCHAR IS NULL OR sqlc.narg('sort') = 'latest' THEN EXTRACT(EPOCH FROM a.published_at) END DESC
LIMIT $1 OFFSET $2;
-- name: CountStoreApps :one
SELECT COUNT(*) FROM applications a
LEFT JOIN categories c ON a.category_id = c.id
WHERE a.status = 'approved'
AND a.visibility = 'public'
AND (sqlc.narg('category_slug')::VARCHAR IS NULL OR c.slug = sqlc.narg('category_slug'))
AND (sqlc.narg('search')::VARCHAR IS NULL
OR to_tsvector('simple', a.name || ' ' || COALESCE(a.description, ''))
@@ plainto_tsquery('simple', sqlc.narg('search')));
-- name: ListFeaturedApps :many
SELECT a.*, c.name as category_name, u.name as creator_name
FROM applications a
LEFT JOIN categories c ON a.category_id = c.id
LEFT JOIN users u ON a.creator_id = u.id
WHERE a.is_featured = true AND a.status = 'approved' AND a.visibility = 'public'
ORDER BY a.usage_count DESC
LIMIT $1;
-- name: ListTopApps :many
SELECT a.*, c.name as category_name, u.name as creator_name
FROM applications a
LEFT JOIN categories c ON a.category_id = c.id
LEFT JOIN users u ON a.creator_id = u.id
WHERE a.status = 'approved' AND a.visibility = 'public'
ORDER BY a.usage_count DESC
LIMIT $1;
-- name: ListCreatorApps :many
SELECT a.*, c.name as category_name
FROM applications a
LEFT JOIN categories c ON a.category_id = c.id
WHERE a.creator_id = $1
ORDER BY a.updated_at DESC
LIMIT $2 OFFSET $3;
-- name: ListTemplates :many
SELECT a.*, c.name as category_name
FROM applications a
LEFT JOIN categories c ON a.category_id = c.id
WHERE a.is_template = true AND a.status = 'approved'
ORDER BY a.usage_count DESC;
-- name: IncrementUsageCount :exec
UPDATE applications SET usage_count = usage_count + 1 WHERE id = $1;
-- name: UpdateFavoriteCount :exec
UPDATE applications SET favorite_count = favorite_count + $2 WHERE id = $1;
-- name: UpdateAppRating :exec
UPDATE applications
SET avg_rating = $2, rating_count = $3
WHERE id = $1;
-- name: ListAllApps :many
SELECT a.*, c.name as category_name, u.name as creator_name
FROM applications a
LEFT JOIN categories c ON a.category_id = c.id
LEFT JOIN users u ON a.creator_id = u.id
WHERE (sqlc.narg('status')::VARCHAR IS NULL OR a.status = sqlc.narg('status'))
ORDER BY a.created_at DESC
LIMIT $1 OFFSET $2;
-- name: CountAllApps :one
SELECT COUNT(*) FROM applications
WHERE (sqlc.narg('status')::VARCHAR IS NULL OR status = sqlc.narg('status'));
+23
View File
@@ -0,0 +1,23 @@
-- name: CreateAuditLog :exec
INSERT INTO audit_logs (user_id, action, resource_type, resource_id, details, ip_address, user_agent)
VALUES ($1, $2, $3, $4, $5, $6, $7);
-- name: ListAuditLogs :many
SELECT al.*, u.name as user_name
FROM audit_logs al
LEFT JOIN users u ON al.user_id = u.id
WHERE (sqlc.narg('user_id')::UUID IS NULL OR al.user_id = sqlc.narg('user_id'))
AND (sqlc.narg('action')::VARCHAR IS NULL OR al.action = sqlc.narg('action'))
AND (sqlc.narg('resource_type')::VARCHAR IS NULL OR al.resource_type = sqlc.narg('resource_type'))
AND (sqlc.narg('start_time')::TIMESTAMPTZ IS NULL OR al.created_at >= sqlc.narg('start_time'))
AND (sqlc.narg('end_time')::TIMESTAMPTZ IS NULL OR al.created_at <= sqlc.narg('end_time'))
ORDER BY al.created_at DESC
LIMIT $1 OFFSET $2;
-- name: CountAuditLogs :one
SELECT COUNT(*) FROM audit_logs
WHERE (sqlc.narg('user_id')::UUID IS NULL OR user_id = sqlc.narg('user_id'))
AND (sqlc.narg('action')::VARCHAR IS NULL OR action = sqlc.narg('action'))
AND (sqlc.narg('resource_type')::VARCHAR IS NULL OR resource_type = sqlc.narg('resource_type'))
AND (sqlc.narg('start_time')::TIMESTAMPTZ IS NULL OR created_at >= sqlc.narg('start_time'))
AND (sqlc.narg('end_time')::TIMESTAMPTZ IS NULL OR created_at <= sqlc.narg('end_time'));
+10
View File
@@ -0,0 +1,10 @@
-- name: ListCategories :many
SELECT * FROM categories
WHERE status = 'active'
ORDER BY sort_order ASC;
-- name: GetCategoryByID :one
SELECT * FROM categories WHERE id = $1;
-- name: GetCategoryBySlug :one
SELECT * FROM categories WHERE slug = $1;
@@ -0,0 +1,37 @@
-- name: AddFavorite :exec
INSERT INTO app_favorites (user_id, app_id) VALUES ($1, $2)
ON CONFLICT DO NOTHING;
-- name: RemoveFavorite :exec
DELETE FROM app_favorites WHERE user_id = $1 AND app_id = $2;
-- name: IsFavorited :one
SELECT EXISTS(SELECT 1 FROM app_favorites WHERE user_id = $1 AND app_id = $2);
-- name: ListUserFavorites :many
SELECT a.*, c.name as category_name
FROM app_favorites f
JOIN applications a ON f.app_id = a.id
LEFT JOIN categories c ON a.category_id = c.id
WHERE f.user_id = $1
ORDER BY f.created_at DESC
LIMIT $2 OFFSET $3;
-- name: UpsertRating :one
INSERT INTO app_ratings (app_id, user_id, score, comment)
VALUES ($1, $2, $3, $4)
ON CONFLICT (app_id, user_id)
DO UPDATE SET score = EXCLUDED.score, comment = EXCLUDED.comment
RETURNING *;
-- name: GetAppAvgRating :one
SELECT COALESCE(AVG(score)::REAL, 0) as avg_rating, COUNT(*) as rating_count
FROM app_ratings WHERE app_id = $1;
-- name: ListAppRatings :many
SELECT r.*, u.name as user_name, u.avatar_url as user_avatar
FROM app_ratings r
JOIN users u ON r.user_id = u.id
WHERE r.app_id = $1
ORDER BY r.created_at DESC
LIMIT $2 OFFSET $3;
+40
View File
@@ -0,0 +1,40 @@
-- name: CreateReview :one
INSERT INTO app_reviews (app_id, version, submitter_id, submit_comment)
VALUES ($1, $2, $3, $4)
RETURNING *;
-- name: GetReviewByID :one
SELECT * FROM app_reviews WHERE id = $1;
-- name: ListPendingReviews :many
SELECT r.*, a.name as app_name, a.description as app_description,
a.icon_url as app_icon, u.name as submitter_name
FROM app_reviews r
JOIN applications a ON r.app_id = a.id
JOIN users u ON r.submitter_id = u.id
WHERE r.status = 'pending'
ORDER BY r.submitted_at ASC
LIMIT $1 OFFSET $2;
-- name: CountPendingReviews :one
SELECT COUNT(*) FROM app_reviews WHERE status = 'pending';
-- name: ApproveReview :exec
UPDATE app_reviews
SET status = 'approved', reviewer_id = $2, review_comment = $3, reviewed_at = NOW()
WHERE id = $1;
-- name: RejectReview :exec
UPDATE app_reviews
SET status = 'rejected', reviewer_id = $2, review_comment = $3, reviewed_at = NOW()
WHERE id = $1;
-- name: WithdrawReview :exec
UPDATE app_reviews SET status = 'withdrawn' WHERE id = $1 AND status = 'pending';
-- name: ListAppReviews :many
SELECT r.*, u.name as reviewer_name
FROM app_reviews r
LEFT JOIN users u ON r.reviewer_id = u.id
WHERE r.app_id = $1
ORDER BY r.created_at DESC;
+34
View File
@@ -0,0 +1,34 @@
-- name: CreateUsageLog :one
INSERT INTO app_usage_logs (
app_id, user_id, dept_id, conversation_id, message_count,
prompt_tokens, completion_tokens, total_tokens, model_name,
estimated_cost, duration_ms, is_successful, error_message, client_type
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
RETURNING *;
-- name: GetRecentUsedApps :many
SELECT DISTINCT ON (a.id) a.*, c.name as category_name, l.created_at as last_used_at
FROM app_usage_logs l
JOIN applications a ON l.app_id = a.id
LEFT JOIN categories c ON a.category_id = c.id
WHERE l.user_id = $1
ORDER BY a.id, l.created_at DESC
LIMIT $2;
-- name: GetUserStats :one
SELECT
COUNT(*) as total_conversations,
COALESCE(SUM(total_tokens), 0) as total_tokens,
COALESCE(SUM(estimated_cost), 0) as total_cost
FROM app_usage_logs
WHERE user_id = $1
AND created_at >= $2;
-- name: GetOverviewStats :one
SELECT
(SELECT COUNT(*) FROM users WHERE status = 'active') as total_users,
(SELECT COUNT(*) FROM applications WHERE status = 'approved') as total_apps,
(SELECT COUNT(DISTINCT user_id) FROM app_usage_logs WHERE created_at >= $1) as active_users,
(SELECT COUNT(*) FROM app_usage_logs WHERE created_at >= $1) as total_conversations,
(SELECT COALESCE(SUM(total_tokens), 0) FROM app_usage_logs WHERE created_at >= $2) as monthly_tokens,
(SELECT COALESCE(SUM(estimated_cost), 0) FROM app_usage_logs WHERE created_at >= $2) as monthly_cost;
+52
View File
@@ -0,0 +1,52 @@
-- name: GetUserByID :one
SELECT * FROM users WHERE id = $1;
-- name: GetUserByEmail :one
SELECT * FROM users WHERE email = $1;
-- name: GetUserByEmployeeID :one
SELECT * FROM users WHERE employee_id = $1;
-- name: CreateUser :one
INSERT INTO users (name, email, password_hash, phone, avatar_url, role, status, sso_provider, sso_external_id)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
RETURNING *;
-- name: UpdateUserProfile :one
UPDATE users
SET name = COALESCE(sqlc.narg('name'), name),
phone = COALESCE(sqlc.narg('phone'), phone),
avatar_url = COALESCE(sqlc.narg('avatar_url'), avatar_url)
WHERE id = $1
RETURNING *;
-- name: UpdateUserRole :exec
UPDATE users SET role = $2 WHERE id = $1;
-- name: UpdateUserStatus :exec
UPDATE users SET status = $2 WHERE id = $1;
-- name: UpdateUserLogin :exec
UPDATE users
SET last_login_at = NOW(), login_count = login_count + 1
WHERE id = $1;
-- name: ListUsers :many
SELECT * FROM users
WHERE (sqlc.narg('role')::VARCHAR IS NULL OR role = sqlc.narg('role'))
AND (sqlc.narg('status')::VARCHAR IS NULL OR status = sqlc.narg('status'))
AND (sqlc.narg('search')::VARCHAR IS NULL
OR name ILIKE '%' || sqlc.narg('search') || '%'
OR email ILIKE '%' || sqlc.narg('search') || '%'
OR employee_id ILIKE '%' || sqlc.narg('search') || '%')
ORDER BY created_at DESC
LIMIT $1 OFFSET $2;
-- name: CountUsers :one
SELECT COUNT(*) FROM users
WHERE (sqlc.narg('role')::VARCHAR IS NULL OR role = sqlc.narg('role'))
AND (sqlc.narg('status')::VARCHAR IS NULL OR status = sqlc.narg('status'))
AND (sqlc.narg('search')::VARCHAR IS NULL
OR name ILIKE '%' || sqlc.narg('search') || '%'
OR email ILIKE '%' || sqlc.narg('search') || '%'
OR employee_id ILIKE '%' || sqlc.narg('search') || '%');