当前位置: 首页 > article >正文

python:django项目知识点02——搭建简易授权码核销系统

前言

        如标题所述,本篇博客主要围绕快速搭建业务系统展开,旨在:快速、逻辑分明

 

适用对象

        django+mysql,实现一套授权码核销功能,包含用户登录和授权码核销两个方面内容

业务代码

        前述

        基础代码已在上篇博客中讲述,这里给出核心views代码和html代码

        python:django项目知识点01——前期配置、用户管理、权限核验、django-orm-CSDN博客

        最终效果 

 

 

        登录

login.py

from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth import authenticate, login


def user_input_check(username, password):
    message = ''
    if len(username) > 16:
        message = "用户名不得超过16位!"
    elif len(password) < 6:
        message = "密码不得少于6位!"
    elif len(password) > 16:
        message = "密码不得超过16位!"
    if message:
        return False, message
    else:
        return True, ''


def login_view(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']

        ret, msg = user_input_check(username, password)
        if ret:
            user = authenticate(request, username=username, password=password)
            if user:
                login(request, user)
                return redirect('/welcome')  # 替换 'welcome' 为你应用的主页视图名
            else:
                messages.error(request, "用户名或密码错误!")
        else:
            messages.error(request, msg)

    return render(request, 'user/login.html')
login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
    <link rel="stylesheet" href="/static/css/form_add.css">
</head>
<body>
    <div class="container">
        <div class="form-wrapper">
            <h2>用户登录</h2>
            {% if messages %}
                <ul class="messages">
                    {% for message in messages %}
                    <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
                    {% endfor %}
                </ul>
            {% endif %}
            {% if form.errors %}
                <div class="errors">
                    <ul>
                        {% for field in form %}
                            {% for error in field.errors %}
                                <li>{{ error }}</li>
                            {% endfor %}
                        {% endfor %}
                        {% for error in form.non_field_errors %}
                            <li>{{ error }}</li>
                        {% endfor %}
                    </ul>
                </div>
            {% endif %}
            <form method="post">
                {% csrf_token %}
                <div class="form-group">
                    <label for="username">用户名</label>
                    <input type="text" name="username" id="username" required>
                </div>
                <div class="form-group">
                    <label for="password">密码</label>
                    <input type="password" name="password" id="password" required>
                </div>
                <button type="submit">登录</button>
            </form>
        </div>
    </div>
</body>
</html>
body {
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    margin: 0;
    padding: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
}
.container {
    background: #fff;
    padding: 2rem;
    border-radius: 8px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    max-width: 500px;
    width: 100%;
}
h1 {
    margin-bottom: 1rem;
    font-size: 24px;
    color: #333;
}
.form-group {
    margin-bottom: 1rem;
}
.form-group label {
    display: block;
    margin-bottom: 0.5rem;
    font-weight: bold;
    color: #555;
}
.form-group input,
.form-group select,
.form-group textarea {
    width: 100%;
    padding: 0.75rem;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
}
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
    border-color: #007bff;
    outline: none;
}
.form-group .error {
    color: #e74c3c;
    font-size: 0.875rem;
    margin-top: 0.25rem;
}
button {
    background-color: #007bff;
    color: #fff;
    border: none;
    padding: 0.75rem 1.5rem;
    border-radius: 4px;
    cursor: pointer;
    font-size: 16px;
    transition: background-color 0.3s;
}
button:hover {
    background-color: #0056b3;
}

         

        授权码核销

permission.py

import datetime
import json
from django.http import JsonResponse
from django.shortcuts import render, redirect
from django.conf import settings
from myProject.models.mysql_models import TmLicense, TmAccount, TmAccountLog, raw_sql_select


def permission_view(request):
    if not request.user.is_authenticated:
        # 用户未登录,重定向到登录页面或显示提示
        return redirect('login')

    if request.method == 'GET':
        username = request.user.username

        # 将结果转换为字典列表
        results = raw_sql_select("""
                SELECT a.username as username, a.account_id as account_id, b.dict_value as user_state, c.account_money as account_money, c.lock_money as lock_money, d.dict_value as account_state
                FROM tp_user a
                LEFT JOIN tb_dict b ON a.state = b.dict_id AND b.dict_type = 'user_state'
                LEFT JOIN tm_account c ON a.account_id = c.account_id
                LEFT JOIN tb_dict d ON c.state = d.dict_id AND d.dict_type = 'account_state'
                WHERE a.username = %s
            """, [username])[0]

        # 用户已登录,处理登录用户的逻辑
        return render(request, 'user/permission.html',
                      context={'back_url': settings.WELCOME_URL, 'user': results})

    elif request.method == 'POST':
        # 解析 JSON 数据
        comes = json.loads(request.body)

        license_code = comes['license_code']
        account_id = comes['account_id']

        # 查询当前账户状态
        account_msg = TmAccount.objects.filter(account_id=account_id).values('state', 'account_money').get()
        account_state = account_msg['state']
        account_money = account_msg['account_money']

        # 当账户可用时
        if account_state == 1:

            # 查询该授权码是否正常在用

            # 之后的代码都是按照约定状态默认值来的,没有借助字典表
            # 因此这里借助字典表来判别验证码状态的情况 存在设计问题
            # 这点留给自己做警醒:考虑用哪种策略后,就不要东一道西一道了,要尽量保障代码逻辑一致性
            license_msg = raw_sql_select("""
                select a.save_money as save_money, b.dict_value as license_state
                from tm_license a
                join tb_dict b on a.state = b.dict_id and b.dict_type = 'license_state'
                where a.license_code = %s
            """, [license_code])

            print(license_msg)
            if not license_msg:
                return JsonResponse({'status': False, 'msg': '授权码不存在'})

            license_msg = license_msg[0]
            if license_msg['license_state'] == '待使用':
                after_money = account_money + license_msg['save_money']
                # 添加核销记录
                log_entry = TmAccountLog(
                    order_effect_ret=0,
                    reason=f'license recharge: {license_code}',
                    account_id=account_id,
                    effect=license_msg['save_money'],
                    before=account_money,
                    after=after_money,
                    create_time=datetime.datetime.now()
                )
                log_entry.save()

                # 核销授权码
                license_updated = TmLicense.objects.filter(license_code=license_code).update(state=2)
                if license_updated:
                    # 账户余额更新
                    account_updated = TmAccount.objects.filter(account_id=account_id).update(account_money=after_money)
                    if account_updated:
                        return JsonResponse({'status': True, 'msg': '成功!'})
                    # 账户更新失败则回滚授权码状态为待用
                    else:
                        TmLicense.objects.filter(license_code=license_code).update(state=1)
                        return JsonResponse({'status': False, 'msg': '账户异常!'})

                return JsonResponse({'status': False, 'msg': '授权码核销失败!'})
            else:
                return JsonResponse({'status': False, 'msg': '授权码已失效'})
permission.html

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="/static/css/user_permission.css">
    <meta name="csrf-token" content="{% csrf_token %}">
    <title>用户授权</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            background-color: #f4f4f4;
            color: #333;
        }
        .container {
            width: 80%;
            max-width: 800px;
            margin: 20px auto;
            background: #fff;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }
        h1 {
            text-align: center;
            color: #007bff;
        }
    </style>
</head>
<body>

    <div class="container">
        <h1>授权详情</h1>

        <!-- 用户信息部分 -->
        <div class="info-section">
            <h2>用户名</h2>
            <p>{{ user.username }}</p>
        </div>

        <div class="info-section">
            <h2>用户状态</h2>
            <p>{{ user.user_state }}</p>
        </div>

        <div class="info-section">
            <h2>账户状态</h2>
            <p>{{ user.account_state }}</p>
        </div>

        <div class="info-section">
            <h2>钱包余额</h2>
            <p style="color: goldenrod">¥ {{ user.account_money }}</p>
        </div>

        <div class="info-section">
            <h2>冻结金额</h2>
            <p style="color: red">¥ {{ user.lock_money }}</p>
        </div>

        <!-- 授权码提交表单 -->
        <div class="form-container">
            <h2>提交授权码</h2>
            <input name="account_id" id="account_id" value="{{ user.account_id }}" hidden/>
            <div class="form-group">
                <label for="auth-code">授权码</label>
                <input type="text" id="license_code" name="license_code" required>
            </div>
            <div class="form-group">
                <button onclick="upMsg()">提交</button>
            </div>
        </div>
    </div>

</body>

<script>
    function upMsg() {
        var license_code = document.getElementById("license_code").value;
        var account_id = document.getElementById("account_id").value;

        if (license_code === "") {
            alert("请填写完整内容");
            return false; // 阻止表单提交
        }

        var jsonData = JSON.stringify({
            "license_code": license_code,
            "account_id": account_id,
        });

        fetch('', {
            method: 'POST',
            headers: {
                    'Content-Type': 'application/json',
                    'X-CSRFToken': csrfToken // 添加 CSRF 令牌到请求头中
                },
            body: jsonData
        })
        .then(response => response.json())
        .then(data => {
            if (data.status === true) {
                alert("已充值")
                window.location.reload()
            } else {
                alert("提交失败: " + data.msg);
            }
        })
        .catch(error => {
            console.error('提交失败:', error);
            alert("提交失败: " + error);
        });
    }
</script>
</html>
user_permission.css

.info-section {
    margin-bottom: 20px;
}
.info-section h2 {
    margin-bottom: 10px;
    font-size: 1.2em;
    color: #555;
}
.info-section p {
    font-size: 1.1em;
    margin: 5px 0;
}
.form-container {
    margin-top: 20px;
}
.form-container h2 {
    margin-bottom: 10px;
    font-size: 1.2em;
    color: #555;
}
.form-group {
    margin-bottom: 15px;
}
.form-group label {
    display: block;
    margin-bottom: 5px;
    font-weight: bold;
}
.form-group input[type="text"] {
    width: 100%;
    padding: 10px;
    font-size: 1em;
    border: 1px solid #ddd;
    border-radius: 4px;
}
.form-group button {
    background-color: #007bff;
    border: none;
    color: white;
    padding: 10px 20px;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    font-size: 1em;
    margin-top: 10px;
    cursor: pointer;
    border-radius: 4px;
}
.form-group button:hover {
    background-color: #0056b3;
}

http://www.kler.cn/news/317744.html

相关文章:

  • Llama 3.1 技术研究报告-3
  • Superset 使用指南之优化数据可视化性能与扩展
  • SpringBoot整合InfluxDB(实战)
  • 视频美颜SDK核心功能解析:打造高效直播美颜工具方案详解
  • 力扣6 N字形变换
  • Python 方法传参详解
  • 【裸机装机系列】11.kali(ubuntu)-优化-扩展root分区存储空间
  • 快递预约取件API接口代码
  • 手机上轻松解压并处理 JSON 文件
  • [单master节点k8s部署]22.构建EFK日志收集平台(一)
  • 网站服务器怎么计算同时在线人数?
  • python基础(1)pyenv安装和对Django使用
  • Python编码系列—Python外观模式:简化复杂系统的快捷方式
  • pytorch--流水线并行
  • pandas外文文档快速入门
  • UNet 眼底血管分割实战教程
  • Python Flask网页开发基本框架
  • 大数据新视界 --大数据大厂之 Vue.js 与大数据可视化:打造惊艳的数据界面
  • 【Java面向对象高级06】static的应用知识:代码块
  • java开发jmeter采样器
  • 【AI写作】介绍 Docker 的基本概念和优势,以及在应用程序开发中的实际应用
  • 目标检测任务中xml标签文件修改
  • 【学习笔记】Transformer架构探讨
  • [ IDE ] SEGGER Embedded Studio for RISC-V
  • C++初阶学习——探索STL奥秘——反向迭代器
  • [Leetcode 543][Easy]-二叉树的直径-递归
  • ubuntu安装StarQuant
  • 【Verilog学习日常】—牛客网刷题—Verilog快速入门—VL22
  • 【Linux】生产者消费者模型:基于阻塞队列,使用互斥锁和条件变量维护互斥与同步关系
  • 高级java每日一道面试题-2024年9月20日-分布式篇-什么是CAP理论?