10.5 add hardware

zrm_branch
ZhuRuimin 1 year ago
parent 3a3e07b552
commit d9be80547d

@ -0,0 +1,141 @@
import serial
error_codes = {
0x00: "成功",
0x01: "模组拒绝该命令",
0x02: "录入/匹配算法已终止",
0x03: "发送消息错误",
0x04: "相机打开失败",
0x05: "未知错误",
0x06: "无效的参数",
0x07: "内存不足",
0x08: "没有已录入的用户",
0x09: "录入超过最大用户数量",
0x0A: "人脸已录入",
0x0C: "活体检测失败",
0x0D: "录入或解锁超时",
0x0E: "加密芯片授权失败",
0x13: "读文件失败",
0x14: "写文件失败",
0x15: "通信协议未加密",
0x17: "RGB 图像没有 ready",
0xFD: "无效信息 IDkey 未写入",
0xFE: "检测错误",
0xFF: "编码错误"
}
status_codes = {
0x00: "人脸正常",
0x01: "未检测到人脸",
0x02: "人脸太靠近图片上边沿,未能录入",
0x03: "人脸太靠近图片下边沿,未能录入",
0x04: "人脸太靠近图片左边沿,未能录入",
0x05: "人脸太靠近图片右边沿,未能录入",
0x06: "人脸距离太远,未能录入",
0x07: "人脸距离太近,未能录入",
0x08: "眉毛遮挡",
0x09: "眼睛遮挡",
0x0A: "脸部遮挡",
0x0B: "录入人脸方向错误",
0x0C: "在闭眼模式检测到睁眼状态",
0x0D: "闭眼状态",
0x0E: "在闭眼模式检测中无法判定睁闭眼状态"
}
def face_recognition(time):
header = bytes([0xEF, 0xAA, 0x12, 0x00, 0x02])
time_bytes = time.to_bytes(2, byteorder='big')
# checksum = sum(bytes([0x12, 0x00, 0x02, 0x00]) + time_bytes) & 0xFF - 4
command = header + time_bytes
checksum = bytes([0x12, 0x00, 0x02]) + time_bytes
xor_result = 0
for byte in checksum:
xor_result ^= byte
command += bytes([xor_result])
return bytes(command)
def face_register(username, time):
header = bytes([0xEF, 0xAA, 0x26, 0x00, 0x28, 0x00])
username_bytes = username.encode('utf-8')
username_bytes = username_bytes.rjust(32, b'\x00')
time_bytes = time.to_bytes(1, byteorder='big')
direction = bytes([0x01, 0x01, 0x00]) + time_bytes + bytes([0x00, 0x00, 0x00])
command = header + username_bytes + direction
checksum = bytes([0x26, 0x00, 0x28, 0x00]) + username_bytes + direction
xor_result = 0
for byte in checksum:
xor_result ^= byte
command += bytes([xor_result])
return bytes(command)
def process_face_recognition_result(data, errorcode):
if errorcode == 0:
username = data[2:34].decode('utf-8')
print("用户名:", username)
elif errorcode in error_codes:
print("error:", error_codes[errorcode])
else:
print("未知错误码:", hex(errorcode))
def process_note_msg(command, errorcode, data):
# 在这里编写处理设备忙的情况的代码
print("note:", status_codes[command])
def process_face_register_result(data, errorcode):
if errorcode == 0:
print("注册成功")
elif errorcode in error_codes:
print("error:", error_codes[errorcode])
else:
print("未知错误码:", hex(errorcode))
def process_reply_msg(command, errorcode, data):
if command == 0x12:
process_face_recognition_result(data, errorcode)
elif command == 0x26:
process_face_register_result(data, errorcode)
else:
print("未知命令:", command)
def process_command(status, command, errorcode, data):
if status == 0x00:
process_reply_msg(command, errorcode, data)
return 1
elif status == 0x01:
process_note_msg(command, errorcode, data)
def read_serial_data(ser):
while ser.read() == bytes([0xEF]):
if ser.read() == bytes([0xAA]):
status = ser.read(1)[0]
if ser.in_waiting >= 2:
data_length_high = ser.read(1)[0]
data_length_low = ser.read(1)[0]
data_length = data_length_low + (data_length_high << 8) - 2
command = ser.read(1)[0]
errorcode = ser.read(1)[0]
data = ser.read(data_length)
checksum = ser.read(1)[0]
return process_command(status, command, errorcode, data)
# 打开串口连接
faceserial = serial.Serial("COM21", 115200, timeout=0.5)
print("启动人脸识别")
faceserial.write(face_recognition(10))
# faceserial.write(face_register("username", 15))
while True:
if read_serial_data(faceserial) == 1:
break
faceserial.close()

@ -0,0 +1,21 @@
import RPi.GPIO as GPIO
from mfrc522 import SimpleMFRC522
reader = SimpleMFRC522()
previous_id = None # 存储先前的卡号
try:
while True:
id, text = reader.read()
if id != previous_id:
print("===================================")
print("新卡号: {}".format(id))
print("===================================")
previous_id = id
print("文本信息: {}".format(text))
print("-----------------------------------")
finally:
GPIO.cleanup()

@ -0,0 +1,22 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "smartshop_be.settings")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == "__main__":
main()

@ -0,0 +1,8 @@
from django.contrib import admin
# Register your models here.
from .models import User, Product, Order
admin.site.register(User)
admin.site.register(Product)
admin.site.register(Order)

@ -0,0 +1,6 @@
from django.apps import AppConfig
class MyappConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'myapp'

@ -0,0 +1,33 @@
from django.db import models
class User(models.Model):
username = models.CharField(max_length=255)
password = models.CharField(max_length=255)
balance = models.IntegerField()
is_vip = models.BooleanField()
class Product(models.Model):
name = models.CharField(max_length=255)
price = models.DecimalField(max_digits=8, decimal_places=2)
stock = models.IntegerField()
class Order(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
is_paid = models.BooleanField()
user = models.ForeignKey(User, on_delete=models.CASCADE)
products = models.ManyToManyField(Product, through='OrderItem')
@property
def total_price(self):
order_items = self.orderitem_set.all()
total = sum(item.product.price * item.quantity for item in order_items)
return total
class OrderItem(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField()

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

@ -0,0 +1,63 @@
from django.http import JsonResponse
from django.shortcuts import render
# Create your views here.
def index(request):
return render(request, "back/base.html")
def user_management(request):
return render(request, "back/user_management.html")
def product_management(request):
return render(request, "back/product_management.html")
def order_management(request):
return render(request, "back/order_management.html")
def add_user(request):
if request.method == 'POST':
# 处理添加用户的逻辑
# 从请求中获取表单数据
username = request.POST.get('username')
balance = request.POST.get('balance')
vip = request.POST.get('vip') == 'on' # 处理复选框的值
# 执行添加用户的操作,例如保存到数据库
# 返回JSON响应表示用户已成功添加
return JsonResponse({'status': 'success'})
# 如果不是POST请求直接渲染页面
return render(request, 'front/user_management.html')
def refresh_users(request):
# 处理刷新用户列表的逻辑
# 查询数据库或执行其他操作以获取最新的用户列表
# 假设你有一个名为users的列表其中包含用户信息
users = [
{'username': 'User 1', 'balance': 100, 'vip': True},
{'username': 'User 2', 'balance': 200, 'vip': False},
{'username': 'User 3', 'balance': 150, 'vip': True},
]
# 返回JSON响应包含最新的用户列表
return JsonResponse({'users': users})
def login(request):
return render(request, "front/html/userLogin.html")
def sign(request):
return render(request, "front/html/userSign.html")
def cart(request):
return render(request, "front/html/shoppingCart.html")

@ -0,0 +1,16 @@
"""
ASGI config for smartshop_be project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "smartshop_be.settings")
application = get_asgi_application()

@ -0,0 +1,124 @@
"""
Django settings for smartshop_be project.
Generated by 'django-admin startproject' using Django 4.2.5.
For more information on this file, see
https://docs.djangoproject.com/en/4.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.2/ref/settings/
"""
import os.path
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = "django-insecure-$8)6@6t4p%(4-=f!q3mn$_!r9wl-s-h+!f+^xp=$&plwo3p670"
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"myapp.apps.MyappConfig",
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
ROOT_URLCONF = "smartshop_be.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [BASE_DIR / 'templates']
,
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
WSGI_APPLICATION = "smartshop_be.wsgi.application"
# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases
DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"NAME": "smartshop",
"USER": "root",
"PASSWORD": "Zrm5123856",
}
}
# Password validation
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",},
{"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",},
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",},
]
# Internationalization
# https://docs.djangoproject.com/en/4.2/topics/i18n/
LANGUAGE_CODE = "en-us"
TIME_ZONE = "UTC"
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/
STATIC_URL = "static/"
STATICFILES_DIRS = (
os.path.join(BASE_DIR,'templates/front'),
)
# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

@ -0,0 +1,35 @@
"""
URL configuration for smartshop_be project.
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.2/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from myapp import views
app_name = "admin"
urlpatterns = [
path("admin/", admin.site.urls),
path("back/", views.index, name="index"),
path("user_management/", views.user_management, name="user_management"),
path("product_management/", views.product_management, name="product_management"),
path("order_management/", views.order_management, name="order_management"),
path('add_user/', views.add_user, name='add_user'),
path('refresh_users/', views.refresh_users, name='refresh_users'),
path('login/', views.login, name='login'),
path('sign/', views.sign, name='sign'),
path('cart/', views.cart, name='cart'),
]

@ -0,0 +1,16 @@
"""
WSGI config for smartshop_be project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/4.2/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "smartshop_be.settings")
application = get_wsgi_application()

@ -0,0 +1,91 @@
<!-- base.html -->
<!DOCTYPE html>
<html lang="en">
<style>
/* styles.css */
/* 设置整体样式 */
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
/* 设置标题栏样式 */
header {
background-color: #333;
color: #fff;
padding: 20px;
}
h1 {
margin: 0;
}
/* 设置导航栏样式 */
nav ul {
list-style-type: none;
margin: 0;
padding: 0;
background-color: #f1f1f1;
}
nav li {
display: inline-block;
margin-right: 10px;
}
nav a {
display: block;
padding: 10px;
text-decoration: none;
color: #333;
}
nav a:hover {
background-color: #333;
color: #fff;
}
/* 设置主要内容区域样式 */
main {
padding: 20px;
}
/* 示例页面样式 */
.user-management-page {
background-color: #f9f9f9;
padding: 10px;
}
.product-management-page {
background-color: #f9f9f9;
padding: 10px;
}
.order-management-page {
background-color: #f9f9f9;
padding: 10px;
}
</style>
<head>
<meta charset="UTF-8">
<title>无人超市后台管理系统</title>
</head>
<body>
<header>
<h1>无人超市后台管理系统</h1>
</header>
<nav>
<ul>
<li><a href="{% url 'user_management' %}">用户管理</a></li>
<li><a href="{% url 'product_management' %}">商品管理</a></li>
<li><a href="{% url 'order_management' %}">订单管理</a></li>
</ul>
</nav>
<main>
{% block content %}
{% endblock %}
</main>
</body>
</html>

@ -0,0 +1,372 @@
<!-- order_management.html -->
{% extends 'back/base.html' %}
{% block content %}
<style>
/* 页面样式 */
body {
font-family: Arial, sans-serif;
}
h2 {
margin-bottom: 20px;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: 10px;
text-align: left;
border-bottom: 1px solid #ddd;
}
th {
background-color: #f2f2f2;
}
#add-order-btn,
#refresh-button {
padding: 10px 20px;
margin-bottom: 10px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.modal {
display: none;
position: fixed;
z-index: 999;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.4);
}
.modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 400px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
border-radius: 4px;
}
.close {
color: #888;
float: right;
font-size: 28px;
font-weight: bold;
cursor: pointer;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
#order-form label {
display: block;
margin-top: 10px;
}
#order-form input[type="text"],
#order-form input[type="number"],
#order-form input[type="checkbox"] {
width: 100%;
padding: 5px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
.modal-buttons {
margin-top: 20px;
text-align: right;
}
.modal-buttons button {
margin-left: 10px;
}
/* 其他样式 */
.overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.4);
z-index: 999;
}
</style>
<h2>订单管理</h2>
<button id="add-order-btn">添加订单</button>
<button id="refresh-button">刷新</button>
<table id="order-table">
<thead>
<tr>
<th>ID</th>
<th>用户名</th>
<th>金额</th>
<th>是否已支付</th>
<th>用户ID</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{# {% for order_profile in order_profiles %}#}
{# <tr>#}
{# <td>{{ order_profile.order.id }}</td>#}
{# <td>{{ order_profile.order.ordername }}</td>#}
{# <td>{{ order_profile.balance }}</td>#}
{# <td>{% if order_profile.is_vip %}是{% else %}否{% endif %}</td>#}
{# <td>{{ order_profile.face_id }}</td>#}
{# <td>#}
{# <button class="edit-button" data-order-id="{{ order_profile.order.id }}">修改</button>#}
{# <button class="delete-button" data-order-id="{{ order_profile.order.id }}">删除</button>#}
{# </td>#}
{# </tr>#}
{# {% endfor %}#}
<tr>
<td>1</td>
<td>张三</td>
<td>100</td>
<td></td>
<td>1</td>
<td>
<button class="edit-button" data-order-id="1">修改</button>
<button class="delete-button" data-order-id="1">删除</button>
</td>
</tr>
<tr>
<td>2</td>
<td>李四</td>
<td>200</td>
<td></td>
<td>2</td>
<td>
<button class="edit-button" data-order-id="2">修改</button>
<button class="delete-button" data-order-id="2">删除</button>
</td>
</tr>
</tbody>
</table>
<!-- 弹窗 -->
<div id="order-modal" class="modal">
<div class="modal-content">
<span class="close">&times;</span>
<h3 id="modal-title">添加订单</h3>
<form id="order-form">
<!-- 订单信息表单字段 -->
<input type="hidden" id="order-id" name="order-id">
<label for="ordername">用户名:</label>
<input type="text" id="ordername" name="ordername" required>
<label for="balance">金额:</label>
<input type="number" id="balance" name="balance" required>
<label for="vip">是否已支付:</label>
<input type="checkbox" id="vip" name="vip">
<!-- 保存和取消按钮 -->
<div class="modal-buttons">
<button type="submit" class="save-button">保存</button>
<button type="button" class="cancel-button">取消</button>
</div>
</form>
</div>
</div>
<script>
// 弹窗显示和隐藏
var modal = document.getElementById("order-modal");
var btn = document.getElementById("add-order-btn");
var span = document.getElementsByClassName("close")[0];
var form = document.getElementById("order-form");
var modalTitle = document.getElementById("modal-title");
var orderIdField = document.getElementById("order-id");
btn.onclick = function () {
modalTitle.textContent = "添加订单";
form.reset();
modal.style.display = "block";
}
span.onclick = function () {
modal.style.display = "none";
}
window.onclick = function (event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
// 刷新按钮点击事件
var refreshButton = document.getElementById("refresh-button");
refreshButton.addEventListener("click", function () {
// 在这里可以执行获取最新内容的操作
// 例如:通过 AJAX 请求获取最新的订单列表数据并刷新表格内容
});
// 页面加载完成后执行的操作
window.addEventListener("load", function () {
// 在这里可以执行页面加载完成后的操作
// 例如:初始化页面、获取初始数据等
});
// 修改按钮点击事件
var editButtons = document.querySelectorAll(".edit-button");
editButtons.forEach(function (button) {
button.addEventListener("click", function () {
var orderId = button.getAttribute("data-order-id");
modalTitle.textContent = "修改订单";
orderIdField.value = orderId;
// 根据订单ID获取其他订单信息并填充到表单中
// 可以通过 AJAX 请求获取订单信息
// 然后将订单信息填充到表单字段中
modal.style.display = "block";
});
});
// 删除按钮点击事件
var deleteButtons = document.querySelectorAll(".delete-button");
deleteButtons.forEach(function (button) {
button.addEventListener("click", function () {
var orderId = button.getAttribute("data-order-id");
// 根据订单ID执行删除订单操作
// 可以通过 AJAX 请求将订单ID发送到后端进行删除
// 然后可以根据返回的结果刷新订单列表或进行其他操作
});
});
// 添加/编辑订单表单提交
form.addEventListener("submit", function (event) {
event.preventDefault();
var orderId = orderIdField.value;
// 在这里可以通过 JavaScript 获取表单字段的值,进行保存等操作
// 例如:通过 AJAX 请求将表单数据发送到后端进行保存
// 然后可以根据返回的结果刷新订单列表或进行其他操作
modal.style.display = "none";
});
// 取消按钮点击事件
var cancelButton = document.querySelector(".cancel-button");
cancelButton.addEventListener("click", function () {
modal.style.display = "none";
});
$(document).ready(function() {
// 添加订单按钮点击事件
$('#add-order-btn').click(function() {
// 显示弹窗
$('#order-modal').show();
$('.overlay').show();
$('#modal-title').text('添加订单');
});
// 关闭弹窗按钮点击事件
$('.close').click(function() {
// 隐藏弹窗
$('#order-modal').hide();
$('.overlay').hide();
});
// 取消按钮点击事件
$('.cancel-button').click(function() {
// 隐藏弹窗
$('#order-modal').hide();
$('.overlay').hide();
});
// 保存按钮点击事件
$('.save-button').click(function(e) {
e.preventDefault();
// 获取表单数据
var ordername = $('#ordername').val();
var balance = $('#balance').val();
var vip = $('#vip').is(':checked');
// 发送POST请求到添加订单的URL
$.ajax({
url: '/add_order/',
type: 'POST',
data: {
'ordername': ordername,
'balance': balance,
'vip': vip
},
success: function(response) {
// 添加订单成功后的处理逻辑
// 隐藏弹窗
$('#order-modal').hide();
$('.overlay').hide();
// 清空表单数据
$('#ordername').val('');
$('#balance').val('');
$('#vip').prop('checked', false);
// 刷新订单列表
refreshOrderTable();
},
error: function(xhr, errmsg, err) {
// 处理错误情况
console.log(errmsg);
}
});
});
// 刷新按钮点击事件
$('#refresh-button').click(function() {
// 刷新订单列表
refreshOrderTable();
});
// 刷新订单列表函数
function refreshOrderTable() {
// 发送GET请求到刷新订单列表的URL
$.ajax({
url: '/refresh_orders/',
type: 'GET',
success: function(response) {
// 更新订单列表
var orders = response.orders;
var tableBody = $('#order-table tbody');
tableBody.empty();
for (var i = 0; i < orders.length; i++) {
var order = orders[i];
var row = '<tr>' +
'<td>' + order.ordername + '</td>' +
'<td>' + order.balance + '</td>' +
'<td>' + (order.vip ? '是' : '否') + '</td>' +
'</tr>';
tableBody.append(row);
}
},
error: function(xhr, errmsg, err) {
// 处理错误情况
console.log(errmsg);
}
});
}
// 页面加载时刷新订单列表
refreshOrderTable();
});
</script>
{% endblock %}

@ -0,0 +1,368 @@
<!-- product_management.html -->
{% extends 'back/base.html' %}
{% block content %}
<style>
/* 页面样式 */
body {
font-family: Arial, sans-serif;
}
h2 {
margin-bottom: 20px;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: 10px;
text-align: left;
border-bottom: 1px solid #ddd;
}
th {
background-color: #f2f2f2;
}
#add-product-btn,
#refresh-button {
padding: 10px 20px;
margin-bottom: 10px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.modal {
display: none;
position: fixed;
z-index: 999;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.4);
}
.modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 400px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
border-radius: 4px;
}
.close {
color: #888;
float: right;
font-size: 28px;
font-weight: bold;
cursor: pointer;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
#product-form label {
display: block;
margin-top: 10px;
}
#product-form input[type="text"],
#product-form input[type="number"],
#product-form input[type="checkbox"] {
width: 100%;
padding: 5px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
.modal-buttons {
margin-top: 20px;
text-align: right;
}
.modal-buttons button {
margin-left: 10px;
}
/* 其他样式 */
.overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.4);
z-index: 999;
}
</style>
<h2>商品管理</h2>
<button id="add-product-btn">新增库存</button>
<button id="refresh-button">刷新</button>
<table id="product-table">
<thead>
<tr>
<th>ID</th>
<th>商品名</th>
<th>单价(单位:分)</th>
<th>剩余库存</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{# {% for user_profile in user_profiles %}#}
{# <tr>#}
{# <td>{{ user_profile.user.id }}</td>#}
{# <td>{{ user_profile.user.username }}</td>#}
{# <td>{{ user_profile.balance }}</td>#}
{# <td>{% if user_profile.is_vip %}是{% else %}否{% endif %}</td>#}
{# <td>{{ user_profile.face_id }}</td>#}
{# <td>#}
{# <button class="edit-button" data-user-id="{{ user_profile.user.id }}">修改</button>#}
{# <button class="delete-button" data-user-id="{{ user_profile.user.id }}">删除</button>#}
{# </td>#}
{# </tr>#}
{# {% endfor %}#}
<tr>
<td>1</td>
<td>可乐</td>
<td>300</td>
<td>20</td>
<td>
<button class="edit-button" data-product-id="1">修改</button>
<button class="delete-button" data-product-id="1">删除</button>
</td>
</tr>
<tr>
<td>2</td>
<td>雪碧</td>
<td>300</td>
<td>20</td>
<td>
<button class="edit-button" data-product-id="2">修改</button>
<button class="delete-button" data-product-id="2">删除</button>
</tr>
</tbody>
</table>
<!-- 弹窗 -->
<div id="product-modal" class="modal">
<div class="modal-content">
<span class="close">&times;</span>
<h3 id="modal-title">添加商品</h3>
<form id="product-form">
<!-- 商品信息表单字段 -->
<input type="hidden" id="product-id" name="product-id">
<label for="productname">商品名:</label>
<input type="text" id="productname" name="productname" required>
<label for="price">单价(单位:分)</label>
<input type="number" id="price" name="price" required>
<label for="stock">库存:</label>
<input type="number" id="stock" name="stock" required>
<!-- 保存和取消按钮 -->
<div class="modal-buttons">
<button type="submit" class="save-button">保存</button>
<button type="button" class="cancel-button">取消</button>
</div>
</form>
</div>
</div>
<script>
// 弹窗显示和隐藏
var modal = document.getElementById("product-modal");
var btn = document.getElementById("add-product-btn");
var span = document.getElementsByClassName("close")[0];
var form = document.getElementById("product-form");
var modalTitle = document.getElementById("modal-title");
var productIdField = document.getElementById("product-id");
btn.onclick = function () {
modalTitle.textContent = "添加商品";
form.reset();
modal.style.display = "block";
}
span.onclick = function () {
modal.style.display = "none";
}
window.onclick = function (event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
// 刷新按钮点击事件
var refreshButton = document.getElementById("refresh-button");
refreshButton.addEventListener("click", function () {
// 在这里可以执行获取最新内容的操作
// 例如:通过 AJAX 请求获取最新的商品列表数据并刷新表格内容
});
// 页面加载完成后执行的操作
window.addEventListener("load", function () {
// 在这里可以执行页面加载完成后的操作
// 例如:初始化页面、获取初始数据等
});
// 修改按钮点击事件
var editButtons = document.querySelectorAll(".edit-button");
editButtons.forEach(function (button) {
button.addEventListener("click", function () {
var productId = button.getAttribute("data-product-id");
modalTitle.textContent = "修改商品";
productIdField.value = productId;
// 根据商品ID获取其他商品信息并填充到表单中
// 可以通过 AJAX 请求获取商品信息
// 然后将商品信息填充到表单字段中
modal.style.display = "block";
});
});
// 删除按钮点击事件
var deleteButtons = document.querySelectorAll(".delete-button");
deleteButtons.forEach(function (button) {
button.addEventListener("click", function () {
var productId = button.getAttribute("data-product-id");
// 根据商品ID执行删除商品操作
// 可以通过 AJAX 请求将商品ID发送到后端进行删除
// 然后可以根据返回的结果刷新商品列表或进行其他操作
});
});
// 添加/编辑商品表单提交
form.addEventListener("submit", function (event) {
event.preventDefault();
var productId = productIdField.value;
// 在这里可以通过 JavaScript 获取表单字段的值,进行保存等操作
// 例如:通过 AJAX 请求将表单数据发送到后端进行保存
// 然后可以根据返回的结果刷新商品列表或进行其他操作
modal.style.display = "none";
});
// 取消按钮点击事件
var cancelButton = document.querySelector(".cancel-button");
cancelButton.addEventListener("click", function () {
modal.style.display = "none";
});
$(document).ready(function() {
// 添加商品按钮点击事件
$('#add-product-btn').click(function() {
// 显示弹窗
$('#product-modal').show();
$('.overlay').show();
$('#modal-title').text('添加商品');
});
// 关闭弹窗按钮点击事件
$('.close').click(function() {
// 隐藏弹窗
$('#product-modal').hide();
$('.overlay').hide();
});
// 取消按钮点击事件
$('.cancel-button').click(function() {
// 隐藏弹窗
$('#product-modal').hide();
$('.overlay').hide();
});
// 保存按钮点击事件
$('.save-button').click(function(e) {
e.preventDefault();
// 获取表单数据
var productname = $('#productname').val();
var balance = $('#balance').val();
var vip = $('#vip').is(':checked');
// 发送POST请求到添加商品的URL
$.ajax({
url: '/add_product/',
type: 'POST',
data: {
'productname': productname,
'balance': balance,
'vip': vip
},
success: function(response) {
// 添加商品成功后的处理逻辑
// 隐藏弹窗
$('#product-modal').hide();
$('.overlay').hide();
// 清空表单数据
$('#productname').val('');
$('#balance').val('');
$('#vip').prop('checked', false);
// 刷新商品列表
refreshproductTable();
},
error: function(xhr, errmsg, err) {
// 处理错误情况
console.log(errmsg);
}
});
});
// 刷新按钮点击事件
$('#refresh-button').click(function() {
// 刷新商品列表
refreshproductTable();
});
// 刷新商品列表函数
function refreshproductTable() {
// 发送GET请求到刷新商品列表的URL
$.ajax({
url: '/refresh_products/',
type: 'GET',
success: function(response) {
// 更新商品列表
var products = response.products;
var tableBody = $('#product-table tbody');
tableBody.empty();
for (var i = 0; i < products.length; i++) {
var product = products[i];
var row = '<tr>' +
'<td>' + product.productname + '</td>' +
'<td>' + product.balance + '</td>' +
'<td>' + (product.vip ? '是' : '否') + '</td>' +
'</tr>';
tableBody.append(row);
}
},
error: function(xhr, errmsg, err) {
// 处理错误情况
console.log(errmsg);
}
});
}
// 页面加载时刷新商品列表
refreshproductTable();
});
</script>
{% endblock %}

@ -0,0 +1,372 @@
<!-- user_management.html -->
{% extends 'back/base.html' %}
{% block content %}
<style>
/* 页面样式 */
body {
font-family: Arial, sans-serif;
}
h2 {
margin-bottom: 20px;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: 10px;
text-align: left;
border-bottom: 1px solid #ddd;
}
th {
background-color: #f2f2f2;
}
#add-user-btn,
#refresh-button {
padding: 10px 20px;
margin-bottom: 10px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.modal {
display: none;
position: fixed;
z-index: 999;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.4);
}
.modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 400px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
border-radius: 4px;
}
.close {
color: #888;
float: right;
font-size: 28px;
font-weight: bold;
cursor: pointer;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
#user-form label {
display: block;
margin-top: 10px;
}
#user-form input[type="text"],
#user-form input[type="number"],
#user-form input[type="checkbox"] {
width: 100%;
padding: 5px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
.modal-buttons {
margin-top: 20px;
text-align: right;
}
.modal-buttons button {
margin-left: 10px;
}
/* 其他样式 */
.overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.4);
z-index: 999;
}
</style>
<h2>用户管理</h2>
<button id="add-user-btn">添加用户</button>
<button id="refresh-button">刷新</button>
<table id="user-table">
<thead>
<tr>
<th>ID</th>
<th>用户名</th>
<th>余额</th>
<th>VIP</th>
<th>人脸ID</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{# {% for user_profile in user_profiles %}#}
{# <tr>#}
{# <td>{{ user_profile.user.id }}</td>#}
{# <td>{{ user_profile.user.username }}</td>#}
{# <td>{{ user_profile.balance }}</td>#}
{# <td>{% if user_profile.is_vip %}是{% else %}否{% endif %}</td>#}
{# <td>{{ user_profile.face_id }}</td>#}
{# <td>#}
{# <button class="edit-button" data-user-id="{{ user_profile.user.id }}">修改</button>#}
{# <button class="delete-button" data-user-id="{{ user_profile.user.id }}">删除</button>#}
{# </td>#}
{# </tr>#}
{# {% endfor %}#}
<tr>
<td>1</td>
<td>张三</td>
<td>100</td>
<td></td>
<td>1</td>
<td>
<button class="edit-button" data-user-id="1">修改</button>
<button class="delete-button" data-user-id="1">删除</button>
</td>
</tr>
<tr>
<td>2</td>
<td>李四</td>
<td>200</td>
<td></td>
<td>2</td>
<td>
<button class="edit-button" data-user-id="2">修改</button>
<button class="delete-button" data-user-id="2">删除</button>
</td>
</tr>
</tbody>
</table>
<!-- 弹窗 -->
<div id="user-modal" class="modal">
<div class="modal-content">
<span class="close">&times;</span>
<h3 id="modal-title">添加用户</h3>
<form id="user-form">
<!-- 用户信息表单字段 -->
<input type="hidden" id="user-id" name="user-id">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" required>
<label for="balance">余额:</label>
<input type="number" id="balance" name="balance" required>
<label for="vip">VIP:</label>
<input type="checkbox" id="vip" name="vip">
<!-- 保存和取消按钮 -->
<div class="modal-buttons">
<button type="submit" class="save-button">保存</button>
<button type="button" class="cancel-button">取消</button>
</div>
</form>
</div>
</div>
<script>
// 弹窗显示和隐藏
var modal = document.getElementById("user-modal");
var btn = document.getElementById("add-user-btn");
var span = document.getElementsByClassName("close")[0];
var form = document.getElementById("user-form");
var modalTitle = document.getElementById("modal-title");
var userIdField = document.getElementById("user-id");
btn.onclick = function () {
modalTitle.textContent = "添加用户";
form.reset();
modal.style.display = "block";
}
span.onclick = function () {
modal.style.display = "none";
}
window.onclick = function (event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
// 刷新按钮点击事件
var refreshButton = document.getElementById("refresh-button");
refreshButton.addEventListener("click", function () {
// 在这里可以执行获取最新内容的操作
// 例如:通过 AJAX 请求获取最新的用户列表数据并刷新表格内容
});
// 页面加载完成后执行的操作
window.addEventListener("load", function () {
// 在这里可以执行页面加载完成后的操作
// 例如:初始化页面、获取初始数据等
});
// 修改按钮点击事件
var editButtons = document.querySelectorAll(".edit-button");
editButtons.forEach(function (button) {
button.addEventListener("click", function () {
var userId = button.getAttribute("data-user-id");
modalTitle.textContent = "修改用户";
userIdField.value = userId;
// 根据用户ID获取其他用户信息并填充到表单中
// 可以通过 AJAX 请求获取用户信息
// 然后将用户信息填充到表单字段中
modal.style.display = "block";
});
});
// 删除按钮点击事件
var deleteButtons = document.querySelectorAll(".delete-button");
deleteButtons.forEach(function (button) {
button.addEventListener("click", function () {
var userId = button.getAttribute("data-user-id");
// 根据用户ID执行删除用户操作
// 可以通过 AJAX 请求将用户ID发送到后端进行删除
// 然后可以根据返回的结果刷新用户列表或进行其他操作
});
});
// 添加/编辑用户表单提交
form.addEventListener("submit", function (event) {
event.preventDefault();
var userId = userIdField.value;
// 在这里可以通过 JavaScript 获取表单字段的值,进行保存等操作
// 例如:通过 AJAX 请求将表单数据发送到后端进行保存
// 然后可以根据返回的结果刷新用户列表或进行其他操作
modal.style.display = "none";
});
// 取消按钮点击事件
var cancelButton = document.querySelector(".cancel-button");
cancelButton.addEventListener("click", function () {
modal.style.display = "none";
});
$(document).ready(function() {
// 添加用户按钮点击事件
$('#add-user-btn').click(function() {
// 显示弹窗
$('#user-modal').show();
$('.overlay').show();
$('#modal-title').text('添加用户');
});
// 关闭弹窗按钮点击事件
$('.close').click(function() {
// 隐藏弹窗
$('#user-modal').hide();
$('.overlay').hide();
});
// 取消按钮点击事件
$('.cancel-button').click(function() {
// 隐藏弹窗
$('#user-modal').hide();
$('.overlay').hide();
});
// 保存按钮点击事件
$('.save-button').click(function(e) {
e.preventDefault();
// 获取表单数据
var username = $('#username').val();
var balance = $('#balance').val();
var vip = $('#vip').is(':checked');
// 发送POST请求到添加用户的URL
$.ajax({
url: '/add_user/',
type: 'POST',
data: {
'username': username,
'balance': balance,
'vip': vip
},
success: function(response) {
// 添加用户成功后的处理逻辑
// 隐藏弹窗
$('#user-modal').hide();
$('.overlay').hide();
// 清空表单数据
$('#username').val('');
$('#balance').val('');
$('#vip').prop('checked', false);
// 刷新用户列表
refreshUserTable();
},
error: function(xhr, errmsg, err) {
// 处理错误情况
console.log(errmsg);
}
});
});
// 刷新按钮点击事件
$('#refresh-button').click(function() {
// 刷新用户列表
refreshUserTable();
});
// 刷新用户列表函数
function refreshUserTable() {
// 发送GET请求到刷新用户列表的URL
$.ajax({
url: '/refresh_users/',
type: 'GET',
success: function(response) {
// 更新用户列表
var users = response.users;
var tableBody = $('#user-table tbody');
tableBody.empty();
for (var i = 0; i < users.length; i++) {
var user = users[i];
var row = '<tr>' +
'<td>' + user.username + '</td>' +
'<td>' + user.balance + '</td>' +
'<td>' + (user.vip ? '是' : '否') + '</td>' +
'</tr>';
tableBody.append(row);
}
},
error: function(xhr, errmsg, err) {
// 处理错误情况
console.log(errmsg);
}
});
}
// 页面加载时刷新用户列表
refreshUserTable();
});
</script>
{% endblock %}

@ -0,0 +1,130 @@
.welcome{
text-align: center;
/* 文字上下居中 */
line-height: 20vh;
/* font-size: 50px; */
color: #fff;
background-color: rgb(7, 193, 96);
/* 字体大小 */
font-size: 80px;
height: 20vh;
margin: 0 auto;
}
.product {
/* border: 1px solid #ccc; */
/* 边距 */
padding: 10px;
/* display: inline-block; */
/* 对齐方式 */
/* float: left; */
/* 宽度 */
width: 100vw;
/* text-align: center; */
/* 边框 */
border: 1px solid #ccc;
/* 有边框的box */
box-sizing: border-box;
display: inline-block;
height: 15vh;
}
.product img {
width: 15vh;
height: 15vh;
margin-bottom: 10px;
padding: 10px;
}
.product h3 {
margin: 0;
font-size: 50px;
}
.ProductInfo{
color: #888;
margin: 0;
font-size: 40px;
}
body {
height: 100%;
margin: 0;
padding: 0;
}
.container {
min-height: 100%;
position: dynamic;
}
.content {
padding-bottom: 50px; /* 为按钮预留空间 */
}
.footer {
position: absolute;
bottom: 0;
width: 100%;
height: 50px;
background-color: #f5f5f5;
text-align: center;
}
.footer button {
margin-top: 10px;
}
*{
box-sizing: border-box;
background-color: rgb(202, 249, 224);
}
.ProductImage{
float: left;
margin-right: 10px;
}
.ProductName{
font-size: 30px;
margin-top: 0px;
margin-left: 0px;
}
.proceed{
/* 位于页面底部距离底部5vh,左右居中 */
position: fixed;
bottom: 3vh;
left: 50%;
transform: translateX(-50%);
/* 字体大小 */
font-size: 50px;
}
button{
/* 字体大小 */
font-size: 50px;
/* 字体颜色 */
color: #7E7E7E;
/* 背景颜色 */
background-color: rgb(202, 249, 224);
/* 居中 */
text-align: center;
/* 边框 */
/* 圆角 */
border-radius: 10px;
/* 边框比内部文字大一点 */
padding: 10px 20px;
}
.price{
position: absolute;
right: 5vw;
bottom: auto;
color: red;
font-size: 60px;
/* 文本加粗 */
font-weight: bold;
}

@ -0,0 +1,102 @@
.welcome{
text-align: center;
/* 文字上下居中 */
line-height: 20vh;
/* font-size: 50px; */
color: #fff;
background-color: rgb(7, 193, 96);
/* 字体大小 */
font-size: 80px;
height: 20vh;
margin: 0 auto;
}
main.photo{
/* 居中 */
margin: 0 auto;
}
main {
/* 对齐方式 */
text-align: center;
/* 字体大小 */
font-size: 40px;
/* 字体颜色 */
color: rgb(79, 61, 61);
/* 背景颜色 */
background-color: rgb(202, 249, 224);
/* 背景颜色无限延申 */
background-repeat: repeat;
margin: 0 auto;
/* 紧挨上文 */
margin-top: 0px;
}
footer {
/* 对齐方式 */
text-align: center;
/* 字体大小 */
font-size: 40px;
/* 字体颜色 */
color: rgb(79, 61, 61);
/* 背景颜色 */
background-color: rgb(202, 249, 224);
margin: 0 auto;
}
button{
/* 字体大小 */
font-size: 30px;
/* 字体颜色 */
color: #7E7E7E;
/* 背景颜色 */
background-color: rgb(202, 249, 224);
/* 居中 */
text-align: center;
/* 边框 */
/* 圆角 */
border-radius: 10px;
/* 边框比内部文字大一点 */
padding: 10px 20px;
}
button:hover{
background-color: grey;
color: #fff;
}
button:active{
background-color: rgb(20, 28, 20);
color: #fff;
}
.TextFace{
color: #7E7E7E;
margin-top: 20vh;
font-size: 60px;
}
*{
box-sizing: border-box;
background-color: rgb(202, 249, 224);
}
.reg{
/* 位于页面底部距离底部5vh,左右居中 */
position: fixed;
bottom: 3vh;
left: 50%;
transform: translateX(-50%);
/* 字体大小 */
font-size: 40px;
}
.photo{
/* 上下居中 */
margin: 0 auto;
/* 放大 */
transform: scale(1.5);
/* 下移10vh */
margin-top: 15vh;
}

@ -0,0 +1,53 @@
.welcome{
text-align: center;
/* 文字上下居中 */
line-height: 20vh;
/* font-size: 50px; */
color: #fff;
background-color: rgb(7, 193, 96);
/* 字体大小 */
font-size: 80px;
height: 20vh;
margin: 0 auto;
}
.form{
font-size: 40px;
margin: 20px;
}
input{
font-size: 40px;
/* 圆角 */
border-radius: 10px;
height: 5vh;
margin: 1vh;
}
*{
box-sizing: border-box;
background-color: rgb(202, 249, 224);
}
.submit{
/* 位于页面底部距离底部5vh,左右居中 */
position: fixed;
bottom: 3vh;
left: 50%;
transform: translateX(-50%);
/* 字体大小 */
font-size: 50px;
/* 字体大小 */
font-size: 50px;
/* 字体颜色 */
color: #7E7E7E;
/* 背景颜色 */
background-color: rgb(202, 249, 224);
/* 居中 */
text-align: center;
/* 边框 */
/* 圆角 */
border-radius: 10px;
/* 边框比内部文字大一点 */
padding: 10px 20px;
}

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>无人超市--购物车</title>
<link rel="stylesheet" href="../static/css/shoppingCart.css">
</head>
<main>
<h1 class="welcome">无人超市购物车</h1>
<!-- <canvas id="gifFace" width="300" height="300"> </canvas> -->
<!-- <div><img src="smartshop/img/face.gif" alt="face"></div> -->
</main>
<body>
<!-- 把下面的东西放入一个列表-->
<div class="product">
<img src="../static/img/product1.jpg" alt="Product Image" class="ProductImage">
<h3 class="ProductName">旺仔小馒头</h3>
<p class="ProductInfo">好吃爱吃</p>
<p class="price">¥4.50</p>
</div>
<div class="product">
<img src="../static/img/product2.jpg" alt="Product Image" class="ProductImage">
<h3 class="ProductName">乐事薯片</h3>
<p class="ProductInfo">好吃爱吃</p>
<p class="price">¥5.50</p>
</div>
<div class="product">
<img src="../static/img/product1.jpg" alt="Product Image" class="ProductImage">
<h3 class="ProductName">旺仔小馒头</h3>
<p class="ProductInfo">好吃爱吃</p>
<p class="price">¥4.50</p>
</div>
<div class="product">
<img src="../static/img/product1.jpg" alt="Product Image" class="ProductImage">
<h3 class="ProductName">旺仔小馒头</h3>
<p class="ProductInfo">好吃爱吃</p>
<p class="price">¥4.50</p>
</div>
<div class="container">
<div class="content">
<!-- 页面内容 -->
</div>
<div>
<button class="proceed">确认支付</button>
</div>
</div>
</body>
</html>

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>欢迎使用无人超市</title>
<link rel="stylesheet" href="../static/css/userLogin.css">
</head>
<main>
<h1 class="welcome">欢迎使用无人超市</h1>
<!-- <canvas id="gifFace" width="300" height="300"> </canvas> -->
<!-- <div><img src="smartshop/img/face.gif" alt="face"></div>
-->
<!-- 插入GIF图片--失败 -->
<div><img src="../static/img/face-unscreen.gif" alt="face" class="photo"></div>
<!-- <br> -->
<p class="TextFace">请靠近识别人脸</p>
<button type="button" class="reg">注册新用户</button>
</main>
<script>
//点击button后跳转到注册页面
var reg = document.getElementsByClassName("reg")[0];
reg.onclick = function(){
window.location.href = "/sign/";
}
</script>
</html>

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>欢迎使用无人超市</title>
<link rel="stylesheet" href="../static/css/userSign.css">
</head>
<main>
<h1 class="welcome">用户注册</h1>
<!-- <canvas id="gifFace" width="300" height="300"> </canvas> -->
<!-- <div><img src="smartshop/img/face.gif" alt="face"></div> -->
</main>
<br>
<form action="../static/js/userSign.js" method="POST" class="form">
<br>
<div style="text-align: center;">
<label>用户名</label>
<!-- name属性是必须的,用来提交给数据库 -->
<input type="text" name="用户名" placeholder="请输入用户名">
</div>
<br>
<div style="text-align: center;">
<label>密码</label>
<!-- name属性是必须的,用来提交给数据库 -->
<input type="password" name="密码" placeholder="请输入密码">
</div>
<br>
<div style="text-align: center;">
<label>确认密码</label>
<!-- name属性是必须的,用来提交给数据库 -->
<input type="password" name="确认密码" placeholder="请再次输入密码">
</div>
<br>
<!-- 居中 -->
<div style="text-align: center;"><input class="submit" type="submit" name="提交" value="提交"></div>
</form>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

@ -0,0 +1 @@
window.location.href = "/login/";
Loading…
Cancel
Save