php mysql 错误日志_php源码建博客5--建库建表-配置文件-错误日志

主要:

整理框架

建库建表

配置文件类

错误日志记录

--------------本篇后文件结构:--------------------------------------

blog

├─App

│ ├─Model 模型目录

│ ├─View 视图目录

│ │ ├─Admin后台目录

│ │ └─Home前台目录

│ ├─Common 配置目录

│ │ └─config.php 配置文件

│ ├─Log 日志目录

│ │ └─log.txt 日志文件

│ ├─Controller 控制器

│ │ ├─Admin后台

│ │ │ └─DemoController.class.php 测试控制器

│ │ └─Home前台

├─Public 静态公共文件(js,css,images)

│ ├─Plugins 插件

│ ├─Back后台

│ └─Home前台

├─Frame 公共使用的类

│ ├─BaseModel.class.php 数据库连接类

│ ├─BaseController.class.php 控制器公共操作(设置编码,信息跳转)

│ ├─FactoryModel.class.php 模型工厂类

│ ├─Log.class.php 日志厂类

│ ├─Config.class.php 配置文件读取类

│ ├─Init.class.php 初始化应用类

│ └─MySQLDB.class.php 数据库操作工具类

└─index.php 入口文件

-----------------------------------------------------------------------------------------------------

利用上篇中搭建好的mvc框架结构,正式开始开发博客项目。首先建立数据表,然后开始搭建后台,数据前台展示,完成博客主要模块展示。

整理框架

清理测试页面

1)前面构建框架结构,使用了用户登录测试页面以及后台首页页面。在此全部去掉,从新开始构建前台和后台页面。类似于我们下载了一个ThinkPHP或Laravel或其他的框架。 现在开始在这个微型框架上来构建我们的项目

2) 实际开发,会用前端人员做好的静态页面来进行开发。所以也可以在 【模板之家】或其他网站 下载 后台模板和前台博客静态页面。然后专注于后端开发,可以加快速度。本项目供学习研究使用,也就不那么着急了。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

原本是准备全部利用别人写好的前端页面(包括前端显示和后台页面),专注于后端逻辑的开发。而且已经把分类页面列表都做好了。还提交传送了。

此刻,仔细想想,要是这样玩,那我直接用框架更好了。既然做后端开发,自己写个后端页面+程序处理,没什么问题吧..., 置于前端显示页面,那再用前辈写的前端页面倒是可以的

于是乎,卷起柚子,说干就干,先来整理框架,开始搭建博客。。。。。

说一说

框架结构:

--------------清理后MVC框架文件结构:--------------------------------------

blog

├─App

│ ├─Model 模型目录

│ ├─View 视图目录

│ │ ├─Back后台

│ │ └─Home前台

│ ├─Controller 控制器目录

│ │ ├─Back后台

│ │ └─Home前台

├─Public 静态公共文件(js,css,images)

│ ├─Plugins 插件

│ ├─Back后台

│ └─Home前台

├─Frame 公共使用的类

│ ├─BaseModel.class.php 数据库连接类

│ ├─BaseController.class.php 控制器公共操作(设置编码,信息跳转)

│ ├─FactoryModel.class.php 模型工厂类

│ ├─Init.class.php 初始化应用类

│ └─MySQLDB.class.php 数据库操作工具类

└─index.php 入口文件

-----------------------------------------------------------------

后续的开发只需要复制该目录结构文件, 就可以在此基础上进行开发了。

提交传送代码

git add -A

git commit-m "清理MVC结构"git push origin master

插件准备

1) layui插件: 搭建后台程序,准备使用layui前端框架,这个框架个人认为做后台界面还是不错的。它还包含一些比较使用模块。

用bootstrap也可以,我更加倾向于用它来做前台页面。

2) jQuery库:  更方便操作DOM, 尤其是经常使用ajax请求。

3) 其他插件: 如Ueditor编辑器等 需要使用时再下载吧。一般插件都会有demo示例, 按照示例和手册,懂web开发基本能使用。

上述插件暂时不熟悉没有关系,官网上有手册,需要什么模块,便查手册便使用,就像搭积木,如果要做得更好,当然要花更多的时间多练习。我本着后台给程序管理员使用,也不一定要非常漂亮,实用就好。

建库建表

准备: 创建分支

$ git checkout master

$ git checkout-b "start-admin-module"

建表思路:

根据博客模板,从首页开始分析,  分析哪些需要动态数据,以便建立对应数据表。

用户: 登录, 注册, 修改, 删除

文章: 分类管理, 博文管理, 评论管理

角色管理: 管理员,普通用户

菜单管理: 不同权限人员,对应菜单栏也有区别

建表工具可以任意选择。初期手工写建表语句,熟悉后直接使用工具。 本项目中使用 Navicat 建立数据库和表

数据库,表

1) 创建数据库:php_blog

create database php_blog charset utf8

2) 用户表: y_users

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

CREATE TABLE`y_user` (

`id`int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户主键',

`username`varchar(20) NOT NULL COMMENT '用户名',

`password`char(32) NOT NULL COMMENT '密码',

`email`varchar(50) NOT NULL DEFAULT '' COMMENT '注册邮箱',

`token_email`varchar(32) NOT NULL DEFAULT '' COMMENT '邮箱验证',

`status`tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '状态, 0-正常,1-禁用',

`gid`tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '角色id,1-管理员,2-普通用户,0-无效',

`login_ip`varchar(20) NOT NULL DEFAULT '' COMMENT '最后登录的ip地址',

`login_times`smallint(6) unsigned NOT NULL DEFAULT '0' COMMENT '登录次数',

`created_at`int(10) unsigned NOT NULL DEFAULT '0' COMMENT '注册时间',

`updated_at`int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最后一次登录时间',PRIMARY KEY(`id`),UNIQUE KEY`username` (`username`),UNIQUE KEY`email` (`email`)

) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT='用户表';

用户表SQL

3)角色表: y_user_group

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

CREATE TABLE`y_user_group` (

`id`int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '角色id',

`name`varchar(20) NOT NULL DEFAULT '' COMMENT '角色名称',

`auths`varchar(255) NOT NULL DEFAULT '' COMMENT '角色权限',PRIMARY KEY(`id`)

) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COMMENT='角色表';

角色表SQL

4) 菜单表: y_menus

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

CREATE TABLE`y_menus` (

`id`int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '菜单id',

`title`varchar(20) DEFAULT '' COMMENT '菜单名称',

`controller`varchar(30) DEFAULT '' COMMENT '控制器名称',

`action`varchar(30) DEFAULT '' COMMENT '操作名称',

`status`tinyint(1) unsigned DEFAULT '1' COMMENT '状态,1-正常,0-禁用',

`is_hidden`tinyint(1) unsigned DEFAULT '0' COMMENT '是否隐藏,0-正常显示,1-隐藏',

`sort`int(10) unsigned DEFAULT '0' COMMENT '排序',

`pid`int(10) unsigned DEFAULT '0' COMMENT '上一级菜单',PRIMARY KEY(`id`)

) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COMMENT='菜单表';

菜单表SQL

5) 文章表 y_article

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

CREATE TABLE`y_article` (

`id`int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '文章id',

`title`varchar(60) NOT NULL DEFAULT '' COMMENT '标题',

`description`varchar(200) NOT NULL DEFAULT '' COMMENT '文章简介',

`content`text NOT NULL COMMENT '内容',

`cid`int(10) unsigned NOT NULL COMMENT '文章类别',

`pic`varchar(150) NOT NULL DEFAULT '' COMMENT '文章封面图',

`pic_watermark`varchar(150) NOT NULL DEFAULT '' COMMENT '水印图',

`pic_thumb`varchar(150) NOT NULL DEFAULT '' COMMENT '缩略图',

`uid`int(10) unsigned NOT NULL COMMENT '作者',

`clicks`int(10) unsigned NOT NULL DEFAULT '0' COMMENT '阅读数(点击数)',

`updated_at`int(10) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',

`created_at`int(11) NOT NULL DEFAULT '0' COMMENT '发布时间',PRIMARY KEY(`id`),KEY`title` (`title`),KEY`uid` (`uid`),KEY`clicks` (`clicks`),KEY`cid` (`cid`) USING BTREE

) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='文章表';

文章表SQL

6) 文章类别表 y_category

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

CREATE TABLE`y_category` (

`id`int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '分类id',

`catename`varchar(15) NOT NULL COMMENT '分类名',

`description`varchar(255) NOT NULL DEFAULT '' COMMENT '简介',PRIMARY KEY(`id`)

) ENGINE=MyISAM AUTO_INCREMENT=15 DEFAULT CHARSET=utf8 COMMENT='文章类别表';

文章类别表SQL

7) 评论(回复)表 y_comment

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

CREATE TABLE`y_comment` (

`id`int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '评论id',

`uid`int(10) unsigned NOT NULL COMMENT '评论者',

`created_at`int(11) DEFAULT NULL COMMENT '评论时间',

`content`varchar(255) NOT NULL DEFAULT '' COMMENT '评论内容',

`aid`int(10) unsigned NOT NULL COMMENT '被评论的文章',PRIMARY KEY(`id`)

) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='评论(回复)表';

评论(回复)表SQL

8) session数据表 y_session  (其实可以不用这个,目的是为了操作 "将session写入数据库" )

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

CREATE TABLE`y_session` (

`sess_id`varchar(50) NOT NULL DEFAULT '' COMMENT 'session id',

`data`text NOT NULL COMMENT 'session数据',

`created_at`int(11) NOT NULL COMMENT 'session创建时间',PRIMARY KEY(`sess_id`)

) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='session数据表';

session数据表SQL

为了避免弄的太复杂, 暂时建立这些数据表,字段后续可以进行调整。如果需要加入模块功能,可以相应增加相应数据表。

连接数据库

在badeModel中修改数据连接的数组信息 【Frame/BaseModel.class.php】  (如果使用配置文件类,此处就可以省略了)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 classBaseModel {2 。。。3 。。。4 。。。5 function __construct(array $config=null)6 {7 $conf = array(8 'host'=>'localhost',

9 'user'=>'root',

10 'pwd'=>'root',

11 'port'=>'3306',

12 'charset'=>'utf8',

13 'dbname'=>'php_blog',

14 );15 $conf = empty($config)? $conf : array_merge($conf,$config);16 $this->db = Db::getDb($conf);17 }18 }

设置连接数据库信息

配置文件类

需求分析:

为了框架便于数据库连接以及方便读取配置文件。如 希望在 App/Common/config.php 做一些配置项,要求能读取这些配置并应用到项目

思路:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

step 1: 创建文件 App/Common/config.php 并将数据库连接信息写入该配置文件

step 2: 在Frame/目录下创建读取配置文件类 Config.class.php

step 3: 设置自动加载 读取配置类

step 4: 基础模型类实例化 读取配置类。 操作数据库必须要经过基础模型类

step 5: 调整数据库工具类获取配置信息,既 其构造方法中通过传递进来的数据配置信息对象获取

step 6: 测试连接数据结果,验证获取配置

实现连接数据库-读取数据库配置信息思路

代码实现

1) 创建配置文件config.php  【App/Common/Config.php】

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

* 配置文件

* User: young*/

return[//数据库连接配置

'host'=>'localhost',

'user'=>'root',

'pwd'=>'root',

'port'=>'3306',

'charset'=>'utf8',

'dbname'=>'php_blog',];

配置文件-数据库配置信息

2) 创建读取配置文件类 【Frame/Config.class.php】

1 <?php2 /**3 * 配置文件读取类4 * User: young5 */

6

7 classConfig8 {9 protected static $ins = null; //本类实例

10 protected $cfg = array(); //存储配置项

11

12 /**13 * 获取本类实例14 * @access public15 * @return object 本类的单例对象16 */

17 public static functiongetIns() {18 if(false === (self::$insinstanceof self)){19 self::$ins = newself();20 }21 return self::$ins;22 }23

24 /**25 * 构造方法: 读取配置项26 * @access public27 * @return void28 */

29 final protected function__construct() {30 require APP.'Common'.DS.'config.php'; //读取配置项

31 $this->cfg = $cfg;32 }33

34 /**35 * 根据指定的配置项,返回该配置项的值36 * @param string $k 配置项37 * @return mixed|null 返回配置项的数据38 */

39 public function __get($k) {40 if(!isset($this->cfg[$k])) {41 return null;42 }43 return $this->cfg[$k];44 }45

46

47 /**48 * 根据指定的配置项,返回配置项的值49 * @param string $k 配置项名称50 * @param string $v 配置项对应的值51 */

52 public function __set($k,$v) {53 $this->cfg[$k] = $v;54 }55 }

3)  自动加载配置类

需要自动加载该类, 该类在Frame目录下, 所以可以写入到 Init.class.php 类中的属性数组中   【Frame/Init.class.php】

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 <?php2 /**3 * 初始化应用类4 * User: young5 */

6

7 classInit8 {9 protected static $frame = array('BaseController','BaseModel','Db','FactoryModel','Config');10 。。。11 。。。12 。。。

自动加载配置类

4)基础模型类实例化配置类【Frame/BaseModel.class.php】

1 <?php2

3 /**4 * BaseModel.class.php 基础模型类5 * 连接数据库6 * @author young7 */

8 classBaseModel9 {10 protected $db = null;11 /**12 * 构造方法: 实例化数据库类13 * @access public14 */

15 function__construct()16 {17 $conf = Config::getIns(); //读取配置项实例

18 $this->db = Db::getDb($conf);19 }20 }

5)数据库读取配置项信息  【Frame/Db.class.php】

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 <?php2 /**3 * Db.class.php 数据库操作工具类4 * @author young5 */

6

7 classDb {8 。。。9 。。。10 。。。11 /**12 * 构造方法: 保存数据库连接信息,连接数据库13 * @access private14 * @param array $conf 数据库连接信息15 */

16 private function __construct($conf)17 {18 $this->host = $conf->host;19 $this->user = $conf->user;20 $this->pwd = $conf->pwd;21 $this->port = $conf->port;22 $this->charset = $conf->charset;23 $this->dbname = $conf->dbname;24 $this->connect();25 }26 。。。27 。。。28 。。。29 }

数据库工具类获取配置信息

6) 测试 在App/Controller/Home/DemoController.class.php  用于测试数据库连接情况

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

/**

* 测试控制器类

* User: young

*/

class DemoController extends BaseController

{

public function test()

{

$db = new BaseModel();

$data = $db->db->getAllRows("select * from y_user");

var_dump($data);

}

}

测试控制器类测试连接数据库

注: 前提,需要将BaseModel.class.php中的$db属性先临时修改为public公开,才能测试成功 (原因:在Demo控制器中实例化的基础模型类,数据库操作实例是放在类的属性db中,外部不能访问protected属性), 本节所有测试,可以临时将db设置为公开的。

ed39cceed4817324db53e1d248c88e7d.png

还可以使用配置如: 上传目录,网站配置信息等,根据需求自定义配置需求,再通过读取配置类读取配置的数据

提交代码

git add -A

git commit-m "完成读取配置文件类"

错误日志记录

除了开发阶段调试错误, 项目上线一般会将错误信息写入指定文件中。安全性更好。

需求分析:

将错误写入日志文件中,这里暂时主要记录数据库操作的错误。 如:默认将错误记录在App/log/logError.txt。 如果在配置文件中进行了配置,则将日志信息写入到配置项log指定的目录中

思路:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

step 1: 制作日志类Frame/Log.class.php, 用于将错误信息写入到指定文件中。 (设置日志文件位置,正好可以利用上面写的配置项,通过读取配置来实现)

step 2: 在基础模型类BaseModel中,读取配置项后, 可以将日志目录路径写入常量。 使用try..catch 捕捉异常,将错误写入日志

step 3: 实现日志类自动加载。Log类在Frame目录中,所以只要在初始化应用类Init中的属性$frame数组中加入 “Log”

step 4: 记录错误。 数据库连接可能失败, sql语句可能执行失败

step 5: 测试错误日志记录功

实现错误日志记录过程思路

代码实现

1) 制作错误日志类 【Frame/Log.class.php】

1 <?php2 /**3 * 日志类4 * User: young5 */

6

7 class Log

8 {9 /**10 * 记录错误信息到文件中11 * @param string $err 错误信息12 */

13 public static function write($err)14 {15 date_default_timezone_set('PRC'); //时区设置16 //打开文件

17 $fh = fopen(LOG.'log.txt','a'); //追加方式打开18

19 //拼接信息

20 $err = date('Y年m月d日 H:i:s',time()) . "\t\r\n" . $err . "\t\r\n";21

22 //写入

23 fwrite($fh,$err);24

25 //关闭

26 fclose($fh);27 }28 }

2)  读取日志位置,捕捉错误  【Frame/BaseModel.class.php】

发生错误记录后,这里只是简单使用exit(..)退出, 可以自定error错误页面会更好

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 <?php2

3 /**4 * BaseModel.class.php 基础模型类5 * 连接数据库,捕捉记录错误6 * @author young7 */

8 classBaseModel9 {10 Public $db = null;11 /**12 * 构造方法: 实例化数据库类13 * @access public14 */

15 function__construct()16 {17 $conf = Config::getIns(); //读取配置项实例18

19 //读取日志配置项目 并写成常量

20 $logPath = $conf->log;21 $logPath = !isset($logPath) ? APP."log".DS : $logPath;22 define('LOG',$logPath);23

24 //监控数据库操作

25 try{26 $this->db = Db::getDb($conf);27 }catch(Exception $e) {28 $err = '';29 $err .= '错误代码:' . $e->getCode() . "\r\n";30 $err .= '错误信息:' . $e->getMessage() . "\r\n";31 $err .= '文件:' . $e->getFile() . "\r\n";32 $err .= '行号:' . $e->getLine() . "\r\n\r\n";33 Log::write($err);34 exit("

客官!页面暂时无法响应,请稍后访问

");35 }36 }37 }

点击查看【基础模型类中监测并记录错误】

3)自动加载日志记录类 【Frame/Init.class.php】

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 <?php2 /**3 * 初始化应用类4 * User: young5 */

6

7 classInit8 {9 protected static $frame = array('BaseController','BaseModel','Db','FactoryModel','Config','Log');10 。。。11 。。。12 。。。

点击查看【自动加载日志类】

4) 记录错误  【Frame/Db.class.php】

数据库连接可能发生错误处理

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 classDb2 {3 。。。4 。。。5 。。。6 /**7 * 连接数据库,设置编码,选库8 * @access private9 */

10 private functionconnect()11 {12 $this->link = @ mysql_connect("{$this->host}:{$this->port}", "$this->user", "$this->pwd") ;13 if(!$this ->link) {14 $error = new Exception("数据库连接不上",10000);15 throw $error;16 }17 $this->setCharset($this->charset);18 $this->useDb($this->dbname);19 }20 。。。21 。。。22 。。。

点击查看【数据库连接错误抛出】

sql语句发生错误处理

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 classDb2 {3 。。。4 。。。5 。。。6 /**7 * 执行sql语句8 * @param string $sql sql语句9 * @return mixed10 */

11 private function query($sql)12 {13 $result = mysql_query($sql, $this->link);14 //if(false === $result) {15 // echo "

sql执行失败!
";16 // echo "
失败语句:".$sql;17 // echo "
错误代号".mysql_errno();18 // echo "
错误提示: ".mysql_error()."

";19 // exit();20 // }

21 if(false === $result) {22 $err = "sql执行失败!\r\n失败语句:".$sql."\r\n错误代号:".mysql_errno()."\r\n错误提示:".mysql_error()."\r\n\r\n";23 Log::write($err);24 exit("

查询出错,请稍后访问

");25 }26 return $result;27 }28 。。。29 。。。30 。。。

点击查看【执行SQL错误处理】

测试

可以在【App/Common/config.php】中配置日志文件目录。 如果不进行配置, 默认记录在App/log/目录中

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 <?php2 /**3 * 配置文件4 * User: young5 */

6 return[7 //数据库连接配置

8 。。。9 、 。。。10 。。。11

12 //日志文件位置配置

13 'log' => APP,

14 ];

点击查看【日志文件配置】

以下测试可以 开启配置项中的配置log  和关闭后分别测试。  注意: 如果没有做配置log, 则要首先在App目录下建立一个log目录

1. 在配置文件中故意写错数据库连接信息,如密码写错

c78b43740caa71917b8d9abbde0ba98f.png

2. 执行sql错误

2f5ee007682118e1612aeacea0fc76e8.png

最后说明: 配置目录,日志目录都是不希望浏览器直接访问的,所以需要将.htaccess文件放入目录中 (由于App目录中已经存在,故也可以省略)

提交传送代码

git add -A

git commit-m "完成日志类"git checkout master

git mergestart-admin-module

git push origin master

小结: 本篇主要实现了 框架清理,博客数据库表搭建,创建配置读取类,日志记录类。

实际上,到此仍然只是更加完善了一下框架结构,增加了2个功能。正如前篇所提,还有很多是可以改进的。这里就暂时不再继续增加功能了。

提出问题:

1. 如何使用该自制框架搭建项目 ==> 用户操作+mvc实现

2. 如何着手使用ajax实现后台登录功能  ==> ajax应用

3. 如何着手实现分类模块功能,它有哪些操作 ==> 增删改查

下一步: 后台模板视图制作,后台登录,文章分类模块功能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值