大转盘活动系统【原创】

前端功能:登录(微信公众号登录,微信扫码登录);抽奖方式(在线支付抽奖,激活码抽奖);支付(对接微信公众号支付,余额支付);抽奖码(后台无限刷生成抽奖码 随机生成和自定义生成抽奖码)查询订单,分站(用户可以开通分站功能要主站一样);海报生成及相关功能
后端功能:首页配置(修改添加各种首页信息);系统配置(一些相关的功能);抽奖码管理(生成抽奖码);奖品管理(添加奖品,删除奖品,编辑奖品,中奖概率,指定商品或抽奖码中奖及其他核心功能);用户管理(用户id,用户名,用户头像,用户余额及其他功能);订单管理(几等奖,奖品收货地址,付款方式,中奖id及其他核心功能);分站管理(分站用户列表 分站名称 站长名称,所属用户,下级及其他核心功能)等
开发语言:前端:HTML CSS JS ;后端:thinkPHP7.4版本;数据库:MySQL

下图为参考,不是真是效果,真实效果及功能简直就是无敌!!!

图片[1]-大转盘活动系统【原创】-[:ug]Waris[:zh]Waris[:]

第一批:项目基础结构与前端页面
1.项目目录结构

bash

project-root/
├── admin/ # 后台管理系统
│ ├── index.php # 后台首页
│ ├── conf/ # 配置文件
│ │ └── database.php # 数据库连接配置
│ ├── controllers/ # 后台控制器
│ │ └── PrizeController.php # 奖品管理控制器
│ ├── models/ # 后台数据模型
│ │ └── PrizeModel.php # 奖品模型
│ ├── views/ # 后台视图文件
│ │ ├── prize/ # 奖品管理视图
│ │ │ └── index.html # 奖品管理页面
│ └── ... # 其他管理相关模块
├── frontend/ # 前端页面
│ ├── index.html # 前端首页(大转盘页面)
│ ├── login.html # 登录页面
│ ├── css/ # CSS样式
│ │ └── style.css # 页面样式文件
│ ├── js/ # 前端JS文件
│ │ ├── main.js # 大转盘抽奖逻辑
│ │ ├── payment.js # 支付功能相关JS
│ ├── images/ # 页面所需图片
│ └── ... # 其他页面或文件
├── config/ # 项目配置
│ ├── database.php # 数据库连接配置
│ ├── payment.php # 支付配置(微信支付等)
├── runtime/ # ThinkPHP运行时目录
│ ├── cache/ # 缓存目录
│ ├── logs/ # 日志目录
├── thinkphp/ # ThinkPHP框架文件
│ ├── ... # 框架核心文件
└── README.md # 项目文档
  1. 前端页面
    2.1 index.html – 大转盘页面
    这是用户进入活动后看到的大转盘页面,包含转盘、登录、支付等功能。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>大转盘抽奖活动</title>
    <link rel="stylesheet" href="css/style.css">
</head>
<body>
    <header>
        <h1>欢迎参加抽奖活动</h1>
    </header>

    <div class="lottery-wheel">
        <!-- 转盘 -->
        <div id="wheel" class="wheel"></div>
        <button id="spin-btn">开始抽奖</button>
    </div>

    <div id="prize-result" class="prize-result"></div>
    
    <script src="js/main.js"></script>
</body>
</html>

2.2 login.html – 登录页面
这是用户扫码登录的页面,提供一个扫码登录的入口。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>微信扫码登录</title>
</head>
<body>
    <h1>微信扫码登录</h1>
    <div id="qr-code">
        <!-- 微信二维码将在这里生成 -->
    </div>
    <button onclick="initiateWeChatLogin()">扫码登录</button>

    <script src="js/payment.js"></script>
</body>
</html>

2.3 css/style.css – 样式文件

body {
    font-family: Arial, sans-serif;
    text-align: center;
}

header {
    margin-top: 50px;
}

.lottery-wheel {
    margin-top: 50px;
    display: flex;
    justify-content: center;
    flex-direction: column;
    align-items: center;
}

.wheel {
    width: 300px;
    height: 300px;
    background-color: #ffcc00;
    border-radius: 50%;
    position: relative;
}

#spin-btn {
    margin-top: 20px;
    padding: 10px 20px;
    background-color: #008CBA;
    color: white;
    border: none;
    cursor: pointer;
}

#spin-btn:hover {
    background-color: #005f73;
}

.prize-result {
    margin-top: 20px;
    font-size: 20px;
    color: green;
}

2.4 js/main.js – 大转盘逻辑

// main.js

document.getElementById('spin-btn').addEventListener('click', spinWheel);

function spinWheel() {
    const wheel = document.getElementById('wheel');
    let deg = Math.floor(Math.random() * 360);
    
    // 动画实现
    wheel.style.transition = 'transform 4s ease-out';
    wheel.style.transform = `rotate(${deg + 3600}deg)`; // 转盘旋转

    // 设置抽奖结果,模拟延迟
    setTimeout(() => {
        const prize = getPrize(deg);
        document.getElementById('prize-result').textContent = `恭喜你,获得了:${prize}`;
    }, 4000); // 延迟4秒,等待转盘旋转完成
}

function getPrize(deg) {
    // 模拟奖品判定
    if (deg >= 0 && deg < 45) {
        return "一等奖";
    } else if (deg >= 45 && deg < 90) {
        return "二等奖";
    } else if (deg >= 90 && deg < 135) {
        return "三等奖";
    } else {
        return "谢谢参与";
    }
}
  1. 后端基础:ThinkPHP 控制器和数据库配置
    3.1 config/database.php – 数据库连接配置
<?php
// config/database.php
return [
    'type'        => 'mysql',      // 数据库类型
    'hostname'    => '127.0.0.1',  // 数据库地址
    'database'    => 'lottery',    // 数据库名
    'username'    => 'root',       // 用户名
    'password'    => '',           // 密码
    'hostport'    => '3306',       // 端口
    'charset'     => 'utf8',       // 字符集
    'prefix'      => 'lottery_',   // 数据表前缀
];

3.2 admin/controllers/PrizeController.php – 奖品管理控制器

<?php
namespace app\admin\controller;
use think\Controller;
use think\Request;
use app\admin\model\PrizeModel;

class PrizeController extends Controller
{
    // 添加奖品
    public function addPrize(Request $request)
    {
        $prizeData = $request->post();
        $prizeModel = new PrizeModel();
        $result = $prizeModel->addPrize($prizeData);
        
        if ($result) {
            return json(['message' => 'Prize added successfully']);
        } else {
            return json(['message' => 'Failed to add prize']);
        }
    }

    // 获取奖品列表
    public function getPrizes()
    {
        $prizes = PrizeModel::all();
        return json($prizes);
    }
}

3.3 admin/models/PrizeModel.php – 奖品模型

<?php
namespace app\admin\model;
use think\Model;

class PrizeModel extends Model
{
    protected $table = 'prizes';  // 数据表名称

    public function addPrize($data)
    {
        return $this->insert($data);
    }

    public function getAllPrizes()
    {
        return $this->select();
    }
}
  1. 数据库设计
    以下是与奖品管理相关的表结构:
CREATE TABLE `lottery_prizes` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `name` VARCHAR(255) NOT NULL,
    `probability` DECIMAL(5,2) NOT NULL, -- 奖品中奖概率
    `type` VARCHAR(255) NOT NULL         -- 奖品类型
);

-- 示例数据
INSERT INTO `lottery_prizes` (`name`, `probability`, `type`) 
VALUES ('一等奖', 5, '实物'),
       ('二等奖', 10, '实物'),
       ('三等奖', 20

后端部分(订单管理、支付接口等)

  1. 订单管理
    1.1 admin/controllers/OrderController.php – 订单管理控制器
    这个控制器用于管理订单,包括查询和更新订单状态等。
<?php
namespace app\admin\controller;
use think\Controller;
use think\Request;
use app\admin\model\OrderModel;

class OrderController extends Controller
{
    // 获取所有订单
    public function getOrders()
    {
        $orders = OrderModel::all();
        return json($orders);
    }

    // 更新订单状态
    public function updateOrderStatus(Request $request, $id)
    {
        $status = $request->post('status');
        $orderModel = OrderModel::find($id);
        
        if ($orderModel) {
            $orderModel->status = $status;
            $orderModel->save();
            return json(['message' => 'Order status updated successfully']);
        } else {
            return json(['message' => 'Order not found']);
        }
    }
}

1.2 admin/models/OrderModel.php – 订单模型
该模型用于操作订单数据。

<?php
namespace app\admin\model;
use think\Model;

class OrderModel extends Model
{
    protected $table = 'orders';  // 数据表名称

    public function createOrder($userId, $prizeId, $status, $paymentMethod)
    {
        return $this->insert([
            'user_id' => $userId,
            'prize_id' => $prizeId,
            'status' => $status,
            'payment_method' => $paymentMethod,
            'created_at' => date('Y-m-d H:i:s')
        ]);
    }

    public function getAllOrders()
    {
        return $this->select();
    }

    public function updateOrder($orderData)
    {
        return $this->update($orderData);
    }
}

1.3 database.sql – 订单表结构
以下是订单表的结构,存储用户订单信息,包括订单状态、支付方式等。

CREATE TABLE `orders` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `user_id` INT NOT NULL,
    `prize_id` INT NOT NULL,
    `status` ENUM('paid', 'unpaid') NOT NULL,
    `payment_method` VARCHAR(255) NOT NULL,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
  1. 支付接口集成(微信支付)
    2.1 config/payment.php – 支付配置
    此文件包含支付所需的配置,尤其是对接微信支付的参数。
<?php
// config/payment.php
return [
    'wechat_pay' => [
        'app_id' => 'wx1234567890abcdef',
        'mch_id' => '1234567890',
        'key' => 'abcdef1234567890',
        'notify_url' => 'https://your-domain.com/payment/notify',  // 支付回调地址
    ],
];

2.2 admin/controllers/PaymentController.php – 支付控制器
处理支付相关的请求,包括发起支付和支付通知。

<?php
namespace app\admin\controller;
use think\Controller;
use think\Request;
use think\Config;
use app\admin\model\OrderModel;

class PaymentController extends Controller
{
    // 发起支付
    public function initiatePayment(Request $request)
    {
        $orderId = $request->post('order_id');
        $orderModel = new OrderModel();
        $order = $orderModel->find($orderId);
        
        if ($order) {
            $payConfig = Config::get('payment.wechat_pay');
            $paymentParams = [
                'appid' => $payConfig['app_id'],
                'mch_id' => $payConfig['mch_id'],
                'nonce_str' => $this->generateNonceStr(),
                'body' => '抽奖活动支付',
                'out_trade_no' => $order->id,
                'total_fee' => $order->total_amount * 100,  // 单位为分
                'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],
                'notify_url' => $payConfig['notify_url'],
                'trade_type' => 'NATIVE',  // 原生扫码支付
            ];

            // 调用微信支付API生成支付二维码
            $paymentResult = $this->wechatPay($paymentParams);

            return json($paymentResult);
        } else {
            return json(['message' => 'Order not found']);
        }
    }

    // 生成随机字符串
    private function generateNonceStr()
    {
        return substr(md5(mt_rand()), 0, 16);
    }

    // 调用微信支付API
    private function wechatPay($params)
    {
        $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        // 生成签名等支付请求,发起请求到微信支付接口
        // 注意:具体的微信支付接口调用细节参考微信官方文档

        // 这里模拟生成支付二维码的链接
        return [
            'code_url' => 'weixin://wxpay/bizpayurl?pr=exampleqrcodeurl',
        ];
    }

    // 支付回调通知
    public function paymentNotify()
    {
        // 微信支付回调逻辑,验证支付结果并更新订单状态
        $xml = file_get_contents('php://input');
        // 解析xml,验证签名,处理支付结果
        
        // 假设支付成功,更新订单状态
        // $orderModel->updateOrderStatus($orderId, 'paid');
        
        return "<xml><return_code>SUCCESS</return_code><return_msg>OK</return_msg></xml>";
    }
}

数据库设计:支付与订单表

-- 支付表(存储支付信息)
CREATE TABLE `payments` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `order_id` INT NOT NULL,
    `payment_method` VARCHAR(255) NOT NULL,
    `transaction_id` VARCHAR(255) NOT NULL,
    `amount` DECIMAL(10, 2) NOT NULL,
    `status` ENUM('paid', 'failed') NOT NULL,
    `payment_date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 修改订单表,增加total_amount字段(订单总金额)
ALTER TABLE `orders`
ADD COLUMN `total_amount` DECIMAL(10, 2) NOT NULL;

前端支付与订单页面

  1. 支付页面 (payment.html)
    用户点击支付按钮后,会进入支付页面,选择支付方式并进行支付。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>支付页面</title>
</head>
<body>
    <h1>支付页面</h1>
    <p>支付金额:<span id="amount"></span></p >
    <button id="pay-btn">支付</button>
    <div id="qr-code" style="display: none;">
        < img src="" alt="支付二维码" />
    </div>

    <script src="js/payment.js"></script>
</body>
</html>

js/payment.js – 前端支付逻辑

// payment.js
document.getElementById('pay-btn').addEventListener('click', initiatePayment);

function initiatePayment() {
    const orderId = 123;  // 示例订单ID
    fetch('/payment/initiate', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({ order_id: orderId }),
    })
    .then(response => response.json())
    .then(data => {
        if (data.code_url) {
            document.getElementById('qr-code').style.display = 'block';
            document.querySelector('#qr-code img').src = data.code_url;
        }
    })
    .catch(error => console.error('Error:', error));
}

分站管理和海报生成功能

  1. 分站管理
    1.1 admin/controllers/SubSiteController.php – 分站管理控制器
    用于处理分站的增删改查功能。
<?php
namespace app\admin\controller;
use think\Controller;
use think\Request;
use app\admin\model\SubSiteModel;

class SubSiteController extends Controller
{
    // 获取所有分站
    public function getSubSites()
    {
        $subSites = SubSiteModel::all();
        return json($subSites);
    }

    // 添加分站
    public function addSubSite(Request $request)
    {
        $data = $request->post();
        $subSiteModel = new SubSiteModel();
        $result = $subSiteModel->addSubSite($data);
        
        if ($result) {
            return json(['message' => 'Subsite added successfully']);
        } else {
            return json(['message' => 'Failed to add subsite']);
        }
    }

    // 编辑分站
    public function editSubSite(Request $request, $id)
    {
        $data = $request->post();
        $subSiteModel = SubSiteModel::find($id);
        
        if ($subSiteModel) {
            $subSiteModel->update($data);
            return json(['message' => 'Subsite updated successfully']);
        } else {
            return json(['message' => 'Subsite not found']);
        }
    }

    // 删除分站
    public function deleteSubSite($id)
    {
        $subSiteModel = SubSiteModel::find($id);
        
        if ($subSiteModel) {
            $subSiteModel->delete();
            return json(['message' => 'Subsite deleted successfully']);
        } else {
            return json(['message' => 'Subsite not found']);
        }
    }
}

1.2 admin/models/SubSiteModel.php – 分站模型
用于分站的增删改查操作。

<?php
namespace app\admin\model;
use think\Model;

class SubSiteModel extends Model
{
    protected $table = 'sub_sites';  // 数据表名称

    public function addSubSite($data)
    {
        return $this->insert($data);
    }

    public function getAllSubSites()
    {
        return $this->select();
    }

    public function updateSubSite($data)
    {
        return $this->update($data);
    }

    public function deleteSubSite($id)
    {
        return $this->destroy($id);
    }
}

1.3 database.sql – 分站表结构

CREATE TABLE `sub_sites` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `name` VARCHAR(255) NOT NULL,         -- 分站名称
    `owner_name` VARCHAR(255) NOT NULL,   -- 站长姓名
    `owner_user_id` INT NOT NULL,         -- 站长用户ID
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
  1. 海报生成功能
    2.1 admin/controllers/PosterController.php – 海报控制器
    用于生成和管理活动海报。
<?php
namespace app\admin\controller;
use think\Controller;
use think\Request;
use think\Image;

class PosterController extends Controller
{
    // 生成海报
    public function generatePoster(Request $request)
    {
        $userId = $request->post('user_id');
        $prize = $request->post('prize');
        $qrCodeUrl = $request->post('qr_code_url');
        
        // 创建海报
        $image = Image::open('path_to_template_poster.jpg');  // 模板海报
        $image->text('恭喜你获得: ' . $prize, 'path_to_font.ttf', 30, '#000000', [0, 0]);

        // 生成二维码
        $qrCode = Image::open($qrCodeUrl);
        $image->compose($qrCode, 100, 100);  // 位置调整
        
        $filePath = 'uploads/posters/' . $userId . '_poster.jpg';
        $image->save($filePath);
        
        return json(['message' => 'Poster generated successfully', 'poster_url' => $filePath]);
    }
}

2.2 public/qr_code.php – 生成二维码
用于生成用户的二维码(例如用于微信支付或扫码登录)。

<?php
require_once 'vendor/autoload.php';
use Endroid\QrCode\QrCode;

if (isset($_GET['data'])) {
    $qrCode = new QrCode($_GET['data']);
    header('Content-Type: image/png');
    echo $qrCode->writeString();
}
?>

数据库设计:分站和海报相关表

-- 创建分站表
CREATE TABLE `sub_sites` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `name` VARCHAR(255) NOT NULL,
    `owner_name` VARCHAR(255) NOT NULL,
    `owner_user_id` INT NOT NULL,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 创建海报记录表
CREATE TABLE `posters` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `user_id` INT NOT NULL,
    `prize` VARCHAR(255) NOT NULL,
    `poster_url` VARCHAR(255) NOT NULL,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

后台管理界面和用户管理

  1. 用户管理功能
    1.1 admin/controllers/UserController.php – 用户管理控制器
    处理用户信息的增删改查功能。
<?php
namespace app\admin\controller;
use think\Controller;
use think\Request;
use app\admin\model\UserModel;

class UserController extends Controller
{
    // 获取所有用户
    public function getUsers()
    {
        $users = UserModel::all();
        return json($users);
    }

    // 获取单个用户
    public function getUser($id)
    {
        $user = UserModel::find($id);
        return json($user);
    }

    // 更新用户信息
    public function updateUser(Request $request, $id)
    {
        $data = $request->post();
        $userModel = UserModel::find($id);
        
        if ($userModel) {
            $userModel->update($data);
            return json(['message' => 'User updated successfully']);
        } else {
            return json(['message' => 'User not found']);
        }
    }

    // 删除用户
    public function deleteUser($id)
    {
        $userModel = UserModel::find($id);
        
        if ($userModel) {
            $userModel->delete();
            return json(['message' => 'User deleted successfully']);
        } else {
            return json(['message' => 'User not found']);
        }
    }
}

1.2 admin/models/UserModel.php – 用户模型

<?php
namespace app\admin\model;
use think\Model;

class UserModel extends Model
{
    protected $table = 'users';  // 用户表

    public function getAllUsers()
    {
        return $this->select();
    }

    public function updateUser($data)
    {
        return $this->update($data);
    }

    public function deleteUser($id)
    {
        return $this->destroy($id);
    }
}

1.3 database.sql – 用户表结构

CREATE TABLE `users` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `username` VARCHAR(255) NOT NULL,
    `avatar` VARCHAR(255) NOT NULL,
    `balance` DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
  1. 后台管理界面(用户管理页面)
    2.1 admin/views/user/index.html – 用户管理页面
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>用户管理</title>
    <link rel="stylesheet" href="/css/style.css">
</head>
<body>
    <h1>用户管理</h1>
    <table>
        <thead>
            <tr>
                <th>ID</th>
                <th>用户名</th>
                <th>头像</th>
                <th>余额</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            <!-- 动态加载用户数据 -->
        </tbody>
    </table>
    <script>
        // 这里可以通过AJAX获取用户数据并填充到表格中
    </script>
</body>
</html>

前端交互和优化

  1. 前端交互功能(基于AJAX)
    为了让用户操作更加流畅,前端页面需要使用AJAX技术来进行数据交互,比如用户列表的获取、订单状态的更新等。

1.1 admin/views/user/index.html – 用户管理页面(AJAX交互)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>用户管理</title>
    <link rel="stylesheet" href="/css/style.css">
</head>
<body>
    <h1>用户管理</h1>
    <table>
        <thead>
            <tr>
                <th>ID</th>
                <th>用户名</th>
                <th>头像</th>
                <th>余额</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody id="user-table-body">
            <!-- 用户数据将通过AJAX加载 -->
        </tbody>
    </table>

    <script>
        // 获取用户数据并加载到表格
        function loadUsers() {
            fetch('/admin/user/getUsers')  // 假设后端接口地址
                .then(response => response.json())
                .then(data => {
                    const tableBody = document.getElementById('user-table-body');
                    tableBody.innerHTML = '';  // 清空当前表格内容

                    data.forEach(user => {
                        const row = document.createElement('tr');
                        row.innerHTML = `
                            <td>${user.id}</td>
                            <td>${user.username}</td>
                            <td>< img src="${user.avatar}" alt="${user.username}" width="50" height="50"></td>
                            <td>${user.balance}</td>
                            <td>
                                <button onclick="editUser(${user.id})">编辑</button>
                                <button onclick="deleteUser(${user.id})">删除</button>
                            </td>
                        `;
                        tableBody.appendChild(row);
                    });
                })
                .catch(error => console.error('Error:', error));
        }

        // 编辑用户
        function editUser(userId) {
            // 实现编辑用户功能
            alert('编辑用户 ID: ' + userId);
        }

        // 删除用户
        function deleteUser(userId) {
            fetch(`/admin/user/deleteUser/${userId}`, { method: 'DELETE' })
                .then(response => response.json())
                .then(data => {
                    alert(data.message);
                    loadUsers();  // 重新加载用户列表
                })
                .catch(error => console.error('Error:', error));
        }

        // 页面加载时自动加载用户列表
        window.onload = loadUsers;
    </script>
</body>
</html>
  1. 后端接口的改进和优化
    2.1 admin/controllers/UserController.php – 用户管理控制器
    为了支持前端的AJAX请求,我们需要优化后端接口,使其能处理用户查询、删除等操作。
<?php
namespace app\admin\controller;
use think\Controller;
use think\Request;
use app\admin\model\UserModel;

class UserController extends Controller
{
    // 获取所有用户
    public function getUsers()
    {
        $users = UserModel::all();
        return json($users);
    }

    // 删除用户
    public function deleteUser($id)
    {
        $userModel = UserModel::find($id);
        
        if ($userModel) {
            $userModel->delete();
            return json(['message' => 'User deleted successfully']);
        } else {
            return json(['message' => 'User not found']);
        }
    }
}

2.2 admin/models/UserModel.php – 用户模型
用户模型用于对接数据库进行增删改查操作。我们保持之前的模型,唯一需要补充的是获取所有用户的功能。

<?php
namespace app\admin\model;
use think\Model;

class UserModel extends Model
{
    protected $table = 'users';  // 用户表

    public function getAllUsers()
    {
        return $this->select();
    }

    public function updateUser($data)
    {
        return $this->update($data);
    }

    public function deleteUser($id)
    {
        return $this->destroy($id);
    }
}

用户支付功能

支付是这个项目中的核心部分之一,前面已经介绍了微信支付的基础集成。接下来,我们将进一步补充支付相关功能,特别是如何管理支付订单。

  1. 支付管理
    1.1 admin/controllers/PaymentController.php – 支付管理控制器
    支付管理控制器用于处理支付相关的操作,例如订单支付状态更新、支付记录查看等。
<?php
namespace app\admin\controller;
use think\Controller;
use think\Request;
use app\admin\model\OrderModel;
use app\admin\model\PaymentModel;

class PaymentController extends Controller
{
    // 获取支付记录
    public function getPayments()
    {
        $payments = PaymentModel::all();
        return json($payments);
    }

    // 更新支付状态
    public function updatePaymentStatus(Request $request, $id)
    {
        $status = $request->post('status');
        $paymentModel = PaymentModel::find($id);
        
        if ($paymentModel) {
            $paymentModel->status = $status;
            $paymentModel->save();
            return json(['message' => 'Payment status updated successfully']);
        } else {
            return json(['message' => 'Payment record not found']);
        }
    }
}

1.2 admin/models/PaymentModel.php – 支付模型

<?php
namespace app\admin\model;
use think\Model;

class PaymentModel extends Model
{
    protected $table = 'payments';  // 支付记录表

    public function createPayment($orderId, $paymentMethod, $transactionId, $amount)
    {
        return $this->insert([
            'order_id' => $orderId,
            'payment_method' => $paymentMethod,
            'transaction_id' => $transactionId,
            'amount' => $amount,
            'status' => 'paid',
            'payment_date' => date('Y-m-d H:i:s')
        ]);
    }

    public function getAllPayments()
    {
        return $this->select();
    }

    public function updatePayment($data)
    {
        return $this->update($data);
    }

    public function deletePayment($id)
    {
        return $this->destroy($id);
    }
}

1.3 database.sql – 支付记录表结构

CREATE TABLE `payments` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `order_id` INT NOT NULL,
    `payment_method` VARCHAR(255) NOT NULL,
    `transaction_id` VARCHAR(255) NOT NULL,
    `amount` DECIMAL(10, 2) NOT NULL,
    `status` ENUM('paid', 'failed') NOT NULL,
    `payment_date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

抽奖码生成与查询

  1. 抽奖码管理
    1.1 admin/controllers/LotteryCodeController.php – 抽奖码管理控制器
<?php
namespace app\admin\controller;
use think\Controller;
use think\Request;
use app\admin\model\LotteryCodeModel;

class LotteryCodeController extends Controller
{
    // 生成抽奖码
    public function generateLotteryCode(Request $request)
    {
        $count = $request->post('count');
        $prefix = $request->post('prefix', 'CODE');  // 可选前缀
        
        $lotteryCodeModel = new LotteryCodeModel();
        $codes = $lotteryCodeModel->generateCodes($count, $prefix);
        
        return json(['codes' => $codes]);
    }

    // 查询抽奖码
    public function getLotteryCodes()
    {
        $codes = LotteryCodeModel::all();
        return json($codes);
    }
}

1.2 admin/models/LotteryCodeModel.php – 抽奖码模型

<?php
namespace app\admin\model;
use think\Model;

class LotteryCodeModel extends Model
{
    protected $table = 'lottery_codes';  // 抽奖码表

    public function generateCodes($count, $prefix)
    {
        $codes = [];
        
        for ($i = 0; $i < $count; $i++) {
            $code = $prefix . strtoupper(uniqid());
            $this->insert(['code' => $code]);
            $codes[] = $code;
        }

        return $codes;
    }
}

1.3 database.sql – 抽奖码表结构

CREATE TABLE `lottery_codes` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `code` VARCHAR(255) NOT NULL,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

前端抽奖和支付界面

  1. 抽奖页面
    抽奖页面需要具备以下功能:

用户登录后显示可参与的抽奖按钮。
点击抽奖按钮后进行支付(如果是支付抽奖),或直接进行激活码抽奖。
显示中奖结果。
1.1 frontend/views/lottery/index.html – 抽奖页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>大转盘抽奖</title>
    <link rel="stylesheet" href="/css/style.css">
</head>
<body>
    <h1>大转盘抽奖活动</h1>

    <!-- 显示当前余额 -->
    <p>当前余额: <span id="user-balance">0.00</span> 元</p >

    <!-- 抽奖按钮 -->
    <button id="start-lottery" onclick="startLottery()">开始抽奖</button>

    <!-- 抽奖结果展示 -->
    <div id="lottery-result" style="display:none;">
        <h2>恭喜你!你赢得了: <span id="lottery-prize"></span></h2>
        <button onclick="claimPrize()">领取奖品</button>
    </div>

    <script>
        // 获取当前用户的余额
        function loadUserBalance() {
            fetch('/user/getBalance')
                .then(response => response.json())
                .then(data => {
                    document.getElementById('user-balance').innerText = data.balance;
                });
        }

        // 开始抽奖
        function startLottery() {
            const balance = parseFloat(document.getElementById('user-balance').innerText);
            
            // 如果余额不足,提示用户充值
            if (balance < 1.00) {
                alert('余额不足,请充值!');
                return;
            }

            // 发起抽奖请求
            fetch('/lottery/start', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ user_id: 123 })  // 示例用户ID
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    document.getElementById('lottery-prize').innerText = data.prize;
                    document.getElementById('lottery-result').style.display = 'block';
                } else {
                    alert('抽奖失败,请稍后再试!');
                }
            });
        }

        // 领取奖品
        function claimPrize() {
            // 领取奖品请求
            fetch('/lottery/claimPrize', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ user_id: 123 })  // 示例用户ID
            })
            .then(response => response.json())
            .then(data => {
                alert(data.message);
                loadUserBalance();  // 重新加载余额
                document.getElementById('lottery-result').style.display = 'none';
            });
        }

        // 页面加载时初始化余额
        window.onload = loadUserBalance;
    </script>
</body>
</html>
  1. 后端抽奖逻辑
    2.1 frontend/controllers/LotteryController.php – 抽奖控制器
    负责处理抽奖逻辑,包括启动抽奖、计算中奖结果等。
<?php
namespace app\frontend\controller;
use think\Controller;
use think\Request;
use app\frontend\model\LotteryModel;
use app\frontend\model\UserModel;

class LotteryController extends Controller
{
    // 开始抽奖
    public function start(Request $request)
    {
        $userId = $request->post('user_id');
        $user = UserModel::find($userId);
        
        if ($user && $user->balance >= 1.00) {  // 假设抽奖需要最低1元
            // 扣除用户余额
            $user->balance -= 1.00;
            $user->save();

            // 进行抽奖逻辑,随机生成奖品
            $lottery = new LotteryModel();
            $prize = $lottery->drawPrize();

            return json(['success' => true, 'prize' => $prize]);
        } else {
            return json(['success' => false, 'message' => '余额不足']);
        }
    }

    // 领取奖品
    public function claimPrize(Request $request)
    {
        $userId = $request->post('user_id');
        $user = UserModel::find($userId);

        if ($user) {
            // 更新用户奖品状态
            return json(['message' => '奖品领取成功']);
        } else {
            return json(['message' => '用户信息错误']);
        }
    }
}

2.2 frontend/models/LotteryModel.php – 抽奖模型

<?php
namespace app\frontend\model;
use think\Model;

class LotteryModel extends Model
{
    // 随机抽取奖品
    public function drawPrize()
    {
        $prizes = ['一等奖:iPhone 15', '二等奖:MacBook Pro', '三等奖:AirPods', '四等奖:10元现金'];
        return $prizes[array_rand($prizes)];
    }
}
  1. 后端支付处理
    3.1 frontend/controllers/PaymentController.php – 支付控制器
    支付控制器用于处理支付相关的请求,包括用户余额支付等。
<?php
namespace app\frontend\controller;
use think\Controller;
use think\Request;
use app\frontend\model\PaymentModel;
use app\frontend\model\UserModel;

class PaymentController extends Controller
{
    // 余额支付
    public function payWithBalance(Request $request)
    {
        $userId = $request->post('user_id');
        $amount = $request->post('amount');

        $user = UserModel::find($userId);
        
        if ($user && $user->balance >= $amount) {
            // 扣除用户余额
            $user->balance -= $amount;
            $user->save();

            // 创建支付记录
            $paymentModel = new PaymentModel();
            $paymentModel->createPayment($userId, 'balance', 'transaction123', $amount);

            return json(['message' => '支付成功']);
        } else {
            return json(['message' => '余额不足,支付失败']);
        }
    }
}

系统配置和优化

  1. 系统配置管理
    后台管理系统的配置部分,用于修改首页信息、支付设置等。

1.1 admin/controllers/SystemConfigController.php – 系统配置控制器

<?php
namespace app\admin\controller;
use think\Controller;
use think\Request;
use app\admin\model\SystemConfigModel;

class SystemConfigController extends Controller
{
    // 获取系统配置
    public function getSystemConfig()
    {
        $config = SystemConfigModel::get(1);  // 假设只有一条配置记录
        return json($config);
    }

    // 修改系统配置
    public function updateSystemConfig(Request $request)
    {
        $data = $request->post();
        $config = SystemConfigModel::find(1);

        if ($config) {
            $config->update($data);
            return json(['message' => '配置更新成功']);
        } else {
            return json(['message' => '配置更新失败']);
        }
    }
}

1.2 admin/models/SystemConfigModel.php – 系统配置模型

<?php
namespace app\admin\model;
use think\Model;

class SystemConfigModel extends Model
{
    protected $table = 'system_config';  // 配置表

    // 获取系统配置
    public function getConfig()
    {
        return $this->find(1);  // 获取唯一的配置记录
    }
}

1.3 database.sql – 系统配置表结构

CREATE TABLE `system_config` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `key` VARCHAR(255) NOT NULL,
    `value` TEXT NOT NULL,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

系统部署与测试

在完成了所有功能的开发之后,下一步就是进行系统部署和测试。以下是针对部署和测试的一些关键步骤:

  • 系统部署
    系统部署的关键在于选择合适的服务器环境、配置数据库以及确保系统在生产环境中运行良好。
  • 1.1 服务器配置
  • 可以选择以下几种常见的部署方案:
  • Linux服务器:如Ubuntu、CentOS等。
  • Web服务器:Nginx 或 Apache 作为反向代理和负载均衡。
  • 数据库服务器:MySQL 或 MariaDB。
  • PHP环境:PHP 7.x 或更高版本,配合 ThinkPHP 框架。
  • 确保服务器的配置能够支持生产环境的高并发,适时进行负载均衡和优化。
  • 1.2 部署步骤
  • 环境配置:
  • 配置 Nginx 或 Apache 作为 Web 服务器,代理到 PHP。
  • 配置 PHP 环境,确保 php-fpm 和 PHP 相关扩展正常工作。
  • 安装 MySQL 或 MariaDB 数据库,确保数据库连接稳定。
  • 上传代码:
  • 将开发环境中的代码推送到生产环境服务器(使用 Git 或 FTP 上传)。
  • 确保环境中的 .env 配置文件指向正确的数据库、缓存和其他服务。
  • 配置 Nginx 或 Apache:
  • 配置 nginx.conf 或 httpd.conf,指向项目的根目录,并设置合适的负载均衡与缓存策略。
  • 配置反向代理,将请求转发到 PHP。
  • 数据库迁移:
  • 使用 SQL 脚本或数据库迁移工具将开发环境中的数据库结构迁移到生产环境中。
  • 确保数据库的表结构和数据是最新的。
  • 配置文件优化:
  • 配置文件如 .env 文件应根据生产环境调整,例如数据库用户名、密码、缓存设置等。
  • 开启生产环境的错误日志,以便追踪和修复潜在问题。
  • 启动与监控:
  • 启动 Nginx 和 PHP 服务,检查系统是否正常运行。
  • 配置系统监控工具(如 Prometheus、Grafana)来监控服务器的性能和健康状态。
  • 1.3 安全与备份
  • 数据库备份:定期备份数据库,防止数据丢失。
  • 系统安全:确保系统使用 HTTPS(SSL证书),并采取防火墙和其他安全措施来防止潜在的攻击。
  • 访问控制:限制后台管理页面的访问权限,确保只有授权的用户能够访问。
  • 系统测试
    在系统部署完成后,进行全面的测试以确保系统功能正常并且没有漏洞。以下是一些关键的测试步骤:
  • 2.1 功能测试
  • 确保所有的功能模块能够按预期工作:
  • 用户登录与注册:测试用户的注册、登录、密码重置等功能,确保用户能够正常操作。
  • 支付功能:测试用户使用余额支付是否正常,检查支付记录是否正确保存。
  • 抽奖功能:测试抽奖功能是否能够正确随机抽取奖品,中奖后用户的余额是否被正确扣除。
  • 奖品领取:测试奖品领取逻辑是否正常,中奖的用户是否能够正确领取奖品。
  • 后台管理:测试管理员能够正常查看用户、管理订单和支付记录等。
  • 2.2 性能测试
  • 确保系统在负载较高的情况下能够正常运行:
  • 压力测试:模拟大量用户同时访问系统,确保系统能够处理高并发请求。
  • 数据库负载测试:检查数据库的读写性能,确保在高并发时不会出现性能瓶颈。
  • 缓存测试:检查缓存机制是否有效,确保高频访问的数据能通过缓存减少数据库查询压力。
  • 2.3 安全性测试
  • 测试系统的安全性,确保没有漏洞可供攻击者利用:
  • SQL注入测试:检查所有数据库交互部分,确保没有 SQL 注入漏洞。
  • XSS 攻击测试:确保前端页面的输入字段能够正确过滤掉恶意的脚本。
  • CSRF 测试:检查是否存在跨站请求伪造(CSRF)攻击的漏洞。
  • 文件上传漏洞测试:如果系统支持文件上传,测试文件上传功能是否有潜在的安全问题,例如上传恶意文件。
  • 2.4 用户体验测试
  • 测试用户界面的易用性,确保界面简洁直观,用户能够顺利完成操作:
  • 界面设计:确保界面美观,用户能够方便地找到各个功能。
  • 表单输入验证:确保所有表单都进行了适当的输入验证,以减少用户的错误操作。
  • 错误提示:确保错误提示清晰且有用,帮助用户快速解决问题。
  • 项目优化
    为了确保系统在生产环境中的流畅运行,以下是一些常见的优化方法:
  • 3.1 性能优化
  • 数据库优化:
  • 对常用查询添加索引,提高查询效率。
  • 使用数据库缓存和优化数据库连接池配置,减少数据库负担。
  • 定期清理过期数据和不必要的数据表。
  • 缓存机制:
  • 使用 Redis 或 Memcached 等缓存工具来存储频繁访问的数据,减少数据库的压力。
  • 使用页面缓存、查询缓存等技术,加速页面渲染和数据访问。
  • 前端性能优化:
  • 使用图片压缩、懒加载等技术来减少页面加载时间。
  • 合并和压缩 CSS 和 JavaScript 文件,减少 HTTP 请求的数量和文件大小。
  • 代码优化:
  • 使用合适的设计模式和开发框架,避免代码重复和冗余。
  • 定期重构代码,清理不再使用的功能和代码块。
  • 3.2 SEO优化
  • 搜索引擎友好:
  • 确保页面有清晰的结构和语义标签,便于搜索引擎抓取。
  • 使用适当的关键词和 meta 标签,优化页面的搜索排名。
  • 为所有页面添加描述性 URL,以提高可读性和索引效果。
  • 移动端优化:
  • 确保网站能够在移动设备上正常访问,使用响应式设计确保页面适应不同屏幕尺寸。
  • 使用 AMP(加速移动页面)技术来加速移动端页面的加载。
  • 项目维护与更新
    一旦系统投入使用,后续的维护和更新工作同样重要。以下是一些常见的维护任务:
  • 定期更新:更新系统框架和库,确保系统没有安全漏洞。
  • 用户反馈:收集用户的反馈和建议,进行功能改进。
  • 日志监控:定期检查系统日志,解决潜在的错误和异常。
  • 数据备份:确保系统定期备份,防止数据丢失。

总结
到此为止,我们已经完成了大转盘抽奖系统的开发与部署,涵盖了以下主要内容:

前端与后端功能开发:包括用户管理、支付系统、抽奖系统、奖品领取、支付记录等功能。
系统架构设计:数据库设计、服务器配置、代码架构等方面的设计与优化。
系统测试:包括功能测试、性能测试、安全性测试等,确保系统在生产环境中正常运行。
项目部署与维护:系统部署到生产环境,并进行必要的优化和维护,确保系统高效、稳定地运行。
随着项目的投入使用,后续还可以根据用户反馈进行优化和功能扩展。希望本系统能够为用户提供一个流畅且公平的抽奖体验,同时也能帮助运营团队更好地管理和分析活动数据。

© 版权声明
THE END
喜欢就支持一下吧
点赞15赞赏 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片快捷回复

    暂无评论内容