2024--Django平台开发-订单项目管理(十四)

时间:2024-01-24 08:46:25

day14 订单管理系统

在这里插入图片描述

1.关于登录

1.1 UI美化

页面美化,用BootStrap + 自定义BooStrapForm类实现。

class BootStrapForm:
    exclude_filed_list = []

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # {'title':对象,"percent":对象}
        for name, field in self.fields.items():
            if name in self.exclude_filed_list:
                continue
            field.widget.attrs['class'] = "form-control"
            field.widget.attrs['placeholder'] = "请输入{}".format(field.label)

1.2 csrf问题

/**
 * 根据cookie的name获取对应的值
 * @param name
 * @returns {null}
 */
function getCookie(name) {
    let cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        const cookies = document.cookie.split(';');
        for (let i = 0; i < cookies.length; i++) {
            const cookie = cookies[i].trim();
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

$.ajaxSetup({
    beforeSend: function (xhr, settings) {
        if (!csrfSafeMethod(settings.type)) {
            xhr.setRequestHeader("X-CSRFTOKEN", getCookie('csrftoken'));
        }
    }
})

在页面上引入即可:

<script src="{% static 'js/csrf.js' %}"></script>

2.中间件校验

2.1 是否登录

NB_WHITE_URL = ['/login/', '/sms/login/', '/sms/send/']
class AuthMiddleware(MiddlewareMixin):
    def is_white_url(self, request):
        if request.path_info in settings.NB_WHITE_URL:
            return True
	def process_request(self, request):
        """ 校验用户是否已登录 """
        # 1.不需要登录就能访问的URL
        if self.is_white_url(request):
            return

        # 2.session中获取用户信息,能获取到登录成功;未登录
        #  {'role': mapping[role], 'name': user_object.username, 'id': user_object.id}
        user_dict = request.session.get(settings.NB_SESSION_KEY)

        # 3.未登录,跳转回登录页面
        if not user_dict:
            return redirect(settings.NB_LOGIN_URL)

        # 4.已登录,封装用户信息
        request.nb_user = UserInfo(**user_dict)

2.2 是否有权限

class AuthMiddleware(MiddlewareMixin):

    def process_view(self, request, callback, callback_args, callback_kwargs):
        if self.is_white_url(request):
            return
        
        current_name = request.resolver_match.url_name

        # 1.根据用户角色获取自己具备所有的权限
        user_permission_dict = settings.NB_PERMISSION[request.nb_user.role]

        # 2.获取当前用户访问的URL
        current_name = request.resolver_match.url_name

        # 3.判断是否在自己具备的权限
        if current_name not in user_permission_dict:
            # return HttpResponse("无权访问")

            # print(request.Meta)
            from django.core.handlers.wsgi import WSGIRequest
            # print(request,type(request))
            if request.is_ajax():
                return JsonResponse({'status': False, 'detail': "无权访问"})
            else:
                return render(request, 'permission.html')
NB_PERMISSION = {
    "ADMIN": {
        "level_list": {"text": "级别列表", 'parent': None},
        "level_add": {"text": "新建级别", 'parent': 'level_list'},
        "level_edit": {"text": "编辑级别", 'parent': 'level_list'},
        "level_delete": {"text": "删除级别", 'parent': 'level_list'},

        "customer_list": {"text": "客户列表", 'parent': None},
        "customer_add": {"text": "新建客户", 'parent': 'customer_list'},
        "customer_edit": {"text": "编辑客户", 'parent': 'customer_list'},
        "customer_delete": {"text": "删除客户", 'parent': 'customer_list'},
        "customer_reset": {"text": "重置密码", 'parent': 'customer_list'},
        "customer_charge": {"text": "我的交易记录", 'parent': 'customer_list'},
        "customer_charge_add": {"text": "创建交易记录", 'parent': 'customer_list'},

        "policy_list": {"text": "价格策略", 'parent': None},
        "policy_add": {"text": "创建价格策略", 'parent': 'policy_list'},
        "policy_edit": {"text": "编辑价格策略", 'parent': 'policy_list'},
        "policy_delete": {"text": "删除价格策略", 'parent': 'policy_list'},

        "transaction_list": {'text': "交易记录", 'name': "transaction_list", 'parent': None},

    },
    "CUSTOMER": {
        "my_order_list": {"text": "订单列表", 'parent': None},
        "my_order_add": {"text": "订单列表", 'parent': 'my_order_list'},
        "my_order_cancel": {"text": "订单列表", 'parent': 'my_order_list'},
        "my_transaction_list": {"text": "我的交易记录", 'parent': None},
    }
}

3.路径导航

推荐:用inclusion_tag在页面渲染时生成。

# ...
# ....

text_list = []  # ["创建订单","订单列表"]

# 1.先添加当前访问的路径导航名称添加text_list
text_list.append(user_permission_dict[current_name]['text'])

# 2.循环获取上级
menu_name = current_name
while user_permission_dict[menu_name]['parent']:
    menu_name = user_permission_dict[menu_name]['parent']
    text = user_permission_dict[menu_name]['text']
    text_list.append(text)

# 3.添加首页
text_list.append("首页")

# 4.翻转
text_list.reverse()

# 5.路径导航列表(用于后续页面显示)
request.nb_user.text_list = text_list
{% if request.nb_user.text_list %}
<ol class="breadcrumb">
    {% for text in request.nb_user.text_list %}
    <li><a>{{ text }}</a></li>
    {% endfor %}
</ol>
{% endif %}

4.动态菜单

NB_MENU = {
    'ADMIN': [
        {
            'text': "用户信息",
            'icon': "fa-bed",
            'children': [
                {'text': "级别管理", 'url': "/level/list/", 'name': "level_list"},
                {'text': "客户管理", 'url': "/customer/list/", 'name': "customer_list"},
                {'text': "价格策略", 'url': "/policy/list/", 'name': "policy_list"},
            ]
        },
        {
            'text': "交易管理",
            'icon': "fa-bed",
            'children': [
                {'text': "交易记录", 'url': "/transaction/list/", 'name': "transaction_list"},
            ]
        },

    ],
    'CUSTOMER': [
        {
            'text': "订单中心",
            'icon': "fa-bed",
            'children': [
                {'text': "订单管理", 'url': "/my/order/list/", 'name': "my_order_list"},
                {'text': "我的交易记录", 'url': "/my/transaction/list/", 'name': "my_transaction_list"},
            ]
        },
    ],
}
from django.http import QueryDict
from django.template import Library
from django.conf import settings
import copy
register = Library()


@register.inclusion_tag("tag/nb_menu.html")
def nb_menu(request):
    # 1.读取当前用户的角色信息
    # print(request.nb_user.role)

    # 2.菜单信息
    user_menu_list = copy.deepcopy(settings.NB_MENU[request.nb_user.role])

    for item in user_menu_list:
        # item['class'] = 'hide'
        for child in item['children']:
            # if child['url'] == request.path_info: # v1版
            if child['name'] == request.nb_user.menu_name:
                child['class'] = 'active'
                # item['class'] = ""

    return {'menu_list': user_menu_list}


<div class="multi-menu">
    {% for item in menu_list %}
        <div class="item">
            <div class="title">
                <span class="icon-wrap"><i class="fa {{ item.icon }}"></i></span> {{ item.text }}
            </div>
            <div class="body {{ item.class }}">
                {% for child in item.children %}
                    <a class="{{ child.class }}" href="{{ child.url }}">{{ child.text }}</a>
                {% endfor %}
            </div>
        </div>
    {% endfor %}
</div>

.multi-menu .item {
    background-color: white;
}

.multi-menu .item > .title {
    padding: 10px 5px;
    border-bottom: 1px solid #dddddd;
    cursor: pointer;
    color: #333;
    display: block;
    background: #efefef;
    background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #efefef), color-stop(1, #fafafa));
    background: -ms-linear-gradient(bottom, #efefef, #fafafa);
    background: -o-linear-gradient(bottom, #efefef, #fafafa);
    filter: progid:dximagetransform.microsoft.gradient(startColorStr='#e3e3e3', EndColorStr='#ffffff');
    -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fafafa',EndColorStr='#efefef')";
    box-shadow: inset 0 1px 1px white;
}

.multi-menu .item > .body {
    border-bottom: 1px solid #dddddd;
}

.multi-menu .item > .body a {
    display: block;
    padding: 5px 20px;
    text-decoration: none;
    border-left: 2px solid transparent;
    font-size: 13px;

}

.multi-menu .item > .body a:hover {
    border-left: 2px solid #2F72AB;
}

.multi-menu .item > .body a.active {
    border-left: 2px solid #2F72AB;
}

5.级别管理

6.客户管理

7.管理员管理