首页 » 日志 » 个人日记 » 正文

陪练订单管理系统 – 项目示范

http://test.pi4.cn
右上角登陆-账号test 密码 test
经典用户:WE陪玩 http://www.90001we.cn桃色陪玩 http://ts.md4.cn

后台订单系统+前台官网系统 100元/月
内部论坛模块 100元/永久授权 (预付三个月赠送)
统计分析模块 200元/永久授权 (预付两个月赠送)
基础系统 – 后台订单系统 以分布式架构+后端集群式服务器保证系统 高流畅性和99.95%的可用性。
扩展模块 – 各部分功能模块灵活开关,以保证基础系统高强度抗D和99.95%的可用性
5分钟开通,支持绑定自有域名和分配三位2级域名。
YY知名第三方工作室 – 包养你工作室 荣誉出品。

管理员:用户管理,订单管理,报单,客户余额查询,充值余额,查询充值记录,结算陪练工资,结算记录
客服:审核用户,确认订单,报单,客户余额查询,充值余额
陪练:自己的订单管理,报单,客户余额查询,自己的结算记录
客户:确认订单,查询自己的余额

项目架构为分布式架构。使用BAE+BOS+MYSQL的解决方案搭建。

代码逻辑层由BAE执行和计算。 http://bce.baidu.com/product/bae.html

图片文件以及静态文件上传由BOS服务提供。BOS+CDN架构保证文件读取的效率和性能。http://bce.baidu.com/product/bos.html 、http://bce.baidu.com/product/cdn.html

数据库存储系统数据和文件列表索引保证文件地址的拼接和快速加载。http://bce.baidu.com/product/rds.html

系统路由的引用解决了小型项目的MVC架构。因为项目过小而且非开源项目。故为了实现团队协同和代码管理。

以url为路由基础自构了简单路由。登陆注册页面因权限控制问题需要游客访问,故使用了特殊的路由标记处理。

然后以 管理员、客服、陪练、客户 四种角色为基础实现功能跳转和权限控制。

所有请求经路由进入系统前台或者后端,故权限以页面数据中转控制更为安全。下图第一行示例有数组注明当前页面的可允许角色列表。

20150522021456

自页面处理请求完成入库简化了项目代码和架构。

20150522023902

同样继续延续了封装的MySQL处理类。简化sql语句使用和释放资源操作 文章最底部贴上了MySQL连库类封装。

/*
+———————————————————————–
| 文件概要:数据库连接函数
| 文件名称:function.php
| 创建时间:2013-12-1
| 用法:
| include/ “libs/function.php”; #引用实例化连接函数
| include/ “libs/mysql.class.php”; #引用数据库操作类
| $connDb=conn_Db(); #实例化数据库连接
| $sql=””;
| $result = $connDb -> query($sql); #执行查询
| $total = $connDb -> numrows($result); #获取记录数方法,更多方法参考mysql.class.php
| $connDb -> __destruct(); #关闭连接,释放资源
+———————————————————————–
*/

数据库字段接受过滤使用的是最原始的关键词替换,小型项目,简单暴力有效。

function lib_replace_end_tag($str)
{
if (empty($str)) return false;
$str = htmlspecialchars($str);
$str = str_replace( ‘/’, “”, $str);
$str = str_replace(“\\”, “”, $str);
$str = str_replace(“&gt”, “”, $str);
$str = str_replace(“&lt”, “”, $str);
$str = str_replace(“<SCRIPT>”, “”, $str);
$str = str_replace(“</SCRIPT>”, “”, $str);
$str = str_replace(“<script>”, “”, $str);
$str = str_replace(“</script>”, “”, $str);
$str=str_replace(“select”,”select”,$str);
$str=str_replace(“join”,”join”,$str);
$str=str_replace(“union”,”union”,$str);
$str=str_replace(“where”,”where”,$str);
$str=str_replace(“insert”,”insert”,$str);
$str=str_replace(“delete”,”delete”,$str);
$str=str_replace(“update”,”update”,$str);
$str=str_replace(“like”,”like”,$str);
$str=str_replace(“drop”,”drop”,$str);
$str=str_replace(“create”,”create”,$str);
$str=str_replace(“modify”,”modify”,$str);
$str=str_replace(“rename”,”rename”,$str);
$str=str_replace(“alter”,”alter”,$str);
$str=str_replace(“cas”,”cast”,$str);
$str=str_replace(“&”,”&”,$str);
$str=str_replace(“>”,”>”,$str);
$str=str_replace(“<“,”<“,$str);
$str=str_replace(” “,chr(32),$str);
$str=str_replace(” “,chr(9),$str);
$str=str_replace(” “,chr(9),$str);
$str=str_replace(“&”,chr(34),$str);
$str=str_replace(“‘”,chr(39),$str);
$str=str_replace(“<br />”,chr(13),$str);
$str=str_replace(“””,”‘”,$str);
$str=str_replace(“css”,”‘”,$str);
$str=str_replace(“CSS”,”‘”,$str);

return $str;

}

登陆页面:

20150522013249

管理员功能示例:

2015052201333920150522013534

在提交订单时引用了Magic:解决时间选择和内窗口查看附件

20150522013600

20150522020220

因为需要参考提交的确认截图来审核订单完成陪练收益结算,所以这里用内窗口形式查看图片,较为方便的解决订单审核。

20150522020248

Magic是用JavaScript脚本开发的轻量级UI组件,具有性能高效、代码量小、支持多种初始化方式等方面的优势,Web前端开发者可以使用Magic快速搭建前端功能比较复杂的网站。Magic的每个组件都有非常丰富的接口和事件处理,网站也提供了详细的使用文档和Demo演示。Web前端开发者可以通过定制组件、初始化方式和插件获得最轻量级版本。Magic的底层为高效的Tangram库。

http://tangram.baidu.com/magic/

—–

充值记录以及提现功能。

因为涉及资金流,所以会有事务涉及保证操作无误和错误回滚。

保证了订单-记录-用户余额之间的数据完整性。

20150522013613

20150522013701

用户余额查询:

20150522013752

用户余额功能完美集成了权限验证方案,由跟路由配置文件和管理员、客服、陪练、客户 权限限制。只允许前三者访问和查询。

由于系统商业保密,技术端解决方案则是

用本地数组区分页面权限功能,解决多角色切换或者多角色页面权限限制。

在数组中的设置一实时与数据后端刷新的方法验证当前用户是否具备当前页面的访问。

解决因session丢失或者cookies破解带来的权限验证问题。

比较棘手的就是在分布式架构下这种验证为了保证用户连贯性采用实时数据对比 无形中增加了数据库的压力,但在小型项目中无需缓存的介入。 MySQL的性能还是比人强的 = = ~

—–

本次项目最大的挑战可能就是自己的弱势项目,前端css的适配,应该我自己比较擅长写后端服务器架构和JavaScript逻辑。

做了手机端界面匹配,为了适应现在互联网移动端发展的需求。

20150522015135

——

/*
+———————————————————————–
| 文件概要:MYSQL数据库连接类
| 文件名称:mysql.class.php
| 创建时间:2013-12-1
+———————————————————————–
*/
class mysql {
private $server; //服务器名
private $user; //数据库用户名
private $password; //数据库密码
private $database; //数据库名
private $link; //MYSQL连接标识符
private $charset = “utf8”; //数据库编码,默认为UTF8

/*=====================================================
* 方法:__construct
* 功能:构造函数
* 参数:$server,$user,$password,$database,$charset
* 说明:实例化时自动连接数据库.
====================================================*/
function __construct($server, $user, $password, $database, $charset) {
$this->server = $server;
$this->user = $user;
$this->password = $password;
$this->database = $database;
$this->charset = $charset;
$this->connect();
}

/*====================================================
* 方法:connect
* 功能:连接数据库
* 参数:无
* 说明:连接MYSQL服务器,连接数据库,设置字符编码
===================================================*/
function connect() {
$this->link = mysql_connect($this->server, $this->user, $this->password) or die($this->error(“数据服务器连接出错,请刷新重试!”));
mysql_select_db($this->database, $this->link) or die($this->error(“数据库连接出错,请刷新重试!”));
mysql_query(“set names ‘$this->charset'”);
}

/*===================================================
* 方法:query
* 功能:执行SQL
* 参数:$sql
* 说明:对传过来的SQL语句执行,并返回结果$result资源标识符
==================================================*/
function query($sql) {
$result = mysql_query($sql, $this->link);
if (!$result) {
$this->error($sql . “语句执行失败!”);
return false;
} else {
return $result;
}
} 

/*===================================================
* 方法:fetcharray
* 功能:从结果集中取一行做为数组
* 参数:$result资源标识符
* 说明:需要提供SQL语句执行返回的资源标识符
==================================================*/
function fetcharray($result) {
return mysql_fetch_array($result);
}

/*===================================================
* 方法:fetchall
* 功能:从结果集中取出所有记录做为二维数组$arr
* 参数:$result资源标识符
* 说明:循环取所有记录保存为$arr
==================================================*/
function fetchall($result) {
$arr = array ();
while ($row = mysql_fetch_array($result)) {
$arr[] = $row;
}
mysql_free_result($result);
return $arr;
}

/*===================================================
* 方法:numrows
* 功能:统计结果集中记录数
* 参数:$result资源标识符
* 说明:统计行数
==================================================*/
function numrows($result) {
return mysql_num_rows($result);
}

/*===================================================
* 方法:numfields
* 功能:统计结果集中字段数
* 参数:$result资源标识符
* 说明:统计字段数
==================================================*/
function numfields($result) {
return mysql_num_fields($result);
}

/*===================================================
* 方法:affectedrows
* 功能:取得前一次MySQL操作所影响的记录行数
* 参数:无
* 说明:取得前一次MySQL操作所影响的记录行数
==================================================*/
function affectedrows() {
return mysql_affected_rows($this->link);
}

/*===================================================
* 方法:version
* 功能:取得MYSQL版本
* 参数:无
* 说明:取得当前数据库服务器MYSQL的版本
==================================================*/
function version() {
return mysql_get_server_info();
}

/*===================================================
* 方法:insertid
* 功能:取得上一步INSERT操作产生的ID
* 参数:无
* 说明:取得上一步INSERT操作产生的自增字段ID
==================================================*/
function insertid() {
return mysql_insert_id($this->link);
}

/*===================================================
* 方法:checksql
* 功能:检查SQL语句
* 参数:SQL语句
* 说明:过滤sql注入
==================================================*/
function checksql($db_string, $querytype = ‘select’) {
$clean = ”;
$old_pos = 0;
$pos = – 1;

//如果是普通查询语句,直接过滤一些特殊语法
if ($querytype == ‘select’) {
$notallow1 = “[^0-9a-z@\._-]{1,}(union|sleep|benchmark|load_file|outfile)[^0-9a-z@\.-]{1,}”;

//$notallow2 = “–|/\*”;
if (eregi ( $notallow1, $db_string )) {
exit ( “<font size=’5′ color=’red’>Safe Alert: Request Error step 1 !</font>” );
}
}

//完整的SQL检查
while ( true ) {
$pos = strpos ( $db_string, ‘\”, $pos + 1 );
if ($pos === false) {
break;
}
$clean .= substr ( $db_string, $old_pos, $pos – $old_pos );
while ( true ) {
$pos1 = strpos ( $db_string, ‘\”, $pos + 1 );
$pos2 = strpos ( $db_string, ‘\\’, $pos + 1 );
if ($pos1 === false) {
break;
} elseif ($pos2 == false || $pos2 > $pos1) {
$pos = $pos1;
break;
}
$pos = $pos2 + 1;
}
$clean .= ‘$s$’;
$old_pos = $pos + 1;
}
$clean .= substr ( $db_string, $old_pos );
$clean = trim ( strtolower ( preg_replace ( array (‘~\s+~s’ ), array (‘ ‘ ), $clean ) ) );

//老版本的Mysql并不支持union,常用的程序里也不使用union,但是一些黑客使用它,所以检查它
if (strpos ( $clean, ‘union’ ) !== false && preg_match ( ‘~(^|[^a-z])union($|[^[a-z])~s’, $clean ) != 0) {
$fail = true;
}

//发布版本的程序可能比较少包括–,#这样的注释,但是黑客经常使用它们
elseif (strpos ( $clean, ‘/*’ ) > 2 || strpos ( $clean, ‘–‘ ) !== false || strpos ( $clean, ‘#’ ) !== false) {
$fail = true;
}

//这些函数不会被使用,但是黑客会用它来操作文件,down掉数据库
elseif (strpos ( $clean, ‘sleep’ ) !== false && preg_match ( ‘~(^|[^a-z])sleep($|[^[a-z])~s’, $clean ) != 0) {
$fail = true;
} elseif (strpos ( $clean, ‘benchmark’ ) !== false && preg_match ( ‘~(^|[^a-z])benchmark($|[^[a-z])~s’, $clean ) != 0) {
$fail = true;
} elseif (strpos ( $clean, ‘load_file’ ) !== false && preg_match ( ‘~(^|[^a-z])load_file($|[^[a-z])~s’, $clean ) != 0) {
$fail = true;
} elseif (strpos ( $clean, ‘into outfile’ ) !== false && preg_match ( ‘~(^|[^a-z])into\s+outfile($|[^[a-z])~s’, $clean ) != 0) {
$fail = true;
}

//老版本的MYSQL不支持子查询,我们的程序里可能也用得少,但是黑客可以使用它来查询数据库敏感信息
elseif (preg_match ( ‘~\([^)]*?select~s’, $clean ) != 0) {
$fail = true;
}
if (! empty ( $fail )) {
exit ( “<font size=’5′ color=’red’>Safe Alert: Request Error step 2!</font>” );
} else {
return $db_string;
}
}

/*===================================================
* 方法:close
* 功能:关闭连接
* 参数:无
* 说明:关闭非永久数据库连接
==================================================*/
function close() {
mysql_close($this->link);
}

/*===================================================
* 方法:error
* 功能:提示错误
* 参数:$err_msg
* 说明:对给出的错误提示内容给予ECHO
==================================================*/
function error($err_msg = “”) {
if ($err_msg == “”) {
echo “Errno:” . mysql_errno . “</br>”;
echo “Error:” . mysql_error . “</br>”;
} else {
echo $err_msg;
}
}

/*===================================================
* 方法:__destruct
* 功能:析构函数
* 参数:无
* 说明:释放类,关闭连接
==================================================*/
function __destruct() {
if(is_resource($this->link)){
$this->close();
}
}
}

 

  1. 这么垃圾的团队居然寻上位.人品都差到爆了还做尼玛的IT.赶紧卖你的红薯去吧