mini
This commit is contained in:
30
backend/check_urls.py
Normal file
30
backend/check_urls.py
Normal file
@@ -0,0 +1,30 @@
|
||||
import os
|
||||
import django
|
||||
from django.urls import reverse
|
||||
from django.conf import settings
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
|
||||
django.setup()
|
||||
|
||||
links = [
|
||||
"admin:shop_wechatuser_changelist",
|
||||
"admin:shop_salesperson_changelist",
|
||||
"admin:shop_distributor_changelist",
|
||||
"admin:shop_esp32config_changelist",
|
||||
"admin:shop_service_changelist",
|
||||
"admin:shop_arservice_changelist",
|
||||
"admin:shop_order_changelist",
|
||||
"admin:shop_serviceorder_changelist",
|
||||
"admin:shop_withdrawal_changelist",
|
||||
"admin:shop_commissionlog_changelist",
|
||||
"admin:shop_wechatpayconfig_changelist",
|
||||
"admin:auth_user_changelist",
|
||||
]
|
||||
|
||||
print("Checking URL patterns...")
|
||||
for link in links:
|
||||
try:
|
||||
url = reverse(link)
|
||||
print(f"[OK] {link} -> {url}")
|
||||
except Exception as e:
|
||||
print(f"[ERROR] {link}: {e}")
|
||||
Binary file not shown.
Binary file not shown.
@@ -170,26 +170,118 @@ SPECTACULAR_SETTINGS = {
|
||||
'REDOC_DIST': 'SIDECAR',
|
||||
}
|
||||
|
||||
from django.urls import reverse_lazy
|
||||
|
||||
# django-unfold配置
|
||||
UNFOLD = {
|
||||
"SITE_TITLE": "科技公司产品管理",
|
||||
"SITE_HEADER": "科技公司产品购买系统",
|
||||
"SITE_TITLE": "量迹AI后台",
|
||||
"SITE_HEADER": "量迹AI科技硬件/服务商场后台",
|
||||
"SITE_URL": "/",
|
||||
"COLORS": {
|
||||
"primary": {
|
||||
"50": "rgb(240 249 255)",
|
||||
"100": "rgb(224 242 254)",
|
||||
"200": "rgb(186 230 253)",
|
||||
"300": "rgb(125 211 252)",
|
||||
"400": "rgb(56 189 248)",
|
||||
"500": "rgb(14 165 233)",
|
||||
"600": "rgb(2 132 199)",
|
||||
"700": "rgb(3 105 161)",
|
||||
"800": "rgb(7 89 133)",
|
||||
"900": "rgb(12 74 110)",
|
||||
"950": "rgb(8 47 73)",
|
||||
"50": "rgb(236 254 255)",
|
||||
"100": "rgb(207 250 254)",
|
||||
"200": "rgb(165 243 252)",
|
||||
"300": "rgb(103 232 249)",
|
||||
"400": "rgb(34 211 238)",
|
||||
"500": "rgb(6 182 212)",
|
||||
"600": "rgb(8 145 178)",
|
||||
"700": "rgb(14 116 144)",
|
||||
"800": "rgb(21 94 117)",
|
||||
"900": "rgb(22 78 99)",
|
||||
"950": "rgb(8 51 68)",
|
||||
},
|
||||
},
|
||||
"SIDEBAR": {
|
||||
"show_search": True,
|
||||
"show_all_applications": False,
|
||||
"navigation": [
|
||||
{
|
||||
"title": "用户管理",
|
||||
"separator": True,
|
||||
"items": [
|
||||
{
|
||||
"title": "微信用户",
|
||||
"icon": "people",
|
||||
"link": reverse_lazy("admin:shop_wechatuser_changelist"),
|
||||
},
|
||||
{
|
||||
"title": "分销员管理",
|
||||
"icon": "supervisor_account",
|
||||
"link": reverse_lazy("admin:shop_salesperson_changelist"),
|
||||
},
|
||||
{
|
||||
"title": "小程序分销员",
|
||||
"icon": "groups",
|
||||
"link": reverse_lazy("admin:shop_distributor_changelist"),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"title": "商品管理",
|
||||
"separator": True,
|
||||
"items": [
|
||||
{
|
||||
"title": "硬件配置 (小智参数)",
|
||||
"icon": "hardware",
|
||||
"link": reverse_lazy("admin:shop_esp32config_changelist"),
|
||||
},
|
||||
{
|
||||
"title": "AI服务",
|
||||
"icon": "smart_toy",
|
||||
"link": reverse_lazy("admin:shop_service_changelist"),
|
||||
},
|
||||
{
|
||||
"title": "AR体验",
|
||||
"icon": "view_in_ar",
|
||||
"link": reverse_lazy("admin:shop_arservice_changelist"),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"title": "交易管理",
|
||||
"separator": True,
|
||||
"items": [
|
||||
{
|
||||
"title": "订单列表",
|
||||
"icon": "shopping_cart",
|
||||
"link": reverse_lazy("admin:shop_order_changelist"),
|
||||
},
|
||||
{
|
||||
"title": "服务订单",
|
||||
"icon": "assignment",
|
||||
"link": reverse_lazy("admin:shop_serviceorder_changelist"),
|
||||
},
|
||||
{
|
||||
"title": "提现管理",
|
||||
"icon": "account_balance_wallet",
|
||||
"link": reverse_lazy("admin:shop_withdrawal_changelist"),
|
||||
},
|
||||
{
|
||||
"title": "佣金记录",
|
||||
"icon": "monetization_on",
|
||||
"link": reverse_lazy("admin:shop_commissionlog_changelist"),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"title": "系统配置",
|
||||
"separator": True,
|
||||
"items": [
|
||||
{
|
||||
"title": "微信支付配置",
|
||||
"icon": "payment",
|
||||
"link": reverse_lazy("admin:shop_wechatpayconfig_changelist"),
|
||||
},
|
||||
{
|
||||
"title": "用户认证",
|
||||
"icon": "security",
|
||||
"link": reverse_lazy("admin:auth_user_changelist"),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
# 重新启用自动补齐斜杠,方便 Admin 使用
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -4,13 +4,13 @@ from django.db.models import Sum
|
||||
from django import forms
|
||||
from unfold.admin import ModelAdmin, TabularInline
|
||||
from unfold.decorators import display
|
||||
from .models import ESP32Config, Order, Salesperson, WeChatPayConfig, Service, ARService, ProductFeature, CommissionLog
|
||||
from .models import ESP32Config, Order, Salesperson, WeChatPayConfig, Service, ARService, ProductFeature, CommissionLog, WeChatUser, Distributor, Withdrawal, ServiceOrder
|
||||
import qrcode
|
||||
from io import BytesIO
|
||||
import base64
|
||||
|
||||
# 自定义后台标题
|
||||
admin.site.site_header = "量迹AI硬件销售管理后台"
|
||||
admin.site.site_header = "量迹AI科技硬件/服务商场后台"
|
||||
admin.site.site_title = "量迹AI后台"
|
||||
admin.site.index_title = "欢迎使用量迹AI管理系统"
|
||||
|
||||
@@ -122,6 +122,25 @@ class ServiceAdmin(ModelAdmin):
|
||||
}),
|
||||
)
|
||||
|
||||
@admin.register(ServiceOrder)
|
||||
class ServiceOrderAdmin(ModelAdmin):
|
||||
list_display = ('id', 'customer_name', 'service', 'total_price', 'status', 'salesperson', 'created_at')
|
||||
list_filter = ('status', 'service', 'salesperson', 'created_at')
|
||||
search_fields = ('id', 'customer_name', 'phone_number', 'email')
|
||||
readonly_fields = ('total_price', 'created_at', 'updated_at')
|
||||
|
||||
fieldsets = (
|
||||
('订单信息', {
|
||||
'fields': ('service', 'status', 'total_price', 'created_at')
|
||||
}),
|
||||
('客户信息', {
|
||||
'fields': ('customer_name', 'company_name', 'phone_number', 'email', 'requirements')
|
||||
}),
|
||||
('销售归属', {
|
||||
'fields': ('salesperson',)
|
||||
}),
|
||||
)
|
||||
|
||||
@admin.register(ARService)
|
||||
class ARServiceAdmin(ModelAdmin):
|
||||
list_display = ('title', 'created_at')
|
||||
@@ -251,3 +270,84 @@ class OrderAdmin(ModelAdmin):
|
||||
'fields': ('wechat_trade_no',)
|
||||
}),
|
||||
)
|
||||
|
||||
@admin.register(WeChatUser)
|
||||
class WeChatUserAdmin(ModelAdmin):
|
||||
list_display = ('nickname', 'avatar_display', 'gender_display', 'province', 'city', 'created_at')
|
||||
search_fields = ('nickname', 'openid')
|
||||
list_filter = ('gender', 'province', 'city', 'created_at')
|
||||
readonly_fields = ('openid', 'unionid', 'session_key', 'created_at', 'updated_at')
|
||||
|
||||
def avatar_display(self, obj):
|
||||
if obj.avatar_url:
|
||||
return format_html('<img src="{}" width="50" height="50" style="border-radius: 50%;" />', obj.avatar_url)
|
||||
return "暂无"
|
||||
avatar_display.short_description = "头像"
|
||||
|
||||
def gender_display(self, obj):
|
||||
choices = {0: '未知', 1: '男', 2: '女'}
|
||||
return choices.get(obj.gender, '未知')
|
||||
gender_display.short_description = "性别"
|
||||
|
||||
fieldsets = (
|
||||
('基本信息', {
|
||||
'fields': ('user', 'nickname', 'avatar_url', 'gender')
|
||||
}),
|
||||
('位置信息', {
|
||||
'fields': ('country', 'province', 'city')
|
||||
}),
|
||||
('认证信息', {
|
||||
'fields': ('openid', 'unionid', 'session_key'),
|
||||
'classes': ('collapse',)
|
||||
}),
|
||||
('时间信息', {
|
||||
'fields': ('created_at', 'updated_at')
|
||||
}),
|
||||
)
|
||||
|
||||
@admin.register(Distributor)
|
||||
class DistributorAdmin(ModelAdmin):
|
||||
list_display = ('get_nickname', 'level', 'status', 'total_earnings', 'withdrawable_balance', 'invite_code', 'created_at')
|
||||
search_fields = ('user__nickname', 'invite_code')
|
||||
list_filter = ('status', 'level', 'created_at')
|
||||
readonly_fields = ('total_earnings', 'withdrawable_balance', 'qr_code_url', 'created_at', 'updated_at')
|
||||
autocomplete_fields = ['user', 'parent']
|
||||
|
||||
def get_nickname(self, obj):
|
||||
return obj.user.nickname
|
||||
get_nickname.short_description = "微信昵称"
|
||||
get_nickname.admin_order_field = 'user__nickname'
|
||||
|
||||
fieldsets = (
|
||||
('分销员信息', {
|
||||
'fields': ('user', 'parent', 'level', 'status')
|
||||
}),
|
||||
('收益概览', {
|
||||
'fields': ('commission_rate', 'total_earnings', 'withdrawable_balance')
|
||||
}),
|
||||
('推广信息', {
|
||||
'fields': ('invite_code', 'qr_code_url')
|
||||
}),
|
||||
('时间信息', {
|
||||
'fields': ('created_at', 'updated_at')
|
||||
}),
|
||||
)
|
||||
|
||||
@admin.register(Withdrawal)
|
||||
class WithdrawalAdmin(ModelAdmin):
|
||||
list_display = ('get_distributor', 'amount', 'status', 'created_at')
|
||||
list_filter = ('status', 'created_at')
|
||||
search_fields = ('distributor__user__nickname',)
|
||||
|
||||
def get_distributor(self, obj):
|
||||
return obj.distributor.user.nickname
|
||||
get_distributor.short_description = "分销员"
|
||||
|
||||
fieldsets = (
|
||||
('提现详情', {
|
||||
'fields': ('distributor', 'amount', 'status', 'remark')
|
||||
}),
|
||||
('时间信息', {
|
||||
'fields': ('created_at', 'updated_at')
|
||||
}),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user