小程序分销
All checks were successful
Deploy to Server / deploy (push) Successful in 24s

This commit is contained in:
jeremygan2021
2026-02-17 11:22:50 +08:00
parent ac61a127ae
commit 7114a33d1b
10 changed files with 296 additions and 137 deletions

View File

@@ -100,7 +100,8 @@ DATABASES = {
}
# 从环境变量获取数据库配置 (Docker 环境会自动注入这些变量)
DB_HOST = os.environ.get('DB_HOST', '121.43.104.161')
# DB_HOST = os.environ.get('DB_HOST', '121.43.104.161')
DB_HOST = os.environ.get('DB_HOST', '6.6.6.66')
if DB_HOST:
DATABASES['default'] = {
'ENGINE': 'django.db.backends.postgresql',
@@ -108,7 +109,8 @@ if DB_HOST:
'USER': os.environ.get('DB_USER', 'market'),
'PASSWORD': os.environ.get('DB_PASSWORD', '123market'),
'HOST': DB_HOST,
'PORT': os.environ.get('DB_PORT', '6433'),
# 'PORT': os.environ.get('DB_PORT', '6433'),
'PORT': os.environ.get('DB_PORT', '5432'),
}

View File

@@ -11,7 +11,7 @@ from drf_spectacular.utils import extend_schema, extend_schema_view, OpenApiPara
from .models import ESP32Config, Order, WeChatPayConfig, Service, VCCourse, ServiceOrder, Salesperson, CommissionLog, WeChatUser, Distributor, Withdrawal, CourseEnrollment
from .serializers import ESP32ConfigSerializer, OrderSerializer, ServiceSerializer, VCCourseSerializer, ServiceOrderSerializer, WeChatUserSerializer, DistributorSerializer, WithdrawalSerializer, CommissionLogSerializer, CourseEnrollmentSerializer
from .utils import get_access_token
from django.db import transaction
from django.db import transaction, models
from django.core.signing import TimestampSigner, BadSignature, SignatureExpired
from django.contrib.auth.models import User
from wechatpayv3 import WeChatPay, WeChatPayType
@@ -1545,7 +1545,7 @@ class DistributorViewSet(viewsets.GenericViewSet):
user = get_current_wechat_user(request)
if not user or not hasattr(user, 'distributor'):
return Response({'error': 'Unauthorized'}, status=401)
distributor = user.distributor
# 直推下级

View File

@@ -0,0 +1,72 @@
// Tech/Cyberpunk Theme Variables & Mixins
// Colors
$bg-dark: #050505;
$primary-cyan: #00f0ff;
$primary-green: #00b96b;
$primary-purple: #bd00ff;
$text-main: #ffffff;
$text-secondary: rgba(255, 255, 255, 0.7);
$text-muted: rgba(255, 255, 255, 0.4);
// Mixins
@mixin page-container {
min-height: 100vh;
background-color: $bg-dark;
background-image:
radial-gradient(circle at 10% 10%, rgba(0, 240, 255, 0.1) 0%, transparent 40%),
radial-gradient(circle at 90% 90%, rgba(189, 0, 255, 0.1) 0%, transparent 40%);
color: $text-main;
padding: 30px;
box-sizing: border-box;
}
@mixin glass-card {
background: rgba(255, 255, 255, 0.03);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 16px;
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.3);
}
@mixin neon-text($color: $primary-cyan) {
color: $color;
text-shadow: 0 0 10px rgba($color, 0.5), 0 0 20px rgba($color, 0.3);
}
@mixin neon-button($color: $primary-cyan) {
background: rgba($color, 0.1);
border: 1px solid rgba($color, 0.5);
color: $color;
box-shadow: 0 0 15px rgba($color, 0.2);
transition: all 0.3s ease;
&:active {
background: rgba($color, 0.2);
box-shadow: 0 0 25px rgba($color, 0.4);
transform: scale(0.98);
}
}
@mixin tech-border {
position: relative;
&::before {
content: '';
position: absolute;
top: -1px; left: -1px;
width: 20px; height: 20px;
border-top: 2px solid $primary-cyan;
border-left: 2px solid $primary-cyan;
border-radius: 4px 0 0 0;
}
&::after {
content: '';
position: absolute;
bottom: -1px; right: -1px;
width: 20px; height: 20px;
border-bottom: 2px solid $primary-cyan;
border-right: 2px solid $primary-cyan;
border-radius: 0 0 4px 0;
}
}

View File

@@ -1,48 +1,56 @@
@import './_shared.scss';
.page-container {
min-height: 100vh;
background: #f5f5f5;
padding: 20px;
@include page-container;
}
.item {
background: #fff;
border-radius: 12px;
@include glass-card;
padding: 30px;
margin-bottom: 20px;
margin-bottom: 24px;
.row {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
margin-bottom: 16px;
align-items: center;
.type {
font-size: 30px;
color: #333;
font-size: 28px;
color: $text-main;
font-weight: bold;
}
.amount {
font-size: 32px;
color: #ff9800;
@include neon-text($primary-green);
font-weight: bold;
font-family: 'DIN Alternate', sans-serif;
}
.source {
font-size: 24px;
color: #666;
color: $text-secondary;
}
.status {
font-size: 24px;
color: #00b96b;
color: $primary-cyan;
background: rgba(0, 240, 255, 0.1);
padding: 4px 12px;
border-radius: 4px;
}
}
.time {
font-size: 22px;
color: #999;
color: $text-muted;
display: block;
margin-top: 10px;
border-top: 1px solid #f5f5f5;
padding-top: 10px;
margin-top: 16px;
border-top: 1px solid rgba(255, 255, 255, 0.1);
padding-top: 12px;
}
}
.empty {
padding: 100px 0;
text-align: center;
color: #999;
color: $text-muted;
font-size: 28px;
}

View File

@@ -1,68 +1,112 @@
@import './_shared.scss';
.page-container {
min-height: 100vh;
background-color: #f7f8fa;
padding: 20px;
@include page-container;
}
.header-card {
background: linear-gradient(135deg, #00b96b, #009456);
border-radius: 12px;
padding: 30px 20px;
color: #fff;
@include glass-card;
@include tech-border;
padding: 40px 30px;
margin-bottom: 30px;
text-align: center;
box-shadow: 0 4px 12px rgba(0, 185, 107, 0.3);
margin-bottom: 20px;
position: relative;
overflow: hidden;
.label { font-size: 14px; opacity: 0.8; display: block; margin-bottom: 10px; }
.amount { font-size: 40px; font-weight: bold; display: block; margin-bottom: 20px; }
// Background accent
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(135deg, rgba(0, 240, 255, 0.05), rgba(0, 185, 107, 0.05));
z-index: -1;
}
.label {
font-size: 16px;
color: $text-secondary;
display: block;
margin-bottom: 16px;
letter-spacing: 1px;
text-transform: uppercase;
}
.amount {
font-size: 56px;
font-weight: bold;
display: block;
margin-bottom: 30px;
@include neon-text($primary-cyan);
font-family: 'DIN Alternate', sans-serif; // Use a tech-looking font if available
}
.btn-withdraw {
background: #fff;
color: #00b96b;
border-radius: 20px;
font-size: 14px;
padding: 0 30px;
height: 40px;
line-height: 40px;
@include neon-button($primary-green);
border-radius: 30px;
font-size: 18px;
padding: 0 40px;
height: 50px;
line-height: 50px;
display: inline-block;
font-weight: bold;
letter-spacing: 2px;
}
}
.stats-grid {
display: flex;
background: #fff;
border-radius: 12px;
padding: 20px 0;
margin-bottom: 20px;
@include glass-card;
padding: 30px 0;
margin-bottom: 30px;
.item {
flex: 1;
text-align: center;
border-right: 1px solid #eee;
border-right: 1px solid rgba(255, 255, 255, 0.1);
&:last-child { border-right: none; }
.val { font-size: 18px; font-weight: bold; color: #333; display: block; margin-bottom: 5px; }
.lbl { font-size: 12px; color: #999; }
.val {
font-size: 24px;
font-weight: bold;
color: $text-main;
display: block;
margin-bottom: 8px;
text-shadow: 0 0 10px rgba(255, 255, 255, 0.2);
}
.lbl {
font-size: 14px;
color: $text-secondary;
}
}
}
.menu-list {
background: #fff;
border-radius: 12px;
@include glass-card;
padding: 0 20px;
.menu-item {
display: flex;
justify-content: space-between;
align-items: center;
height: 60px;
border-bottom: 1px solid #f5f5f5;
font-size: 16px;
color: #333;
height: 70px; // Larger touch target
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
font-size: 18px;
color: $text-main;
&:last-child { border-bottom: none; }
.arrow { color: #ccc; }
.arrow {
color: $primary-cyan;
opacity: 0.7;
font-family: monospace;
}
&:active {
background: rgba(255, 255, 255, 0.02);
}
}
}

View File

@@ -1,43 +1,49 @@
@import './_shared.scss';
.page-container {
padding: 30px;
background-color: #f8f8f8;
min-height: 100vh;
box-sizing: border-box;
@include page-container;
display: flex;
flex-direction: column;
align-items: center;
}
.qr-card {
background: #fff;
border-radius: 16px;
@include glass-card;
@include tech-border;
padding: 40px;
width: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
box-shadow: 0 4px 12px rgba(0,0,0,0.05);
margin-top: 40px;
.qr-img {
width: 400px;
height: 400px;
background: #eee;
margin-bottom: 30px;
background: rgba(255, 255, 255, 0.1);
margin-bottom: 40px;
border: 1px solid $primary-cyan;
padding: 10px;
border-radius: 8px;
}
.tip {
color: #666;
color: $text-main;
font-size: 28px;
text-align: center;
line-height: 1.5;
line-height: 1.6;
opacity: 0.9;
}
}
.btn-save {
margin-top: 60px;
width: 100%;
background: #07c160;
color: #fff;
@include neon-button($primary-cyan);
height: 90px;
line-height: 90px;
font-size: 32px;
font-weight: bold;
border-radius: 45px;
}

View File

@@ -1,51 +1,57 @@
@import './_shared.scss';
.page-container {
min-height: 100vh;
background: #f5f5f5;
padding: 20px;
@include page-container;
}
.item {
background: #fff;
border-radius: 12px;
padding: 24px;
margin-bottom: 20px;
@include glass-card;
padding: 30px;
margin-bottom: 24px;
.row {
display: flex;
justify-content: space-between;
border-bottom: 1px solid #f5f5f5;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
padding-bottom: 16px;
margin-bottom: 16px;
.order-no {
font-size: 24px;
color: #666;
color: $text-secondary;
font-family: monospace;
}
.status {
font-size: 24px;
color: #00b96b;
color: $primary-green;
}
}
.content {
display: flex;
margin-bottom: 16px;
.img {
width: 120px;
height: 120px;
border-radius: 8px;
background: #eee;
margin-right: 20px;
background: rgba(255, 255, 255, 0.1);
margin-right: 24px;
border: 1px solid rgba(255, 255, 255, 0.1);
}
.info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
.title {
font-size: 28px;
color: #333;
color: $text-main;
line-height: 1.4;
}
.price {
font-size: 32px;
color: #ff9800;
color: $primary-cyan;
font-weight: bold;
}
}
@@ -54,12 +60,13 @@
display: flex;
justify-content: space-between;
font-size: 24px;
color: #999;
color: $text-muted;
}
}
.empty {
padding: 100px 0;
text-align: center;
color: #999;
color: $text-muted;
font-size: 28px;
}

View File

@@ -1,42 +1,46 @@
@import './_shared.scss';
.page-container {
min-height: 100vh;
background-color: #f7f8fa;
padding: 40px 20px;
@include page-container;
display: flex;
justify-content: center;
align-items: center;
}
.card {
background: #fff;
border-radius: 12px;
padding: 40px 30px;
@include glass-card;
@include tech-border;
padding: 50px 30px;
width: 100%;
text-align: center;
box-shadow: 0 4px 12px rgba(0,0,0,0.05);
.title {
font-size: 24px;
font-size: 32px;
font-weight: bold;
color: #333;
@include neon-text($primary-purple);
display: block;
margin-bottom: 10px;
margin-bottom: 16px;
letter-spacing: 2px;
}
.desc {
font-size: 14px;
color: #999;
font-size: 16px;
color: $text-secondary;
display: block;
margin-bottom: 40px;
margin-bottom: 50px;
}
.btn-register {
background: #00b96b;
color: #fff;
border-radius: 22px;
height: 44px;
line-height: 44px;
font-size: 16px;
border: none;
@include neon-button($primary-green);
background: linear-gradient(90deg, rgba(0, 185, 107, 0.2), rgba(0, 240, 255, 0.2));
border: 1px solid $primary-green;
border-radius: 30px;
height: 56px;
line-height: 56px;
font-size: 20px;
font-weight: bold;
width: 80%;
margin: 0 auto;
letter-spacing: 4px;
}
}

View File

@@ -1,49 +1,61 @@
@import './_shared.scss';
.page-container {
min-height: 100vh;
background: #f5f5f5;
@include page-container;
padding-bottom: 40px;
}
.header {
background: #fff;
@include glass-card;
padding: 30px;
display: flex;
justify-content: space-around;
margin-bottom: 20px;
margin-bottom: 24px;
.stat {
display: flex;
flex-direction: column;
align-items: center;
.val {
font-size: 36px;
font-weight: bold;
color: #333;
@include neon-text($primary-cyan);
}
.lbl {
font-size: 24px;
color: #999;
color: $text-secondary;
margin-top: 10px;
}
}
}
.list {
background: #fff;
@include glass-card;
padding: 0;
overflow: hidden;
.list-header {
padding: 20px 30px;
padding: 24px 30px;
font-size: 28px;
font-weight: bold;
border-bottom: 1px solid #eee;
color: $text-main;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
background: rgba(255, 255, 255, 0.02);
}
.item {
display: flex;
align-items: center;
padding: 20px 30px;
border-bottom: 1px solid #eee;
padding: 24px 30px;
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
.avatar {
width: 80px;
height: 80px;
border-radius: 50%;
margin-right: 20px;
background: #eee;
margin-right: 24px;
background: #333;
border: 2px solid $primary-purple;
}
.info {
flex: 1;
@@ -51,22 +63,23 @@
flex-direction: column;
.name {
font-size: 28px;
color: #333;
color: $text-main;
}
.time {
font-size: 22px;
color: #999;
margin-top: 6px;
color: $text-muted;
margin-top: 8px;
}
}
.level {
font-size: 24px;
color: #ff9800;
color: $primary-purple;
font-weight: bold;
}
}
.empty {
padding: 50px;
text-align: center;
color: #999;
color: $text-muted;
}
}

View File

@@ -1,33 +1,31 @@
@import './_shared.scss';
.page-container {
padding: 30px;
background-color: #f8f8f8;
min-height: 100vh;
box-sizing: border-box;
@include page-container;
}
.card {
background: #fff;
border-radius: 16px;
@include glass-card;
padding: 40px;
box-shadow: 0 4px 12px rgba(0,0,0,0.05);
.label {
font-size: 28px;
color: #333;
margin-bottom: 20px;
color: $text-secondary;
margin-bottom: 24px;
display: block;
}
.input-box {
display: flex;
align-items: center;
border-bottom: 1px solid #eee;
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
padding-bottom: 20px;
margin-bottom: 20px;
margin-bottom: 24px;
.symbol {
font-size: 48px;
font-weight: bold;
color: $text-main;
margin-right: 20px;
}
@@ -36,22 +34,27 @@
height: 60px;
font-size: 48px;
font-weight: bold;
color: $primary-green;
}
}
.balance-tip {
font-size: 24px;
color: #999;
color: $text-muted;
.all {
color: #576b95;
margin-left: 10px;
color: $primary-cyan;
margin-left: 16px;
}
}
.btn-submit {
margin-top: 60px;
background: #07c160;
color: #fff;
margin-top: 80px;
@include neon-button($primary-green);
height: 88px;
line-height: 88px;
font-size: 32px;
font-weight: bold;
border-radius: 44px;
}
}