v1.2.97 - 完整同步
This commit is contained in:
parent
257ca40079
commit
4ae29eb4bf
|
|
@ -32,6 +32,3 @@ Thumbs.db
|
||||||
.vscode/
|
.vscode/
|
||||||
*.swp
|
*.swp
|
||||||
*.swo
|
*.swo
|
||||||
|
|
||||||
# 版本文件
|
|
||||||
VERSION
|
|
||||||
|
|
|
||||||
|
|
@ -89,13 +89,18 @@ def get_deal_list(
|
||||||
status: str = Query("active"),
|
status: str = Query("active"),
|
||||||
deal_date: Optional[str] = Query(None),
|
deal_date: Optional[str] = Query(None),
|
||||||
page: int = Query(1, ge=1),
|
page: int = Query(1, ge=1),
|
||||||
page_size: int = Query(20, ge=1, le=500),
|
page_size: int = Query(20, ge=1, le=1000),
|
||||||
|
user_only: bool = Query(False), # 是否只查看自己的
|
||||||
current_user: Optional = Depends(get_current_user),
|
current_user: Optional = Depends(get_current_user),
|
||||||
db: Session = Depends(get_db)
|
db: Session = Depends(get_db)
|
||||||
):
|
):
|
||||||
"""获取成交行情列表"""
|
"""获取成交行情列表"""
|
||||||
query = db.query(DealInfo).filter(DealInfo.status == status)
|
query = db.query(DealInfo).filter(DealInfo.status == status)
|
||||||
|
|
||||||
|
# 我的行情:只查看自己的(管理员也只看自己的)
|
||||||
|
if user_only and current_user:
|
||||||
|
query = query.filter(DealInfo.user_id == current_user.f99_90_id)
|
||||||
|
|
||||||
# 成交日期过滤
|
# 成交日期过滤
|
||||||
if deal_date:
|
if deal_date:
|
||||||
query = query.filter(DealInfo.deal_date == deal_date)
|
query = query.filter(DealInfo.deal_date == deal_date)
|
||||||
|
|
|
||||||
|
|
@ -59,13 +59,18 @@ class SeekInfoResponse(BaseModel):
|
||||||
def get_seek_list(
|
def get_seek_list(
|
||||||
status: str = Query("active"),
|
status: str = Query("active"),
|
||||||
page: int = Query(1, ge=1),
|
page: int = Query(1, ge=1),
|
||||||
page_size: int = Query(20, ge=1, le=100),
|
page_size: int = Query(20, ge=1, le=1000),
|
||||||
|
user_only: bool = Query(False),
|
||||||
current_user: Optional = Depends(get_current_user),
|
current_user: Optional = Depends(get_current_user),
|
||||||
db: Session = Depends(get_db)
|
db: Session = Depends(get_db)
|
||||||
):
|
):
|
||||||
"""获取寻配号列表"""
|
"""获取寻配号列表"""
|
||||||
query = db.query(SeekInfo).filter(SeekInfo.status == status)
|
query = db.query(SeekInfo).filter(SeekInfo.status == status)
|
||||||
|
|
||||||
|
# 我的寻配号:只查看自己的
|
||||||
|
if user_only and current_user:
|
||||||
|
query = query.filter(SeekInfo.user_id == current_user.f99_90_id)
|
||||||
|
|
||||||
# 排序
|
# 排序
|
||||||
query = query.order_by(SeekInfo.created_at.desc())
|
query = query.order_by(SeekInfo.created_at.desc())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
DATABASE_URL=postgresql://jiachenlong:Passwd1%403@pgm-bp1t5w248t7s1pvr.pg.rds.aliyuncs.com:5432/jiachenlong
|
||||||
|
SECRET_KEY=production-secret-key-b-env
|
||||||
|
OSS_ACCESS_KEY_ID=LTAI5t6HUnpFBLEK9194kPVG
|
||||||
|
OSS_ACCESS_KEY_SECRET=LEr4Q8yRxb8D5b24cKfCwlt4MMoke1
|
||||||
|
SMS_ACCESS_KEY_ID=LTAI5tQAx5niD7JQVqGE5acE
|
||||||
|
SMS_ACCESS_KEY_SECRET=QsQFAEKBkaNynIoKyvdIi3BUyWVZu1
|
||||||
|
SMS_SIGN_NAME=苏州算力
|
||||||
|
SMS_TEMPLATE_CODE=SMS_501590956
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
VERSION=1.2.97
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
<title>甲辰收藏 v=1.2.81</title>
|
<title>甲辰收藏 v=1.2.97</title>
|
||||||
|
|
||||||
<!-- Favicon -->
|
<!-- Favicon -->
|
||||||
<link rel="icon" type="image/png" href="/static/icons/favicon.png" />
|
<link rel="icon" type="image/png" href="/static/icons/favicon.png" />
|
||||||
|
|
|
||||||
|
|
@ -844,20 +844,21 @@ export default function Add() {
|
||||||
const sizeType = (dealForm.packaging === '标十' && ['01','11','21','31','41','51','61','71','81','91'].includes(tailNumber)) ? '小号' :
|
const sizeType = (dealForm.packaging === '标十' && ['01','11','21','31','41','51','61','71','81','91'].includes(tailNumber)) ? '小号' :
|
||||||
(dealForm.packaging === '标百' && ['001','011','021','031','041','051','061','071','081','091'].includes(rawSerial.slice(-3))) ? '小号' : '大号'
|
(dealForm.packaging === '标百' && ['001','011','021','031','041','051','061','071','081','091'].includes(rawSerial.slice(-3))) ? '小号' : '大号'
|
||||||
|
|
||||||
const response = await fetch(`${API_BASE}/api/information/`, {
|
const response = await fetch(`${API_BASE}/api/deal`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
info_type: 'deal',
|
|
||||||
title: `${normalizedSerial}-¥${dealForm.price}`,
|
title: `${normalizedSerial}-¥${dealForm.price}`,
|
||||||
content: `分类: ${dealForm.category || '未分类'}\n尾号: ${tailNumber || '-'}\n大小号: ${sizeType || '-'}\n包装: ${dealForm.packaging}\n平台: ${dealForm.platform}\n价格: ¥${dealForm.price}\n出售者: ${dealForm.seller || '-'}\n购买者: ${dealForm.buyer || '-'}\n日期: ${dealForm.date}\n评级: ${dealForm.gradingCompany ? dealForm.gradingCompany + ' ' + dealForm.gradingScore : '未评级'}`,
|
content: `分类: ${dealForm.category || '未分类'}\n尾号: ${tailNumber || '-'}\n大小号: ${sizeType || '-'}\n包装: ${dealForm.packaging}\n平台: ${dealForm.platform}\n价格: ¥${dealForm.price}\n出售者: ${dealForm.seller || '-'}\n购买者: ${dealForm.buyer || '-'}\n日期: ${dealForm.date}\n评级: ${dealForm.gradingCompany ? dealForm.gradingCompany + ' ' + dealForm.gradingScore : '未评级'}`,
|
||||||
deal_price: parseFloat(dealForm.price),
|
deal_price: parseFloat(dealForm.price),
|
||||||
deal_date: dealForm.date,
|
deal_date: dealForm.date,
|
||||||
packaging: dealForm.packaging,
|
packaging: dealForm.packaging,
|
||||||
category: dealForm.category,
|
category: dealForm.category,
|
||||||
is_graded: !!dealForm.gradingCompany,
|
tail_number: tailNumber,
|
||||||
grading_company: dealForm.gradingCompany || '',
|
size_type: sizeType,
|
||||||
grading_score: dealForm.gradingScore || ''
|
platform: dealForm.platform,
|
||||||
|
seller: dealForm.seller || '',
|
||||||
|
buyer: dealForm.buyer || ''
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
|
|
@ -1045,21 +1046,20 @@ export default function Add() {
|
||||||
tail_number = item.packaging === '标十' ? digits.slice(-2) : digits.slice(-3)
|
tail_number = item.packaging === '标十' ? digits.slice(-2) : digits.slice(-3)
|
||||||
size_type = (item.packaging === '标十' && ['01','11','21','31','41','51'].includes(tail_number)) || (item.packaging === '标百' && ['101','201','301','401','501'].includes(tail_number)) ? '小号' : '大号'
|
size_type = (item.packaging === '标十' && ['01','11','21','31','41','51'].includes(tail_number)) || (item.packaging === '标百' && ['101','201','301','401','501'].includes(tail_number)) ? '小号' : '大号'
|
||||||
}
|
}
|
||||||
await fetch(`${API_BASE}/api/information/`, {
|
await fetch(`${API_BASE}/api/deal`, {
|
||||||
method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
|
method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
info_type: 'deal',
|
|
||||||
title: `${item.serial}-¥${item.price}`,
|
title: `${item.serial}-¥${item.price}`,
|
||||||
content: `分类: ${item.category || '-'}\n尾号: ${tail_number || '-'}\n大小号: ${size_type || '-'}\n包装: ${item.packaging || '单张'}\n平台: ${item.platform || '-'}\n价格: ¥${item.price}\n出售者: ${item.seller || '-'}\n购买者: ${item.buyer || '-'}\n日期: ${item.deal_date || new Date().toISOString().split('T')[0]}`,
|
content: `分类: ${item.category || '-'}\n尾号: ${tail_number || '-'}\n大小号: ${size_type || '-'}\n包装: ${item.packaging || '单张'}\n平台: ${item.platform || '-'}\n价格: ¥${item.price}\n出售者: ${item.seller || '-'}\n购买者: ${item.buyer || '-'}\n日期: ${item.deal_date || new Date().toISOString().split('T')[0]}`,
|
||||||
deal_price: parseFloat(item.price),
|
deal_price: parseFloat(item.price),
|
||||||
deal_date: item.deal_date || new Date().toISOString().split('T')[0],
|
deal_date: item.deal_date || new Date().toISOString().split('T')[0],
|
||||||
packaging: item.packaging || '单张',
|
packaging: item.packaging || '单张',
|
||||||
is_graded: item.is_graded || false,
|
|
||||||
grading_company: item.grading_company || '',
|
|
||||||
grading_score: item.grade || '',
|
|
||||||
category: item.category || '',
|
category: item.category || '',
|
||||||
tail_number: tail_number,
|
tail_number: tail_number,
|
||||||
size_type: size_type
|
size_type: size_type,
|
||||||
|
platform: item.platform || '-',
|
||||||
|
seller: item.seller || '',
|
||||||
|
buyer: item.buyer || ''
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
count++
|
count++
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ export default function List() {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const user = JSON.parse(userStr)
|
const user = JSON.parse(userStr)
|
||||||
const res = await fetch(`${API_BASE}/api/deal/list?page_size=500`, {
|
const res = await fetch(`${API_BASE}/api/deal/list?user_only=true&page_size=500`, {
|
||||||
headers: { 'Authorization': 'Bearer ' + token }
|
headers: { 'Authorization': 'Bearer ' + token }
|
||||||
})
|
})
|
||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,128 @@
|
||||||
|
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||||
|
from sqlalchemy import Table, MetaData
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from typing import Optional, List
|
||||||
|
from datetime import datetime, date
|
||||||
|
from app.core.database import get_db, engine
|
||||||
|
from app.models.models import User
|
||||||
|
from app.routers.auth import get_current_user
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/api/news", tags=["资讯"])
|
||||||
|
metadata = MetaData()
|
||||||
|
|
||||||
|
# 分类表
|
||||||
|
categories_table = Table('news_categories', metadata, autoload_with=engine)
|
||||||
|
news_table = Table('news', metadata, autoload_with=engine)
|
||||||
|
user_posts_table = Table('user_posts', metadata, autoload_with=engine)
|
||||||
|
users_table = Table('users', metadata, autoload_with=engine)
|
||||||
|
deals_table = Table('deals', metadata, autoload_with=engine)
|
||||||
|
notifications_table = Table('notifications', metadata, autoload_with=engine)
|
||||||
|
|
||||||
|
# ============ 获取分类 ============
|
||||||
|
@router.get("/categories")
|
||||||
|
def get_categories(db: Session = Depends(get_db)):
|
||||||
|
results = db.query(categories_table).order_by(categories_table.c.sort_order).all()
|
||||||
|
return [dict(r._mapping) for r in results]
|
||||||
|
|
||||||
|
# ============ 获取资讯 ============
|
||||||
|
@router.get("")
|
||||||
|
def get_news(
|
||||||
|
category_id: Optional[int] = None,
|
||||||
|
page: int = 1,
|
||||||
|
limit: int = 20,
|
||||||
|
db: Session = Depends(get_db)
|
||||||
|
):
|
||||||
|
query = db.query(news_table)
|
||||||
|
if category_id:
|
||||||
|
query = query.filter(news_table.c.category_id == category_id)
|
||||||
|
offset = (page - 1) * limit
|
||||||
|
results = query.order_by(news_table.c.created_at.desc()).offset(offset).limit(limit).all()
|
||||||
|
return [dict(r._mapping) for r in results]
|
||||||
|
|
||||||
|
# ============ 获取用户发布 ============
|
||||||
|
@router.get("/posts")
|
||||||
|
def get_posts(
|
||||||
|
post_type: Optional[str] = None,
|
||||||
|
status: str = "active",
|
||||||
|
page: int = 1,
|
||||||
|
limit: int = 20,
|
||||||
|
db: Session = Depends(get_db)
|
||||||
|
):
|
||||||
|
query = db.query(user_posts_table).filter(user_posts_table.c.status == status)
|
||||||
|
if post_type:
|
||||||
|
query = query.filter(user_posts_table.c.post_type == post_type)
|
||||||
|
offset = (page - 1) * limit
|
||||||
|
results = query.order_by(user_posts_table.c.created_at.desc()).offset(offset).limit(limit).all()
|
||||||
|
return [dict(r._mapping) for r in results]
|
||||||
|
|
||||||
|
# ============ 创建发布 ============
|
||||||
|
class PostCreate(BaseModel):
|
||||||
|
post_type: str
|
||||||
|
title: str
|
||||||
|
content: Optional[str] = None
|
||||||
|
zodiac_type: Optional[str] = None
|
||||||
|
packaging: Optional[str] = None
|
||||||
|
|
||||||
|
@router.post("/posts")
|
||||||
|
def create_post(
|
||||||
|
post: PostCreate,
|
||||||
|
current_user: User = Depends(get_current_user),
|
||||||
|
db: Session = Depends(get_db)
|
||||||
|
):
|
||||||
|
result = db.execute(user_posts_table.insert().values(
|
||||||
|
user_id=current_user.f99_90_id,
|
||||||
|
post_type=post.post_type,
|
||||||
|
title=post.title,
|
||||||
|
content=post.content,
|
||||||
|
zodiac_type=post.zodiac_type,
|
||||||
|
packaging=post.packaging,
|
||||||
|
status="pending"
|
||||||
|
))
|
||||||
|
db.commit()
|
||||||
|
return {"success": True, "id": result.inserted_primary_key[0]}
|
||||||
|
|
||||||
|
# ============ 成交数据 ============
|
||||||
|
@router.get("/deals")
|
||||||
|
def get_deals(
|
||||||
|
zodiac_type: Optional[str] = None,
|
||||||
|
limit: int = 20,
|
||||||
|
db: Session = Depends(get_db)
|
||||||
|
):
|
||||||
|
query = db.query(deals_table)
|
||||||
|
if zodiac_type:
|
||||||
|
query = query.filter(deals_table.c.zodiac_type == zodiac_type)
|
||||||
|
results = query.order_by(deals_table.c.deal_date.desc()).limit(limit).all()
|
||||||
|
return [dict(r._mapping) for r in results]
|
||||||
|
|
||||||
|
# ============ 通知 ============
|
||||||
|
@router.get("/notifications")
|
||||||
|
def get_notifications(limit: int = 10, db: Session = Depends(get_db)):
|
||||||
|
results = db.query(notifications_table).filter(
|
||||||
|
notifications_table.c.is_published == True
|
||||||
|
).order_by(notifications_table.c.created_at.desc()).limit(limit).all()
|
||||||
|
return [dict(r._mapping) for r in results]
|
||||||
|
|
||||||
|
# ============ 首页数据 ============
|
||||||
|
@router.get("/home")
|
||||||
|
def get_home(db: Session = Depends(get_db)):
|
||||||
|
# 推荐发布
|
||||||
|
posts = db.query(user_posts_table).filter(
|
||||||
|
user_posts_table.c.status == "active"
|
||||||
|
).order_by(user_posts_table.c.created_at.desc()).limit(10).all()
|
||||||
|
|
||||||
|
# 成交
|
||||||
|
deals = db.query(deals_table).order_by(
|
||||||
|
deals_table.c.deal_date.desc()
|
||||||
|
).limit(10).all()
|
||||||
|
|
||||||
|
# 通知
|
||||||
|
notices = db.query(notifications_table).filter(
|
||||||
|
notifications_table.c.is_published == True
|
||||||
|
).order_by(notifications_table.c.created_at.desc()).limit(5).all()
|
||||||
|
|
||||||
|
return {
|
||||||
|
"posts": [dict(p._mapping) for p in posts],
|
||||||
|
"deals": [dict(d._mapping) for d in deals],
|
||||||
|
"notices": [dict(n._mapping) for n in notices]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
#!/bin/bash
|
||||||
|
cd /root/jiachenlong/backend
|
||||||
|
export DATABASE_URL='postgresql://jiachenlong:Passwd1%403@pgm-bp1t5w248t7s1pvr.pg.rds.aliyuncs.com:5432/jiachenlong'
|
||||||
|
export SECRET_KEY=production-secret-key-b-env-20260401
|
||||||
|
export OSS_ACCESS_KEY_ID=LTAI5t6HUnpFBLEK9194kPVG
|
||||||
|
export OSS_ACCESS_KEY_SECRET=LEr4Q8yRxb8D5b24cKfCwlt4MMoke1
|
||||||
|
export SMS_ACCESS_KEY_ID=LTAI5t86bc1nNKVNyYv4Af6x
|
||||||
|
export SMS_ACCESS_KEY_SECRET=92EVAIE3GECr214c9UaSF6TSYJvDLY
|
||||||
|
export SMS_SIGN_NAME=苏州双人旁
|
||||||
|
export SMS_TEMPLATE_CODE=SMS_505015231
|
||||||
|
export DASHSCOPE_API_KEY=sk-9389024a37da4f7bb455ac9a6b28776f
|
||||||
|
nohup python3 -m uvicorn app.main:app --host 0.0.0.0 --port 3000 --workers 1 > /tmp/uvicorn.log 2>&1 &
|
||||||
|
echo 'B后端服务已启动'
|
||||||
Loading…
Reference in New Issue