james %!s(int64=5) %!d(string=hai) anos
achega
6877d60569

+ 4 - 0
autoload.php

@@ -0,0 +1,4 @@
+<?php
+//error_reporting(0);
+header("Content-Type:text/html;charset=utf-8");
+require  __DIR__.'/lib/'.'runtime.php';

+ 544 - 0
chat.php

@@ -0,0 +1,544 @@
+<?php
+
+require "autoload.php";
+
+$name = $_REQUEST['account'];
+$pas = $_REQUEST['paw'];
+$type = !empty($_REQUEST['type']) ? $_REQUEST['type'] : ZERO; // 1 注册 2 登录
+if (!empty($name) && !empty($pas) && isset($_REQUEST['login2'])) {
+    $_SESSION['account'] = $name;
+    $_SESSION['password'] = $pas;
+    $account = $_SESSION['account'];
+    $password = $_SESSION['password'];
+    $data = [
+        'account' => $account,
+        'password' => $password
+    ];
+    $pactdata = Utils::senFormatData('login', $data);
+} else {
+
+    echo "<script>alert('账号密码不能为空!');
+window.location.href='login.php';</script>";
+}
+/*$ChatModel = new  ChatModel($type);
+$ChatModel->userLogin();
+if (!empty($name) && !empty($pas)) {
+    log_message::info(3);
+    $data = $ChatModel->userVerif();
+    $data = is_string($data) ? json_decode($data, true) : $data;
+    $rs = [
+        'msg' => '用户名密码ok',
+        'data' => $data
+    ];
+    log_message::info(4);
+    echo json_encode($data, JSON_UNESCAPED_UNICODE);
+    // 校验用户名
+}*/
+$time = null;
+$weekarray = array("日", "一", "二", "三", "四", "五", "六"); //先定义一个数组
+$time = date('Y-m-d') . " 星期" . $weekarray[date("w")] . ' ' . date("H:i:s");
+//$pactdata = Utils::senFormatData('Intopic', $data);
+?>
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <style>
+        * {
+            margin: 0px;
+            padding: 0px;
+        }
+    </style>
+</head>
+<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
+<script type="text/javascript" src="http://localhost:8055/chatroom/res/js/jquery.cookie.js"></script>
+<script>
+
+    $(function () {
+        $("#quit").click(function () {
+            window.history.back(-1);
+        });
+
+    });
+</script>
+<body>
+<div id="user_id"></div>
+<div id="roole_id" style="display: none"></div>
+<input type="button" name="quit" id='quit' value="退出"/>
+<input type="button" name="close" value="清理记录" onclick="close_session('userinfo_data')">
+<div>
+    <marquee onMouseOut="this.start()" onMouseOver="this.stop()" id="bulletin">
+
+    </marquee>
+
+</div>
+<div id="friend" style="border:1px solid;width: 600px;height: 100px;">
+    <table id="friendtables">
+
+    </table>
+</div>
+<div style="margin-left:400px">
+    <p id="byfriend"></p>
+    <div style="border:1px solid;width: 600px;height: 500px;">
+
+        <div id="msgArea"
+             style="width:100%;height: 100%;text-align:start;resize: none;font-family: 微软雅黑;font-size: 20px;overflow-y: scroll"></div>
+    </div>
+    <div style="border:1px solid;width: 600px;height: 200px;">
+        <div style="width:100%;height: 100%;">
+            <textarea id="userMsg"
+                      style="width:100%;height: 100%;text-align:start;resize: none;font-family: 微软雅黑;font-size: 20px;"></textarea>
+        </div>
+    </div>
+    <div style="border:1px solid;width: 600px;height: 25px;">
+        <button style="float: right;" onclick="sendMsg()">发送</button>
+    </div>
+
+</div>
+</body>
+<p></p>
+<form id="ByFrom">
+    <input type="hidden" id="userid" name="userid"/>
+    <input type="hidden" id="nickname" name="nickname"/>
+</form>
+</html>
+
+<script>
+    //修改备注
+
+
+    var ws;
+    var userinfo = {};
+    var friends_info = {};
+    var strings = <?php echo $pactdata; ?>;
+    var time = "<?php echo $time;?>";
+    var timestamp = (new Date()).getTime();
+    var friend_realtime = {};
+    var storage = window.sessionStorage;
+    var Interval = {};
+    $(document).on("click", "#friendtables tr td", function () {
+        $('#byfriend').html('');
+        var _this = $(this);
+        var userinfo = _this.text();
+        var id = $(this).attr("data-name");
+        $('#byfriend').append(userinfo + "(" + id + ")");
+        $('#ByFrom #userid').text(id);
+        // 展示消息
+        var in_data_json = getJson();
+        setinfo(in_data_json, id);
+        if (Interval.id) {
+            clearInterval(Interval.id);
+        }
+
+    });
+    $(document).on("reload", "#friendtables tr td", function () {
+        $("#friendtables").each(function () {
+
+            var _this = $(this);
+            var text = null;
+            var userinfo = _this.text();
+            var value = $(_this).parent().parent().find('[data-name=' + roole + ']').text();
+
+        });
+
+    });
+
+    $("#friendtables tr").each(function () {
+        var _this = $(this);
+        var text = null;
+        var userinfo = _this.text();
+        if (userinfo) {
+            // 设置
+        }
+
+    });
+
+    function client_info(roole) {
+        $("#friendtables").each(function () {
+            //alert(2222);
+            var _this = $(this);
+            var text = null;
+            var userinfo = _this.text();
+            var value = $(_this).parent().parent().find('[data-name=' + roole + ']').text();
+            //var itemName = $("table tr").attr("data-name");
+            //console.log("clicen_info"+itemName);
+            //var v1 = _this.getAttribute('data-name');
+
+            /* if (userinfo == roole) {
+                 // 设置
+                 alert(roole);
+             }
+             else {
+                 alert('and info:' + userinfo);
+             }*/
+
+        });
+
+    }
+
+    $(function () {
+        link();
+
+
+    })
+
+    function link(accountid) {
+        ws = new WebSocket("ws://192.168.0.183:9501");//连接服务器
+
+        ws.onopen = function (event) {
+            console.log(event);
+            // login
+
+            var data_message = JSON.stringify(strings);
+            // login
+            ws.send(data_message);
+            // get userInfo
+            alert('连接了');
+        };
+
+        ws.onmessage = function (event) {
+
+            // 这里去处理解析服务api的相关接口
+            var obj = JSON.parse(event.data);
+            var serdat = obj.msg;
+            var status = obj.status;
+            var pact = obj.pact;
+
+            // 回调成功
+            if (status == 1) {
+                //login
+
+                switch (pact) {
+                    case 'login':
+                        // 获取用户信息
+                        var nick_name = obj.msg.nick_name;
+                        $('#ByFrom #nickname').text(nick_name);
+                        var id = obj.msg.id;
+                        // 获取用户好友信息bulletin
+                        $("#bulletin").append("Welcome back " + nick_name + "!!");
+                        $("#user_id").append("ID :: " + id);
+                        $("#roole_id").append(id);
+                        var friendinfo = obj.msg.friendinfo
+                        // 展示好好友信息列表
+                        //$("#friend").append("<table id='friendtables'>");
+                        var html = '';
+
+                        for (var p in friendinfo) {//遍历json数组时,这么写p为索引,0,1
+                            var nickname = friendinfo[p].nick_name;
+                            var id = friendinfo[p].id;
+                            var status = friendinfo[p].status;
+                            status = (nickname != "" && status == 1
+                            )
+                                ? '在线' : '离线'
+                            html += "<tr><td data-name=" + id + ">" + nickname + status + "</td></tr>";
+                        }
+                        // data = {"pact": "sende_message","data": {"time": time, "msg": msg, "friendid": friendid, "user_id": userid}};
+                        //var data = JSON.stringify(data);
+                        $('#friendtables').append(html);
+                        //$("#friend").append("</table>");
+                        break;
+                    case 'sende_message':
+
+                        var friend_nickname = obj.msg.friend_info.nick_name;
+                        var friend_id = parseInt(obj.msg.friend_info.id);
+                        var friend_msg = obj.msg.info;
+                        var timestamp = (new Date()).getTime();
+                        friend_realtime.friend_id = friend_id;
+                        var info = "<p style='color: #0a789b'>" + "(" + friend_nickname + ")" + time + "</p>" + "<p>" + obj.msg.info + "</p>";
+                        /*var info = "<p>" + "(" + friend_nickname + ")" + obj.msg.info + "</p>";*/
+                        // 这里设置更改为提示在用户列表中闪烁灯 吧接收的消息存放缓存里
+                        // 后面当点击的时候 获取缓存的消息数据并且展现到列表上面
+                        $("#friendtables tr td").each(function (obj) {
+                            //alert("friend_id:" + friend_id);
+                            var _this = $(this);
+                            var userinfo = _this.text();
+                            // alert(userinfo);
+
+                            var dataname = $(_this).attr("data-name");
+                            //alert(dataname);
+
+                            // exportRaw('userinfo.txt', friend_nickname + ":" + friend_msg);//
+                            //localStorage
+                            //var data =
+                            // 如果列表有用户
+                            if (dataname == friend_id) {
+                                $.cookie("roolestatus", friend_id);
+                                // 根据消息的用户id存放到数组追加最后 当用户不在线的时候存放到服务端吧消息
+                                // 如果在线的时候直接发过来存放session data
+                                // 后面当用户点击消息闪动的时候读取状态未能读取的内容 并且设置session 的状态
+                                var data = {
+                                    "friend_msg": friend_msg,
+                                    "friendid": friend_id,
+                                    "friend_nickname": friend_nickname,
+                                    'create_at': time,
+                                    'status': 1
+                                };
+                                //var data = JSON.stringify(datad);
+                                var dd = $('#byfriend').text();
+                                // 并且已经非存在的对话框泽
+                                Interval.id = setInterval("changeColor()", 200);//每0.2秒变换一种颜色
+                                // 展示消息
+                                var in_data_json = setJson(data);
+
+
+                            }
+                        });
+                        //$("#msgArea").append(info);
+                        break;
+                    case 'intopic':
+                        // set json
+                        //  set info
+
+                        var in_data_json = serdat;
+                        if (in_data_json != false) {
+
+                            setinfo(in_data_json, friend_realtime.friend_id);
+                        }
+
+                        break;
+                    default:
+                        alert('无效的协议');
+                        break;
+
+                }
+
+            } else {
+
+                alert(obj.msg);
+
+                window.history.back(-1);
+
+            }
+            //var msg = "<p>" + event.data + "</p>";
+            //$("#msgArea").append(obj.status);
+            //$("#msgArea").append(msg);
+        }
+        ws.onclose = function (event) {
+            alert("已经与服务器断开连接\r\n当前连接状态:" + this.readyState);
+        };
+
+        ws.onerror = function (event) {
+            alert("WebSocket异常!");
+        };
+    }
+
+
+    var data = [];
+    data = undefined;
+
+
+    /***
+     * 客户端发消息
+     */
+    function sendMsg() {
+        var msg = $("#userMsg").val();
+        var friendid = $('#ByFrom #userid').text();
+        if (friendid == "" || friendid == null || friendid == false || friendid == "undefined") {
+            alert("请选择用户在进行发消息");
+            return false;
+        }
+        var username = $('#ByFrom #nickname').text();
+        var userid = $("#roole_id").text();
+        data = {"pact": "sende_message", "data": {"msg": msg, "friendid": friendid, "user_id": userid}};
+        var data = JSON.stringify(data);
+
+
+        var info = "<p>" + "(" + username + ")" + time + "</p>" + "<p>" + msg + "</p>";
+
+        $("#msgArea").append(info);
+
+        ws.send(data);
+    }
+
+    function changeColor() {
+        // 目前是单个 后期改为多个 通过设置cookie来进行设置
+        var roolestatus = $.cookie("roolestatus");
+
+        if (roolestatus != "undefined" && roolestatus != null && roolestatus != null) {
+
+            $("#friendtables tr td").each(function () {
+
+                var _this = $(this);
+                var userinfo = _this.text();
+                // alert(userinfo);
+                var dataname = $(_this).attr("data-name");
+
+                if (dataname == roolestatus) {
+
+                    var color = "#f00|#0f0|#00f|#880|#808|#088|yellow|green|blue|gray";
+                    color = color.split("|");
+                    var rand_color = color[parseInt(Math.random() * color.length)];
+                    $(_this).parent().css("color", rand_color);
+                }
+            });
+
+        }
+
+        //$(obj).parent().css("color", rand_color);
+    }
+
+
+    function fakeClick(obj) {
+        var ev = document.createEvent("MouseEvents");
+        ev.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
+        obj.dispatchEvent(ev);
+    }
+
+    function exportRaw(name, data) {
+        var urlObject = window.URL || window.webkitURL || window;
+        var export_blob = new Blob([data]);
+        var save_link = document.createElementNS("http://www.w3.org/1999/xhtml", "a")
+        save_link.href = urlObject.createObjectURL(export_blob);
+        save_link.download = name;
+        fakeClick(save_link);
+    }
+
+    function extend(des, src, override) {
+        if (src instanceof Array) {
+            for (var i = 0, len = src.length; i < len; i++)
+                extend(des, src[i], override);
+        }
+        for (var i in src) {
+            if (override || !(i in des)) {
+                des[i] = src[i];
+            }
+        }
+        return des;
+    }
+
+    function setinfo(data, uid) {
+
+        uid = uid ? parseInt(uid) : '';
+        var dat = [];
+        var indata = JSON.parse(data);
+        var usertitle = $('#byfriend').text();
+        //var clien_uid = $('#ByFrom #userid').text();
+        var i = 0;
+        if (uid != '') {
+            $.each(indata, function (infoIndex, info) {
+                var msg = info["friend_msg"];
+                if (msg != undefined) {
+                    var msg = info["friend_msg"];
+                    var friendid = parseInt(info["friendid"]);
+                    var friend_nickname = info["friend_nickname"];
+                    var status = info["status"];
+                    var userinfo = null;
+                    // 如果用户打开对话框口 并且状态没有获取 直接显示
+                    if (friendid === uid && status == 1 && usertitle != "") {
+                        info["status"] = 0;
+                        // 设置data的status 为1
+                        // userinfo = "(" + friend_nickname + ")" + time + "<br>" + "\n" + msg;
+                        userinfo = "<p>" + "(" + friend_nickname + ")" + time + "</p>" + "<p>" + msg + "</p>";
+
+                        $("#msgArea").append(userinfo);
+                    }
+                }
+                indata[infoIndex] = info;
+            });
+            var stringdat = JSON.stringify(indata);
+            storage.setItem('userinfo_data', stringdat);
+            // set session
+        }
+    }
+
+    /**
+     * @param data 要录入的json str
+     * @returns {*} bool and obj
+     */
+    function setJson(data = null, uid = null) {
+
+        var sum_obj = null;
+        var obj_str = null;
+
+
+        var userinfo_data = storage.getItem('userinfo_data');
+        var dacc = data;
+
+        // 如果存在准备录入合并
+        if (data != null && userinfo_data !== "" && userinfo_data != "null" && userinfo_data != null && userinfo_data != {} && userinfo_data != "[object JSON]") {
+            //storage.setItem('userinfo_data', null);
+
+            var receive_info = JSON.parse(userinfo_data);
+            var send_dat = {'pact': 'intopic', 'data': {"history_receive_info": receive_info, "receive_info": data}};
+            var indata = JSON.stringify(send_dat);
+            ws.send(indata);
+            /* //var sum_obj = extend({}, [userinfo_obj, data]);
+
+             var sum_obj = extend({}, [userinfo_obj, data]);
+             var in_sum_data = JSON.stringify(sum_obj);
+
+             storage.setItem('userinfo_data', in_sum_data);
+             return storage.getItem('userinfo_data');*/
+
+        } else if (data != null && (userinfo_data === "" || userinfo_data === null || userinfo_data === {} || userinfo_data == "[object JSON]")) {
+
+            var in_str_data = JSON.stringify(data);
+            storage.setItem('userinfo_data', in_str_data);
+            return data;
+        }
+        return false;
+    }
+
+    /****
+     *
+     * @param data 要录入的json str
+     * @returns {*}
+     */
+    function getJson() {
+
+        var userinfo_data = storage.getItem('userinfo_data');
+        if (userinfo_data !== "" && userinfo_data != null && userinfo_data != {} && userinfo_data != "[object JSON]") {
+            return userinfo_data;
+        }
+    }
+
+    function close_session(key = null) {
+
+        var sessiontor = window.sessionStorage;
+        if (key && key != null) {
+            var msg = sessiontor.getItem(key);
+
+            var d = sessiontor.removeItem(msg);
+            if (d) {
+                alert('清理成功' + key);
+                return;
+            }
+            alert('清理失败' + key);
+        }
+    }
+
+    function concat(jsonbject1, jsonbject2) {
+
+        var resultJsonObject = {};
+        for (var attr in jsonbject1) {
+            resultJsonObject[attr] = jsonbject1[attr];
+        }
+        for (var attr in jsonbject2) {
+            resultJsonObject[attr] = jsonbject2[attr];
+        }
+        return resultJsonObject;
+    }
+
+    /**
+     *
+     * @param old_data
+     * @param now_data
+     * @constructor
+     */
+    function InServerTopicInfo(old_data, now_data) {
+        $.ajax({
+            type: 'POST',
+            url: '/active/loadserver',
+            dataType: 'json',
+            success: function (result) {
+                if (result.errcode == 0) {
+                    var zTree;
+                    $.fn.zTree.init($("#tree"), setting, result.msg);
+                    zTree = $.fn.zTree.getZTreeObj("tree");
+                    zTree.expandAll(true);
+                }
+            }
+        });
+    }
+
+</script>

+ 60 - 0
chatser.php

@@ -0,0 +1,60 @@
+<?php
+
+$server = new swoole_websocket_server('0.0.0.0', 9501);
+
+$server->on("open", "openServer");
+$server->on("message", "messageServer");
+$server->on("close", "closeServer");
+$server->on("workerStart", 'isOnWorkerStart');
+$user_id = 0;
+function isOnWorkerStart($server, $worker_id)
+{
+    include "autoload.php";
+
+    log_message::info(" isOnWorkerStart ");
+}
+
+/**
+ * open server
+ * @param $server
+ * @param $request
+ */
+function openServer($server, $request)
+{
+    log_message::info(" openServer ", $request);
+    echo "server: handshake success with fd{$request->fd}";
+}
+
+function messageServer($server, $frame)
+{
+    //require "autoload.php";
+
+    log_message::info("@@@@@@@@@@@@@@@client messageServer Info", " server fd", $frame->fd, " server data", $frame->data);
+
+    $chat = new ChatModel($server, $frame->fd, $frame->data);
+    log_message::info("@@@@@@@@@@@@@@@client messageServer in class chatmodel");
+    echo $chat;
+    // 解包
+
+    // 处理之后返回发包开始
+    // MODE 里进行处理
+
+    // 对应用户数据
+    /*foreach ($server->connections as $key => $fd) {
+        $user_message = $frame->data;
+        log_message::info(" messageServer ", $user_message);
+        $server->push($fd, "fd1212121" . $user_message);
+    }*/
+}
+
+function closeServer($ser, $fd)
+{
+
+    $data = ['pact' => 'quit'];
+    $chat = new ChatModel($ser, $fd, $data);
+    log_message::info(" client ", $fd, $data);
+    echo "client {$fd} closed\n";
+}
+
+
+$server->start();

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 494 - 0
elk.php


+ 2 - 0
index.php

@@ -0,0 +1,2 @@
+<?php
+require "autoload.php";

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1113 - 0
lib/activitesmodel.php


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1032 - 0
lib/activityser.php


+ 243 - 0
lib/chataser.php

@@ -0,0 +1,243 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2018/9/26 0026
+ * Time: 下午 6:28
+ */
+class  ChataSer extends Mysqldb
+{
+    private static $mysql;
+    public $redis = null;
+    private static $appid = null;
+    protected $game_db_name = 'gank_activites';
+    protected $redis_prefix = 'gank_wechat_activites';
+    protected $activity_reward_table = 'app_user_reward';
+    protected $redis_prize_key = null;
+    protected static $activity_user_table = null;
+    protected static $activity_prize_dbname = 'wechat_prize_config';
+    protected $login_table = 'receivelogin';
+    protected static $consignee_table = 'wechat_user_consignee';
+    protected static $virtual_item_prize_table = 'wechat_virtual_item_prize';
+    protected static $table = 'tb_user';
+    public static $prize_info = null;
+    protected static $wechat_stat_lottery_tab = 'wechat_stat_lottery_info';
+    protected static $wechat_stat_webclick_tab = 'wechat_stat_web_click';
+    const LIMIT_ONE = 1;
+    const K_EXPICE_TIME = 3600;
+
+    #----------------
+    protected $user_table = "tb_user";
+    protected static $friend_table = "tb_friendid";
+    protected static $tb_topic_table = "tb_topic";
+
+    function __construct()
+    {
+        self::$mysql = new Mysqldb();
+        //$this->redis = new Xredis();
+    }
+
+    //登录获取
+    public function getdbCharUserInfo($account, $password)
+    {
+        $sql = "SELECT * FROM tb_user WHERE account='" . $account . "' AND password='" . $password . "'   limit 1 ";
+
+        if (self::$mysql->query($sql)) {
+            return self::$mysql->fetch_row();
+        }
+        return false;
+
+    }
+
+    public function getByIdUserinfo($id)
+    {
+
+        $sql = "SELECT * FROM tb_user WHERE id='" . $id . "'   limit 1 ";
+
+        if (self::$mysql->query($sql)) {
+            return self::$mysql->fetch_row();
+        }
+        return false;
+    }
+
+    public function addUserInfo($data)
+    {
+
+        if (!self::$mysql->insert($this->user_table, $data)) {
+            log_message::info('insert indo db saveuserinfo false');
+            return false;
+        }
+        return true;
+    }
+
+    /***
+     * 添加缓存消息
+     * @param $data
+     * @return bool
+     */
+    public function addTopitInfo($data)
+    {
+        if (!self::$mysql->insert(self::$tb_topic_table, $data)) {
+            log_message::info('insert indo db tb_topic_table false');
+            return false;
+        }
+        return true;
+    }
+
+    /***
+     *
+     * 更新用户信息
+     */
+    public function setUser($id, $applydata)
+    {
+        $res = self::$mysql->update2($this->user_table, $applydata, 'id=:id', array('id' => $id));
+
+        if ($res) {
+
+            return true;
+        }
+        log_message::info("用户变更false");
+        return false;
+    }
+
+    /***
+     *
+     * 退出更新用户信息
+     */
+    public function setFdUser($fd, $applydata)
+    {
+        $res = self::$mysql->update2($this->user_table, $applydata, 'fd=:fd', array('fd' => $fd));
+
+        if ($res) {
+
+            return true;
+        }
+        log_message::info("用户变更false");
+        return false;
+    }
+    /***
+     * 更新用户管道
+     */
+
+    /***
+     * Save Userinfo
+     * @param $data ['openid']
+     * @return array|bool|mixed|null
+     */
+    public function saveCharUserInfo($data)
+    {
+        //$openid = isset($data['openid']) ? $data['openid'] : ZERO;
+        $account = isset($data['account']) ? $data['account'] : ZERO;
+        $password = isset($data['password']) ? $data['password'] : ZERO;
+        $db_user_info = $this->getdbCharUserInfo($account, $password);
+
+        // 如果db 也不存在那么 cache 与 redis 都有进行录入set
+        if (empty($db_user_info)) {
+            // 没有该账户
+            // 这个时候注意参数 $data 是客户端新用户第一次进来初始的参数
+            /* if (!self::$mysql->insert(self::$table, $data)) {
+                 log_message::info('insert indo db saveuserinfo false');
+             }
+             $data['status'] = ONE;
+             return $data;*/
+            // 如果不存在或者密码不正确则进行提示
+            // 缓存后期进行添加
+            return false;
+        }
+        // 更新fd
+        log_message::info("db user info id ", $db_user_info['id']);
+
+        if (!$this->setUser($db_user_info['id'], $data)) {
+            //
+            log_message::info('user edit is false');
+        }
+
+        $db_user_info['status'] = TWO;
+        // 存在账户
+        return $db_user_info;
+    }
+
+    /***
+     * add user
+     */
+    public function addFriend($data)
+    {
+        if (!self::$mysql->insert(self::$friend_table, $data)) {
+            log_message::info('insert addFriend db addFriend false');
+            return false;
+        }
+        return true;
+    }
+
+    /***
+     * 好友列表
+     */
+    public function friendidInfo($uid)
+    {
+
+        $sql = "SELECT * FROM tb_user WHERE id in (SELECT friendid FROM tb_friendid WHERE uid='" . $uid . "')";
+
+        if (self::$mysql->query($sql)) {
+            return self::$mysql->fetch_all();
+        }
+        return false;
+    }
+
+    /***
+     * 好友状态变更  1-申请中 2-已拒绝 3-已接收 4已拉黑
+     * $applydata = ['apply_status' => $apply_status]
+     */
+    public function setFriendid($uid, $applydata)
+    {
+        $res = self::$mysql->update2(self::$friend_table, $applydata, 'uid=:uid', array('uid' => $uid));
+        if ($res) {
+
+            return true;
+        }
+        log_message::info("好友变更false");
+        return false;
+    }
+
+    /**
+     * 发送消息内容
+     */
+    public function addusersendMessage($data)
+    {
+
+        if (!self::$mysql->insert(self::$tb_topic_table, $data)) {
+            log_message::info('insert addFriend db addFriend false');
+            return false;
+        }
+        return true;
+    }
+
+    /***
+     * 登录轮训缓存消息
+     * @param $uid
+     */
+    public function usersendMessageinfo($uid)
+    {
+        $sql = "SELECT * FROM " . self::$tb_topic_table . " WHERE receiveuid='" . $uid . "'";
+
+        if (self::$mysql->query($sql)) {
+            return self::$mysql->fetch_all();
+        }
+        return false;
+    }
+
+    /***
+     * 更改消息状态
+     */
+    public function setUserMessageStatus($message_status, $id)
+    {
+        $res = self::$mysql->update2(self::$tb_topic_table, ['message_status' => $message_status], 'id=:id', array('id' => $id));
+        if ($res) {
+            return true;
+        }
+        log_message::info("update  message status false");
+        return false;
+    }
+
+
+}

+ 421 - 0
lib/chatmodel.php

@@ -0,0 +1,421 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2018-10-11
+ * Time: 下午 06:19
+ */
+class ChatModel
+{
+
+    public $roole_name = null;
+    public $roole_password = null;
+    public $roole_type = null;
+    public $request = null;
+    public $time = null;
+
+    protected $uid = null;
+    protected static $config = null;
+
+    private $user_info = null;
+    private $utils = null;
+    private $service = null;
+
+    //
+    private static $pact = null;
+    private static $clien_data = null;
+
+    private $swoole = null;
+    private $clien_fd = null;
+    private $message = null;
+    private $friendid_info = null;
+
+    public function __construct($swoole_server = null, $fd = null, $data = null)
+    {
+        log_message::info("++++++++++++++++++ fd", $fd);
+        $this->utils = new Utils();
+        $this->service = new ChataSer();
+        $this->time = date('Y-m-d H:i:s', time());
+        $this->swoole = $swoole_server;
+        $this->clien_fd = $fd;
+        log_message::info("+++++++++++++++++++ clien_info", $data);
+        $this->message = Utils::decodeDate($data);
+
+        self::$pact = self::isParame($this->message, 'pact');
+        self::$clien_data = self::isParame($this->message, 'data');
+
+        log_message::info("++++++++++++++++++ pact", self::$pact);
+        log_message::info("++++++++++++++++++ clien_data", self::$clien_data);
+
+        self::$config = Utils::config();
+        log_message::info("++++++++++++++++++config", json_encode(self::$config));
+        $pact_action = $this->IsPact();
+        log_message::info("++++++++++++++++++ pact_action ", $pact_action);
+        if (method_exists('ChatModel', $pact_action)) {
+            log_message::info("++++++++++++++++++", $pact_action);
+            return $this->$pact_action();
+        } else {
+
+            log_message::info("++++++++++++++++++ pact_action is function false", $pact_action);
+        }
+    }
+
+    /***
+     * 初始基础配置数据
+     * @return bool
+     */
+    public function httpData($type = null)
+    {
+
+        //$request = file_get_contents("php://input");
+
+        /* $this->request = $_REQUEST;
+         log_message::info(json_encode($_REQUEST));
+         $this->roole_name = self::isParame($_REQUEST, 'account');
+         $this->roole_password = self::isParame($_REQUEST, 'paw');
+         $this->roole_type = self::isParame($_REQUEST, 'type');*/
+    }
+
+    public function friendInfo()
+    {
+        $uid = self::$clien_data['id'];
+
+        $res = $this->service->friendidInfo($uid);
+        if ($res) {
+            return Utils::errorCode($res, SUCCESS);
+        }
+        return Utils::errorCode('好友列表空');
+    }
+
+    /***
+     * 登录
+     */
+    public function login()
+    {
+        log_message::info("~~~~~~~~~~~~~~~~  is login");
+        $account = self::$clien_data['account'];
+        $password = self::$clien_data['password'];
+        if (isDatas($account) && isDatas($password)) {
+            log_message::info("~~~~~~~~~~~~~~~~  is login and account a pass is ok");
+            $time = date('Y-m-d H:i:s', time());
+
+            $data = [
+                'account' => $account,
+                'nick_name' => $account,
+                'password' => $password,
+                'creat_at' => $time,
+                'login_at' => $time,
+                'fd' => $this->clien_fd,
+                'status' => ONE,
+            ];
+
+            $this->user_info = $this->service->saveCharUserInfo($data);
+            if (isDatas($this->user_info)) {
+                // 获取好友列表信息
+                //
+                $this->user_info['friendinfo'] = $this->service->friendidInfo($this->user_info['id']);
+
+                log_message::info(Utils::errorCode($this->user_info, SUCCESS, 'login'));
+
+                return $this->swoole_pull(Utils::errorCode($this->user_info, SUCCESS, 'login'));
+            }
+        }
+        log_message::info("账号密码错误!");
+        $this->swoole_pull(Utils::errorCode("账号密码错误"));
+        return false;
+    }
+
+    public function intopic()
+    {
+        //{'pact': 'intopic', 'data': {"history_receive_info": receive_info, "receive_info": data}};
+        $recive_dat = self::$clien_data['receive_info'];
+        $history_recive_dat = self::$clien_data['history_receive_info'];
+        log_message::info("intopic******recive_dat*************", $recive_dat);
+        log_message::info("intopic******history_recive_dat*************", $history_recive_dat);
+
+        echo "-------------------------" . "<br>";
+        //$recive_dat = json_decode($recive_dat, true);
+
+        //$history_recive_dat = json_decode   ($history_recive_dat, true);
+        $sumdata = null;
+
+        $history_recive = isDatas($history_recive_dat) ? $history_recive_dat : $recive_dat;
+
+        $dim = Utils::arrayDimension($history_recive);
+        log_message::info("intopic dim**********", $dim);
+        if ($dim == ONE) {
+            $sumdata[] = $history_recive;
+            $sumdata[] = $recive_dat;
+            $indata = json_encode($sumdata, JSON_UNESCAPED_UNICODE);
+            log_message::info("[][][][][][][]intopic dim**********", $dim, $indata);
+            return $this->swoole_pull(Utils::errorCode($indata, SUCCESS, 'intopic'));
+        }
+
+        if ($dim == TWO) {
+            //$sumdata = array_push($history_recive_dat, $recive_dat);
+            $history_recive_dat[time()] = $recive_dat;
+            $sumdata = $history_recive_dat;
+            $indata = json_encode($sumdata, JSON_UNESCAPED_UNICODE);
+            log_message::info("[][][][][][][]intopic*************dim", $dim, $indata);
+            return $this->swoole_pull(Utils::errorCode($indata, SUCCESS, 'intopic'));
+        }
+        return $this->swoole_pull(Utils::errorCode('msg data is null', SUCCESS, 'intopic'));
+    }
+
+    public function sende_message()
+    {
+        //data = {"pact": "sende_message", "data": {"msg": msg, "friendid": friendid, "user_id": userid}};
+
+        $uid = self::$clien_data['user_id'];
+        // 接收者id
+        $friendid = self::$clien_data['friendid'];
+        $info = self::$clien_data['msg'];
+        $this->user_info = $this->service->getByIdUserinfo($uid);
+        // 接收者信息
+        $this->friendid_info = $this->service->getByIdUserinfo($friendid);
+        $friendid_info_fd = $this->friendid_info['fd'];
+        if ($friendid_info_fd) {
+            // 中心根据接收者
+            // 当返回数据的时候好友的相关角色就互换了
+            // 接收者就成了自己
+            // 发消息的就成了推送者 及 friend_info
+            $data = [
+                'friend_info' => $this->user_info, //
+                'user_info' => $this->friendid_info,
+                'info' => $info
+
+            ];
+            $data = Utils::errorCode($data, SUCCESS, 'sende_message');
+            // 如果接收者不在线那么存储到数据缓存等到上线的时候进行推送给他
+            if ($this->friendid_info['status'] == ZERO) {
+
+                $topic_data = [
+                    'receiveuid' => $friendid,
+                    'senduid' => $uid,
+                    'send_user_name' => $this->user_info['nick_name'],
+                    'message_status' => ZERO,
+                    'message' => $info,
+                    'send_at' => $this->time
+                ];
+                $res = $this->service->addTopitInfo($topic_data);
+                if (!$res) {
+                    log_message::info("发送消息失败!");
+                    $this->swoole_pull(Utils::errorCode("发送消息失败!"));
+                }
+            }
+            $this->swoole->push($friendid_info_fd, $data);
+        }
+        // data = {"pact": "sende_message", "data": {"msg": msg, "friendid": friendid, "user_id": userid}};
+    }
+
+    public function index($pact)
+    {
+        switch ($pact) {
+            case 'login' :
+                $this->login();
+                break;
+            default:
+                break;
+        }
+
+    }
+
+    /**
+     * 退出
+     */
+    public function quit()
+    {
+        $this->clien_fd;
+        $res = $this->service->setFdUser($this->clien_fd, ['status' => ZERO]);
+        if ($res) {
+            // 推送用户已经退出了
+            log_message::info("退出状态更新成功");
+            log_message::info("quit 已经退出了");
+        } else {
+            log_message::info("退出状态更新失败");
+        }
+
+    }
+
+    /***
+     * 注册
+     * @return bool
+     */
+    public function registered()
+    {
+
+        $account = self::$clien_data['account'];
+        $password = self::$clien_data['password'];
+        if (isDatas($account) && isDatas($password)) {
+            $time = date('Y-m-d H:i:s', time());
+
+            $data = [
+                'nick_name' => $account,
+                'password' => $password,
+                'creat_at' => $time,
+                'login_at' => $time,
+                'fd' => $this->clien_fd,
+            ];
+
+            $req = $this->service->addUserInfo($data);
+            if ($req) {
+                return true;
+            }
+            return false;
+        }
+        $this->swoole_pull(Utils::errorCode("账号密码为空"));
+        return false;
+    }
+
+    /***
+     * pact解码
+     */
+    public function IsPact()
+    {
+        if (self::isParame($this->message, 'pact')) {
+            log_message::info("IsPact isParame 11");
+            // 是否存在协议
+            log_message::info("IsPact message 1110", $this->message['pact']);
+            if ($this->isAction($this->message['pact'])) {
+                log_message::info("IsPact isParame 22");
+                return $this->message['pact'];
+            }
+        }
+        log_message::info(Utils::errorCode('协议异常', FAILURE));
+
+        $this->swoole_pull(Utils::errorCode('协议异常', FAILURE));
+
+        return false;
+    }
+
+    public function isAction($pact)
+    {
+        log_message::info("isAction", json_encode(self::$config['server_pact']));
+
+        log_message::info("isAction22", self::isParame(self::$config['server_pact'], $pact));
+
+        if (in_array($pact, self::$config['server_pact'])) {
+
+            return $pact;
+        }
+        return false;
+    }
+
+    public function swoole_pull($data)
+    {
+        $this->swoole->push($this->clien_fd, $data);
+    }
+
+    /***
+     * 参数是否为空
+     * @param $data
+     * @return bool
+     */
+    public static function isParame($data, $key)
+    {
+        if ($red = isDatas($data, $key)) {
+            return $red;
+        }
+        log_message::info("$key is null ");
+        //exit(Utils::sendResults("$key is null"));
+        //exit(Utils::errorCode("$key is null ", FAILURE));
+        return null;
+    }
+
+    public function parameVerif()
+    {
+        if (isBlank($this->roole_name)) {
+            log_message::info('roole_name is null');
+            exit(Utils::sendResults("roole_name is null "));
+        }
+        if (isBlank($this->roole_password)) {
+            log_message::info('roole_password is null');
+            exit(Utils::sendResults("roole_password is null "));
+        }
+        $_SESSION['account'] = $this->roole_name;
+        $_SESSION['password'] = $this->roole_password;
+        $_SESSION['type'] = $this->roole_type;
+        return true;
+    }
+
+    /***
+     * 添加好友
+     */
+    public function addFriend()
+    {
+
+    }
+
+    /***
+     *
+     */
+    public function userVerif()
+    {
+        // 获取服务端用户密码
+        // 正确返回true 跳转登录界面
+        // else false 提示失败
+        $this->initializeUserinfo();
+        return $this->verifAccount();
+    }
+
+    /***
+     * @param array $userdata
+     * @return bool
+     */
+    public function initializeUserinfo($userdata = [])
+    {
+
+        $data = [
+            'nick_name' => $this->roole_name,
+            'account' => $this->roole_name,
+            'password' => $this->roole_password,
+            'creat_at' => date('Ymd', time()),
+            'type' => $this->roole_type
+            //'sign_rule'=>$ruleinfo,
+        ];
+        $data = isDatas($userdata) ? $userdata : $data;
+
+        $this->user_info = $this->service->saveCharUserInfo($data);
+        // 如果type 是注册 但是已经存在用户或者 空的进行注册 返回注册成功 二类 返回已经存在用户
+        // 如果type 是登录 但是
+        // 最好是分开设置注册就是注册的函数 登录就是登录的函数 每次只要
+
+        if ($this->user_info) {
+            return $this->user_info;
+        }
+        return Utils::sendResults("获取信息失败");
+    }
+
+    public function verifAccount()
+    {
+        $roole_name = $this->roole_name;
+        $roole_password = $this->roole_password;
+        if ($roole_name = $this->user_info['account'] && $roole_password == $this->user_info['password']) {
+            log_message::info(Utils::sendResults('ok...', $this->user_info));
+            return Utils::sendResults('ok', $this->user_info);;
+        }
+        return false;
+    }
+
+    public function userLogin()
+    {
+        $db_user_info = $this->service->getdbCharUserInfo($this->roole_name);
+        $this->uid = $db_user_info['id'];
+        $this->user_info = $db_user_info;
+        $roole_name = $this->roole_name;
+        $roole_password = $this->roole_password;
+        if ($roole_name = $db_user_info['account'] && $roole_password == $db_user_info['password']) {
+            return Utils::sendResults('登录成功', $this->user_info, SUCCESS);
+        }
+        return Utils::sendResults('账号或密码错误!', $this->user_info, FAILURE);;
+    }
+
+    public function friendList()
+    {
+
+        $this->service->friendidInfo($this->uid);
+    }
+    //~
+
+}

+ 240 - 0
lib/config.php

@@ -0,0 +1,240 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2018/9/26 0026
+ * Time: 下午 12:46
+ */
+/*'host' => 'rm-uf68i53m6uaapa9t0.mysql.rds.aliyuncs.com',
+'user' => 'unicorndb',
+'port' => 3306,
+'password' => 'HHgankStudio@it520',
+'dbname' => 'unicorn_log',
+'dbcharset' => 'utf8'*/
+$daytimes = date(DATE_FORMAT_S, time());
+return $config = [
+    'rank_api' => [
+        'host' => 'http://event.djsh5.com/rank/?',
+        'game_cache' => [
+            'host' => '192.168.0.140',
+            'port' => 6379,
+            'auth' => '123456'
+        ]
+    ],
+    'game_db' => [
+        'host' => 'rm-uf66699x295178337127.mysql.rds.aliyuncs.com',
+        'user' => 'activedb',
+        'port' => 3306,
+        'password' => 'GankDBCon88t72',
+        'dbname' => 'gank_activites',
+        'dbcharset' => 'utf8'
+    ],
+    'game_stat_db' => [
+        'host' => 'rm-uf66699x295178337127.mysql.rds.aliyuncs.com',
+        'user' => 'activedb',
+        'port' => 3306,
+        'pass' => 'GankDBCon88t72',
+        'dbname' => 'gank_activites',
+        'dbcharset' => 'utf8'
+    ],
+    'game_prize' => [
+        '1' => array('prize_id' => 1, 'prize' => '5元京东卡', 'rate' => 200, 'number' => 1, 'status' => 0, 'upper_limit' => 165, 'frequency' => 0, 'prize_type' => 0, 'create_at' => $daytimes),
+        '2' => array('prize_id' => 2, 'prize' => '爱奇艺月卡', 'rate' => 50, 'number' => 1, 'status' => 0, 'upper_limit' => 50, 'frequency' => 0, 'prize_type' => 0, 'create_at' => $daytimes),
+        '3' => array('prize_id' => 3, 'prize' => '独角兽充电宝', 'rate' => 1, 'number' => 1, 'status' => 1, 'upper_limit' => 10, 'frequency' => 0, 'prize_type' => 0, 'create_at' => $daytimes),
+        '4' => array('prize_id' => 4, 'prize' => '10元京东卡', 'rate' => 100, 'number' => 1, 'status' => 0, 'upper_limit' => 100, 'frequency' => 0, 'prize_type' => 0, 'create_at' => $daytimes),
+        '5' => array('prize_id' => 5, 'prize' => '独角兽挂饰', 'rate' => 2, 'number' => 1, 'status' => 1, 'upper_limit' => 15, 'frequency' => 0, 'prize_type' => 0, 'create_at' => $daytimes),
+        '6' => array('prize_id' => 6, 'prize' => '谢谢参与', 'rate' => 1000, 'status' => 0, 'number' => 0, 'upper_limit' => 0, 'frequency' => 0, 'prize_type' => 0, 'create_at' => $daytimes),
+    ],
+    'server_pact' => array('login', 'sende_message', 'quit', 'intopic'),
+    'rand_at'=>[
+        '2019/1/3',
+        '2019/1/4',
+        '2019/1/5',
+        '2019/1/6',
+        '2019/1/7',
+        '2019/1/8',
+        '2019/1/9',
+        '2019/1/10',
+        '2019/1/11',
+        '2019/1/12',
+        '2019/1/13',
+        '2019/1/14',
+        '2019/1/15',
+        '2019/1/16',
+        '2019/1/17',
+        '2019/1/18',
+        '2019/1/19',
+        '2019/1/20',
+        '2019/1/21',
+        '2019/1/22',
+        '2019/1/23',
+        '2019/1/24',
+        '2019/1/25',
+        '2019/1/26',
+        '2019/1/27',
+        '2019/1/28',
+        '2019/1/29',
+        '2019/1/30',
+        '2019/1/31',
+        '2019/2/1',
+        '2019/2/2',
+        '2019/2/3',
+        '2019/2/4',
+        '2019/2/5',
+        '2019/2/6',
+        '2019/2/7',
+        '2019/2/8',
+        '2019/2/9',
+        '2019/2/10',
+        '2019/2/11',
+        '2019/2/12',
+        '2019/2/13',
+        '2019/2/14',
+        '2019/2/15',
+        '2019/2/16',
+        '2019/2/17',
+        '2019/2/18',
+        '2019/2/19',
+        '2019/2/20',
+        '2019/2/21',
+        '2019/2/22',
+        '2019/2/23',
+        '2019/2/24',
+        '2019/2/25',
+        '2019/2/26',
+        '2019/2/27',
+        '2019/2/28',
+        '2019/3/1',
+        '2019/3/2',
+        '2019/3/3',
+        '2019/3/4',
+        '2019/3/5',
+        '2019/3/6',
+        '2019/3/7',
+        '2019/3/8',
+        '2019/3/9',
+        '2019/3/10',
+        '2019/3/11',
+        '2019/3/12',
+        '2019/3/13',
+        '2019/3/14',
+        '2019/3/15',
+        '2019/3/16',
+        '2019/3/17',
+        '2019/3/18',
+        '2019/3/19',
+        '2019/3/20',
+        '2019/3/21',
+        '2019/3/22',
+        '2019/3/23',
+        '2019/3/24',
+        '2019/3/25',
+        '2019/3/26',
+        '2019/3/27',
+        '2019/3/28',
+        '2019/3/29',
+        '2019/3/30',
+        '2019/3/31',
+        '2019/4/1',
+        '2019/4/2',
+        '2019/4/3',
+        '2019/4/4',
+        '2019/4/5',
+        '2019/4/6',
+        '2019/4/7',
+        '2019/4/8',
+        '2019/4/9',
+        '2019/4/10',
+        '2019/4/11',
+        '2019/4/12',
+        '2019/4/13',
+        '2019/4/14',
+        '2019/4/15',
+        '2019/4/16',
+        '2019/4/17',
+        '2019/4/18',
+        '2019/4/19',
+        '2019/4/20',
+        '2019/4/21',
+        '2019/4/22',
+        '2019/4/23',
+        '2019/4/24',
+        '2019/4/25',
+        '2019/4/26',
+        '2019/4/27',
+        '2019/4/28',
+        '2019/4/29',
+        '2019/4/30',
+        '2019/5/1',
+        '2019/5/2',
+        '2019/5/3',
+        '2019/5/4',
+        '2019/5/5',
+        '2019/5/6',
+        '2019/5/7',
+        '2019/5/8',
+        '2019/5/9',
+        '2019/5/10',
+        '2019/5/11',
+        '2019/5/12',
+        '2019/5/13',
+        '2019/5/14',
+        '2019/5/15',
+        '2019/5/16',
+        '2019/5/17',
+        '2019/5/18',
+        '2019/5/19',
+        '2019/5/20',
+        '2019/5/21',
+        '2019/5/22',
+        '2019/5/23',
+        '2019/5/24',
+        '2019/5/25',
+        '2019/5/26',
+        '2019/5/27',
+        '2019/5/28',
+        '2019/5/29',
+        '2019/5/30',
+        '2019/5/31',
+        '2019/6/1',
+        '2019/6/2',
+        '2019/6/3',
+        '2019/6/4',
+        '2019/6/5',
+        '2019/6/6',
+        '2019/6/7',
+        '2019/6/8',
+        '2019/6/9',
+        '2019/6/10',
+        '2019/6/11',
+        '2019/6/12',
+        '2019/6/13',
+        '2019/6/14',
+        '2019/6/15',
+        '2019/6/16',
+        '2019/6/17',
+        '2019/6/18',
+        '2019/6/19',
+        '2019/6/20',
+        '2019/6/21',
+        '2019/6/22',
+        '2019/6/23',
+        '2019/6/24',
+        '2019/6/25',
+        '2019/6/26',
+        '2019/6/27',
+        '2019/6/28',
+        '2019/6/29',
+        '2019/6/30',
+        '2019/7/1',
+        '2019/7/2',
+        '2019/7/3',
+        '2019/7/4',
+        '2019/7/5',
+        '2019/7/6',
+        '2019/7/7',
+        '2019/7/8',
+        '2019/7/9',
+        '2019/7/10'
+    ]
+];

+ 79 - 0
lib/define.php

@@ -0,0 +1,79 @@
+<?php
+
+define('TIMEZONE', "PRC");                // 时区设置
+date_default_timezone_set(TIMEZONE);
+
+define('DBHOST', '127.0.0.1');            // 数据库地址
+define('DBUSER', 'chatroom');                 // 数据库用户名
+define('DBPORT', 3306);
+define('DBPASSWORD', 'lmj3503791673');    // 数据库密码
+define('DBNAME', 'chatroom');              // 默认数据库
+define('DBCHARSET', 'utf8');              // 数据库字符集
+
+#wechat defaine
+define('WECHAT_APPID', 'wx6a7abf227bcd0d56');
+define('WECHAT_KEY', '13084de8fbb0038feeaa15c3d6b392e7');
+define('WECHAT_SCOPE_BASE', 'snsapi_base'); // 不弹框
+define('WECHAT_SCOPE', 'snsapi_userinfo'); // 弹框
+
+define('WECHAT_SERVER', 'https://open.weixin.qq.com/connect/oauth2/authorize');
+define('WECHAT_REDIRECT_URL', urlencode('localhost'));
+
+define('WECHAT_ACCESSTOKEN_URL', 'https://api.weixin.qq.com/sns/oauth2/access_token');
+
+#log dir
+define('DIR_SEPARATOR', "/");
+define('LINUX_LOGDIRS', dirname(dirname(__FILE__)) . '/log/'); // 日志目录
+define('WINDOWS_LOGDIRS', dirname(dirname(__FILE__)) . '/log/error.txt'); // 日志目录
+define('LOGDIRS_FILENAME', 'error.log'); // 日志目录
+define("LOG_SERVER_URL", dirname(dirname(__FILE__)) . "/log/");
+#gift code status
+define('GIFTCODE_STATUS', 0); // 正常
+define('GIFTCODE_EXPIRED_STATUS', 1); //过期
+#log url
+
+
+# class dir
+define('LIBDIR', dirname(__FILE__) . '/'); // lib
+define('LIBDIR_TWO', dirname(dirname(__FILE__)) . '/mode/'); // mode
+
+#Redis
+define('REDIS_HOST', 'd2444656u3.zicp.vip');
+define('REDIS_PORT', '6379');
+define('REDIS_AUTH', '123456');
+# time format
+define('DATE_FORMAT_S', "Y-m-d H:i:s");
+define('DATE_FORMAT_D', "Y-m-d");
+
+# res
+#file upload url
+//define('RES_URL', 'http://192.168.181.133:9095');
+//define('RES_PATH', dirname(dirname(dirname($_SERVER['DOCUMENT_ROOT']))) . '/res/config/');
+//define('RES_CONFIG_URL', 'https://d.djsh5.com');// config file url
+define('RES_CONFIG_URL', 'http://d.djsh5.com');
+//define('RES_FILE_URL','/home/projects/res/config');
+#排行榜接口地址
+define('STAT_RANKING_DIR', 'http://event.djsh5.com/rank/?');
+# 常数zero
+define('ZERO', 0);
+define('ONE', 1);
+define('TWO', 2);
+define('THREE', 3);
+define('FIVE', 5);
+define('SIX', 6);
+define('HUNDRED', 100);
+#activites
+define('ACTIVITES_STATUS', 1); // 0 未开启 1 已开启
+
+#error info
+define('SUCCESS', 1);
+define('FAILURE', -1);
+
+#swoole
+define('SWOOLE_SER_HOST', '0.0.0.0');
+define('SWOOLE_SER_PORT', 9501);
+
+# css and js dir
+
+define('CSS_DIR', dirname(dirname(__FILE__)) . '/res/css/'); // css
+define('JS_DIR', dirname(dirname(__FILE__)) . '/res/js/'); // js

+ 133 - 0
lib/log_message.php

@@ -0,0 +1,133 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2018/9/19 0019
+ * Time: 下午 1:54
+ */
+class log_message
+{
+    public static function info()
+    {
+        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
+
+        $file = str_replace(LOG_SERVER_URL, '', $trace[0]['file']);
+
+        $line = $trace[0]['line'];
+
+        if (isset($trace[1]['function'])) {
+            $function = $trace[1]['function'];
+        } else {
+            $function = 'unknow';
+        }
+
+        $message = date(DATE_FORMAT_S, time()) . '[' . $file . ": line: " . $line . ' funtion: ' . $function . ']';
+
+        foreach (func_get_args() as $item) {
+            //$message .= self::toString($item) . ' ';
+        }
+
+        $classname_file = basename($file, '.php') . '.txt';
+
+        $file_name = LOG_SERVER_URL . date(DATE_FORMAT_D, time()) . '_' . $classname_file;
+
+        if (!$file_name) {
+            return -1;
+        }
+        if (self::isCli()) {
+            self::echoLine('[INFO]' . date(DATE_FORMAT_S, time()) . ' ' . $message);
+        } else {
+            if (error_log($message . "\n", 3, $file_name) == FALSE) {
+                return -1;
+            }
+        }
+    }
+
+    /**
+     * 是不是简单基础类型(null, boolean , string, numeric)
+     * @param $object
+     * @return bool
+     */
+    public static function isPrimary($object)
+    {
+        return is_null($object) || is_bool($object) || is_string($object) || is_numeric($object);
+    }
+
+    public static function toString($object)
+    {
+        if (self::isPrimary($object)) {
+
+            return $object;
+        }
+        if (is_array($object)) {
+            return json_encode($object, JSON_UNESCAPED_UNICODE);
+        }
+        if (method_exists($object, '__toString')) {
+            return get_class($object) . '@{' . $object->__toString() . '}';
+        }
+
+        $reflection_object = new ReflectionObject($object);
+        $properties = $reflection_object->getProperties();
+        $values = array();
+        foreach ($properties as $property) {
+            if ($property->isStatic() || !$property->isPublic()) {
+                continue;
+            }
+            $name = $property->getName();
+            $value = $property->getValue($object);
+            if (isPrimary($value)) {
+                $values[$name] = $value;
+            } elseif (is_array($value)) {
+                $values[$name] = json_encode($value, JSON_UNESCAPED_UNICODE);
+            } else {
+                $values[$name] = '@' . get_class($value);
+            }
+        }
+        return get_class($object) . '@{' . json_encode($values, JSON_UNESCAPED_UNICODE) . '}';
+    }
+
+    public static function errorInfo()
+    {
+
+        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
+
+        $file = str_replace(SERVER_URL, '', $trace[0]['file']);
+        $line = $trace[0]['line'];
+
+        if (isset($trace[1]['function'])) {
+            $function = $trace[1]['function'];
+        } else {
+            $function = 'unknow';
+        }
+
+        $message = '[' . $file . ":" . $line . ' ' . $function . ']';
+        foreach (func_get_args() as $item) {
+            $message .= toString($item) . ' ';
+        }
+        return $message;
+    }
+
+    /**
+     * 方便调试输出
+     */
+    public function echoLine()
+    {
+        $message = '';
+        foreach (func_get_args() as $item) {
+            $message .= self::toString($item) . ' ';
+        }
+
+        $text = '[PID ' . getmypid() . ']' . $message;
+        if (self::isCli()) {
+            echo $text . PHP_EOL;
+        } else {
+            echo $text . '<br/>';
+        }
+    }
+
+    public static function isCli()
+    {
+        return php_sapi_name() == 'cli';
+    }
+}

+ 7 - 0
lib/lotteresmodel.php

@@ -0,0 +1,7 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2018-10-12
+ * Time: 下午 06:04
+ */

+ 7 - 0
lib/lotteryser.php

@@ -0,0 +1,7 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2018-10-12
+ * Time: 下午 06:04
+ */

+ 342 - 0
lib/mysqldb.php

@@ -0,0 +1,342 @@
+<?php
+
+class Mysqldb
+{
+    private $dbh;
+    private $statement;
+    private $dbconfig;
+
+    function __construct($dbKey = array())
+    {
+        if (count($dbKey) <= ZERO) {
+            $this->dbconfig = array
+            (
+                'host' => DBHOST,
+                'port' => DBPORT,
+                'user' => DBUSER,
+                'pass' => DBPASSWORD,
+                'dbname' => DBNAME
+            );
+        } else {
+            log_message::info("############", json_encode($dbKey));
+            $this->dbconfig = array
+            (
+                'host' => $dbKey['host'],
+                'port' => 3306,
+                'user' => $dbKey['user'],
+                'pass' => $dbKey['pass'],
+                'dbname' => $dbKey['dbname']
+            );
+            log_message::info("############", json_encode($this->dbconfig));
+        }
+
+        //$this->dbconfig = $dbconfig;
+        $dbh = $this->connect();
+
+
+        if ($this->connect()) {
+            $this->dbh = $this->connect();
+        }
+    }
+
+    private function connect()
+    {
+        $_dsn = 'mysql:host=' . $this->dbconfig['host'] . ';';
+        $_dsn .= 'port=' . $this->dbconfig['port'] . ';';
+        $_dsn .= 'dbname=' . $this->dbconfig['dbname'] . ';';
+        $_dsn .= 'charset=utf8';
+        log_message::info('Connect : ' . $_dsn);
+        try {
+            $dbLink = new PDO($_dsn, $this->dbconfig['user'],
+                $this->dbconfig['pass'], array(
+                    PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8';"));
+            $dbLink->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
+
+        } catch (PDOException $e) {
+            log_message::info('Connection failed: ' . $e->getMessage(), 'db');
+            return false;
+        }
+        return $dbLink;
+    }
+
+    public function close()
+    {
+        if (is_object($this->dbh)) {
+            $this->dbh = null;
+        }
+    }
+
+    public function query($sql, $prepare = array())
+    {
+        if (empty($sql) || !is_array($prepare) || empty($this->dbh)) {    //echo  "lod false prepare 1";
+            log_message::info("false execution failed", 'db');
+            // 重新实例化
+
+           // $msyql = new Mysqldb();
+        }
+        //log_message::info("sqll" . $sql);
+        //echo  "lod false prepare ??";
+        $dbh = $this->dbh->prepare($sql);
+        //echo  "lod false prepare ??";
+        $dbh->closeCursor();
+
+        $res = $dbh->execute($prepare);
+        //echo  "lod false prepare ??";
+        if (!$res) {
+            log_message::info("db error : " . json_encode($dbh->errorInfo()) . " sql:" . $sql, 'db');
+            return false;
+        }
+        $this->statement = $dbh;
+        return $dbh;
+    }
+
+    /**
+     *  update
+     *
+     */
+    public function update($table, $aFields, $where = '', $prepare_array = array())
+    {
+
+        if (!$where)
+            return false;
+
+        if (!is_array($aFields) || count($aFields) < 1)
+            return false;
+
+        $aSet = array();
+        foreach ($aFields as $key => $v) {
+            $aSet[] = "`{$key}`=:{$key}";
+            $prepare_array[$key] = $v;
+        }
+        $aSet && $set = implode(',', $aSet);
+        if (empty($set))
+            return false;
+
+        $sql = " UPDATE {$table} SET {$set} WHERE {$where}";
+        if ($this->query($sql, $prepare_array)) {
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     *  自定义 update
+     *
+     *
+     * public function update2($table, $aFields, $where = array())
+     * {
+     * if (!$where)
+     * return false;
+     *
+     * if (!is_array($aFields) || count($aFields) < 1)
+     * return false;
+     *
+     * $aSet = array();
+     * foreach ($aFields as $key => $v) {
+     * $aSet[] = "`{$key}`={$v}";
+     * }
+     *
+     * foreach ($where as $fileKey => $fileVar) {
+     * if (isset($whereOut)) {
+     * $whereOut[$fileKey] = "AND  {$fileKey}={$fileVar}";
+     * } else {
+     * $whereOut[$fileKey] = "WHERE {$fileKey}={$fileVar}";
+     * }
+     * }
+     * $aSet && $set = implode(',', $aSet);
+     *
+     * $wheres = implode(' ', $whereOut);
+     *
+     * $sql = " UPDATE {$table} SET {$set}  {$wheres}";
+     * //_log("updata2 sql ".$sql,'db');
+     * if ($this->mysqlQuery($sql)) {
+     * return true;
+     * }
+     * return false;
+     *
+     * } */
+    public function update2($table, $aFields, $where = '', $prepare_array = array())
+    {
+
+        if (!$where)
+            return false;
+
+        if (!is_array($aFields) || count($aFields) < 1)
+            return false;
+
+        $aSet = array();
+        foreach ($aFields as $key => $v) {
+            $aSet[] = "`{$key}`=:{$key}";
+            $prepare_array[$key] = $v;
+        }
+        $aSet && $set = implode(',', $aSet);
+        if (empty($set))
+            return false;
+
+        $sql = " UPDATE {$table} SET {$set} WHERE {$where}";
+
+        if ($this->query($sql, $prepare_array)) {
+            if ($this->rowcount() > 0) {
+                return true;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    public function mysqlQuery($sql)
+    {
+        if (empty($sql) || empty($this->dbh)) {
+            return false;
+            log_message::info("false execution failed", 'db');
+        }
+        return $this->dbh->query($sql);
+    }
+
+    /**
+     * 返回结果集
+     * @$statement PDO
+     */
+    public function fetch_all($statement = false)
+    {
+        if (!isset($statement) || empty($statement)) {
+
+            return $this->statement->fetchAll(PDO::FETCH_ASSOC);
+        }
+        return $statement->fetchAll(PDO::FETCH_ASSOC);
+    }
+
+    public function rowcount($statement = false)
+    {
+        if (!isset($statement) || empty($statement)) {
+
+            return $this->statement->rowCount();
+        }
+
+        return $statement->rowCount();
+    }
+
+    /**
+     * 取得单行记录
+     *
+     * @return array
+     */
+    public function fetch_row($statement = false)
+    {
+        if (!isset($statement) || empty($statement)) {
+
+            return $this->statement->fetch(PDO::FETCH_ASSOC);
+        }
+
+        return $statement->fetch(PDO::FETCH_ASSOC);
+    }
+
+    /**
+     * 单个录入
+     *
+     * @param type $table tables
+     * @param type $array =array(fields=>value)
+     * @param type $dbLink pdo connect
+     */
+    public function insert($table, $array = array())
+    {
+        $sql = " INSERT INTO {$table} ";
+        $fields = array_keys($array);
+        $values = array_values($array);
+        $condition = array_fill(1, count($fields), '?');
+
+        $sql .= "(`" . implode('`,`', $fields) . "`)
+		VALUES (" . implode(',', $condition) . ")";
+        log_message::info("asdasdsa" . $sql);
+        return $this->query($sql, $values);
+    }
+
+    public function insert2($table, $array = array(), $addition = null)
+    {
+        $sql = " INSERT INTO {$table} ";
+        $fields = array_keys($array);
+        $values = array_values($array);
+        $condition = array_fill(1, count($fields), '?');
+
+        $sql .= "(`" . implode('`,`', $fields) . "`)
+		VALUES (" . implode(',', $condition) . ") " . $addition;
+
+        return $this->query($sql, $values);
+    }
+
+    /**
+     * 批量插入
+     * 字段与数值的对应关系,请调用方处理好
+     *
+     * @param type $table
+     * @param type $field = "uid,name,sex",用逗号隔开
+     * @param type $data = 多维数组
+     */
+    public function insertBatch($table, $fields, $data = array())
+    {
+
+        //log_message::info(" 批量录入 insertBatch");
+        if (empty($fields))
+            return false;
+
+        if (!is_array($data) || count($data) < 1) {
+            return false;
+        }
+
+        $sql = " INSERT INTO {$table} ($fields) VALUES  ";
+
+        foreach ($data as $v) {
+            $sql .= "(" . implode(',', $v) . "),";
+        }
+        //log_message::info($sql);
+        return $this->query(rtrim($sql, ','), array());
+    }
+
+    /**
+     * 注入符验证
+     *
+     * @param type $sql_str 验证字符
+     */
+    private function inject_check($sql_str)
+    {
+        $injectSign = 'select|insert|update|delete|\'|\/\*|\*|';
+
+        $injectSign .= '\.\.\/|\.\/|union|into|load_file|outfile';
+
+        $check = eregi($injectSign, $sql_str);
+
+        if ($check) {
+            //exit('{"status":"false","result":"Invaild symbol"}');
+        } else {
+            return $sql_str;
+        }
+    }
+
+    /***
+     * @param $data
+     * @param null $addition
+     * @return bool|string
+     */
+    public static function formatSqlWhere($data, $addition = null)
+    {
+        if (isDatas($data)) {
+            $where = null;
+            foreach ($data as $field_key => $field_val) {
+                if (!empty($where)) {
+                    $where .= ' AND  ' . $field_key . '=:' . $field_key;
+                } else {
+                    $where .= $field_key . '=:' . $field_key;
+                }
+            }
+            log_message::info("formatSqlWhere data is ok", $where, $addition);
+            return $where . ' ' . $addition;
+        }
+        log_message::info("formatSqlWhere data is null", FAILURE);
+        return false;
+    }
+
+}
+
+?>

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 7027 - 0
lib/pinyin.php


+ 93 - 0
lib/runtime.php

@@ -0,0 +1,93 @@
+<?php
+header("Access-Control-Allow-Origin: *");
+include "define.php";
+/***
+ * @param $classname
+ */
+function anshee_autoload($classname)
+{
+    $class_file = strtolower($classname) . ".php";
+
+    require(LIBDIR . $class_file);
+    if (class_exists('log_message')) {
+        log_message::info("****function anshee_autoload::", LIBDIR . '/' . $class_file);
+    }
+    if (file_exists($class_file)) {
+        require($class_file);
+        // .mod require_once(LIBDIR_TWO.$class_file);
+    } else {
+
+    }
+}
+
+/***
+ * @param $object
+ * @return bool
+ */
+function isBlank($object)
+{
+    if (is_null($object) || '' === $object || (is_array($object) && count($object) < 1) || !isset($object)) {
+        return true;
+    }
+    return empty($object);
+}
+
+/***
+ * @param $object
+ * @param null $key
+ * @return bool
+ */
+function isDatas($object, $key = null)
+{
+    if (is_string($object) && !empty($object)) {
+        return $object;
+        log_message::info("is Data string ");
+    }
+    if (is_array($object) && !empty($object) && count($object) > ZERO && empty($key)) {
+        log_message::info("is Data array ");
+        return $object;
+    }
+    if (is_array($object) && !empty($key) && isset($object[$key]) && !empty($object[$key])) {
+        log_message::info("is Data array key ");
+        return $object[$key];
+    }
+    log_message::info("data is null", $key);
+    return false;
+}
+
+function isPrimary($object)
+{
+    return is_null($object) || is_bool($object) || is_string($object) || is_numeric($object);
+}
+
+function isSetData()
+{
+
+}
+
+function get_server_ip()
+{
+    if (!empty($_SERVER['SERVER_ADDR']))
+        return $_SERVER['SERVER_ADDR'];
+    $result = shell_exec("/sbin/ifconfig");
+    if (preg_match_all("/addr:(\d+\.\d+\.\d+\.\d+)/", $result, $match) !== 0) {
+        foreach ($match[0] as $k => $v) {
+            if ($match[1][$k] != "127.0.0.1")
+                return $match[1][$k];
+        }
+    }
+    return false;
+}
+
+function getIp()
+{
+    if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
+        $ip = getHostByName(php_uname('n'));
+        return $ip;
+    } else {
+        return get_server_ip();
+    }
+}
+
+//
+spl_autoload_register("anshee_autoload");

+ 57 - 0
lib/token.php

@@ -0,0 +1,57 @@
+<?php
+header("Content-type: text/html; charset=utf-8");
+include "config.php";
+include "mysql.lib.php";
+
+class Token
+{
+    public $wechat_error;
+    public $wechat_code;
+    public $wechat_url;
+    public $token;
+    public $openid;
+    public $access_info;
+
+    public function __construct($error_code = false)
+    {
+        $this->wechat_error = $error_code;
+        $this->GetWechatAccessToken();
+        $this->SetOpenID();
+    }
+
+    /****
+     * 获取 wechat code
+     */
+    public function GetWechatCode()
+    {
+        $url = WECHAT_SERVER . '?appid=' . WECHAT_APPID . '&redirect_uri=' . WECHAT_REDIRECT_URL . '&response_type=code&scope=' . WECHAT_SCOPE_BASE . '&state=1#wechat_redirect';
+
+        $this->wechat_code = file_get_contents($url);
+        $this->wechat_url = $url;
+        return $this->wechat_code;
+    }
+
+    public function GetWechatAccessToken()
+    {
+        $this->GetWechatCode();
+        $url = WECHAT_ACCESSTOKEN_URL . '?appid=' . WECHAT_APPID . '&secret=' . WECHAT_KEY . '&code=' . $this->wechat_code . '&grant_type=authorization_code';
+        $this->access_info = file_get_contents($url);
+        return $this->access_info;
+    }
+
+    public function SetOpenID($data)
+    {
+        $this->openid = json_decode($data, true)['openid'];
+    }
+
+
+}
+/*
+$token = new Token();
+
+$cc = $token->GetWechatCode();
+error_log("code#######" . $cc, '3', 'D:\xampp\htdocs\wechat\log\error.txt');
+
+error_log("wechat_url#######" . $token->wechat_url, '3', 'D:\xampp\htdocs\wechat\log\error.txt');
+
+var_dump($token->wechat_code);*/

+ 538 - 0
lib/utils.php

@@ -0,0 +1,538 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2018/9/26 0026
+ * Time: 下午 3:24
+ */
+class  Utils
+{
+    public $timelist;
+    public $timearray;
+    private $day = 1;
+    private $datatamp = 86400;
+    private $signvar = 1;
+
+    public function __construct()
+    {
+        unset($this->timelist);
+        unset($this->timearray);
+        $this->GetDayList();
+    }
+
+    public function GetDayList()
+    {
+        $totalDay = date("t");
+
+        //获取本月第一天时间戳
+        $start_time = strtotime(date('Y-m-01'));
+
+        $array = array();
+
+        for ($i = 0; $i < $totalDay; $i++) {
+            //每隔一天赋值给数组
+            $array[] = date('Ymd', $start_time + $i * $this->datatamp);
+        }
+        $this->timearray = $array;
+        return $array;
+    }
+
+    /***
+     * 活动 data info
+     * @param null $array
+     * @return bool
+     */
+    public function SetDay($array = null)
+    {
+        $array = (isset($array) && !empty($array)) ? $array : $this->timearray;
+
+        if (empty($array) || count($array) <= ZERO) {
+            return false;
+        }
+
+        $i = $this->day;
+
+        foreach ($array as $times) {
+
+            $data[$i] = array
+            (
+                'day' => $times,
+            );
+            $i++;
+        }
+        return ['sign' => $data];
+    }
+
+    /***
+     * 设置 sign
+     * @param string $time
+     * @return array
+     */
+    public function SetSignDay($data = array(), $time = '20180902')
+    {
+        // $data = $this->SetDay();
+
+        $dataOut = [];
+
+        foreach ($data['sign'] as $key => $var) {
+
+            if ($var['day'] == $time) {
+
+                $var['sign'] = $this->signvar;
+            }
+            $dataOut[$key] = $var;
+        }
+        return ['sign' => $dataOut];
+    }
+
+    public function SetMesage($data, $mesage, $code = ZERO)
+    {
+        $ret = ($code == ZERO) ? 'success' : 'failure';
+
+        if (isset($data) && count($data) > ZERO) {
+
+            $data['ret'] = $ret;
+            $data['msg'] = $mesage;
+            $data['login'] = true;
+        }
+        return $data;
+    }
+
+    public function GetdefaultConfig()
+    {
+        $data = $this->SetDay();
+        $data['ret'] = 'success';
+        $data['msg'] = 'default day list ';
+        $data['login'] = true;
+        return $data;
+    }
+
+    /***
+     * 礼包规则配置 获奖励规则
+     */
+    public function isGiftDay()
+    {
+
+    }
+
+    /***
+     * Json 生成规则
+     */
+    public function ActivityConfig($pc = null, $channel = null)
+    {
+        $Acitvity = [
+            'pc' => $pc,
+            'channel' => $channel
+        ];
+        // $dd = json_encode($Acitvity);
+    }
+
+    /**
+     * 是不是简单基础类型(null, boolean , string, numeric)
+     * @param $object
+     * @return bool
+     */
+    function isPrimary($object)
+    {
+        return is_null($object) || is_bool($object) || is_string($object) || is_numeric($object);
+    }
+
+    function isBlank($object)
+    {
+        if (is_null($object) || '' === $object || (is_array($object) && count($object) < 1)) {
+            return true;
+        }
+        return empty($object);
+    }
+
+    /***
+     * @param $json_config_name
+     * @return bool|mixed
+     */
+    function getFileConfig($file_name)
+    {
+        log_message::info(RES_CONFIG_URL . DIR_SEPARATOR . 'res/config/' . $file_name);
+        if ($headers = get_headers(RES_CONFIG_URL . DIR_SEPARATOR . 'res/config/' . $file_name)) {
+            if (strpos($headers[ZERO], '404') === false) {
+                $url = RES_CONFIG_URL . DIR_SEPARATOR . 'res/config/' . $file_name;
+                $pagecontent = trim(file_get_contents($url));
+
+                if (!isBlank($pagecontent)) // runtime
+                {
+                    return json_decode($pagecontent, true);
+                }
+                log_message::info('open url json data null');
+                return false;
+            }
+            log_message::info('open url json false');
+            return false;
+        }
+        log_message::info('json url false');
+        return false;
+    }
+
+    /***
+     * 区服区间验证
+     */
+    public function serverVerif($role_sid, $min_sid, $max_sid)
+    {
+        if (($role_sid >= $min_sid) && ($role_sid <= $max_sid)) {
+            return true;
+        }
+        log_message::info('user sid 区间有误');
+        return false;
+    }
+
+    /***
+     * @param $url
+     * @param $data
+     * @param string $coding
+     * @param string $refererUrl
+     * @param string $method
+     * @param string $contentType
+     * @param int $timeout
+     * @param bool $proxy
+     * @return bool|null|string
+     */
+    public static function send_request($url, $data, $coding = 'gbk', $refererUrl = '',
+                                        $method = 'POST', $contentType = 'application/json;', $timeout = 30, $proxy = false)
+    {
+        $ch = $responseData = null;
+        //$data = trim(mb_convert_encoding($data, "gbk", "utf-8"));
+        if ('POST' === strtoupper($method)) {
+            $ch = curl_init($url);
+            curl_setopt($ch, CURLOPT_POST, 1);
+            curl_setopt($ch, CURLOPT_HEADER, 0);
+            curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);
+            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+            curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
+            curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
+            $info = curl_getinfo($ch);
+            if ($refererUrl) {
+                curl_setopt($ch, CURLOPT_REFERER, $refererUrl);
+            }
+            $contentType = '';
+            if ($contentType) {
+                curl_setopt($ch, CURLOPT_HTTPHEADER, $contentType);
+            }
+            if (isset($data['upload_file'])) {
+                $file = new \CURLFile($data['upload_file']['file'],
+                    $data['upload_file']['type'], $data['upload_file']['name']);
+                $params[$data['upload_file']['get_name']] = $file;
+                curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
+
+            } else {
+                curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
+            }
+        } else if ('GET' === strtoupper($method)) {
+            if (is_string($data)) {
+                $real_url = $url . rawurlencode($data);
+            } else {
+                $real_url = $url . http_build_query($data);
+            }
+
+            //$urldata = rawurlencode($data);
+            $ch = curl_init($real_url);
+            curl_setopt($ch, CURLOPT_HEADER, 0);
+            curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type:' . $contentType]);
+            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+            curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
+            if ($refererUrl) {
+                curl_setopt($ch, CURLOPT_REFERER, $refererUrl);
+            }
+        } else {
+            $args = func_get_args();
+            return false;
+        }
+        if ($proxy) {
+            curl_setopt($ch, CURLOPT_PROXY, $proxy);
+        }
+        $ret = curl_exec($ch);
+        curl_close($ch);
+        $responseData = $ret;
+        //$responseData = mb_convert_encoding($ret, "utf-8", "gbk");
+        return $responseData;
+    }
+
+    /**
+     * @param $messige
+     * @param null $status
+     * @param null $pact
+     * @return false|string
+     */
+    public static function errorCode($messige, $status = null, $pact = null)
+    {
+        if (!isDatas($messige)) {
+            $status = isDatas($status) ? $status : FAILURE;
+        }
+        $data = array(
+            'msg' => $messige,
+            'status' => $status,
+            'pact' => $pact,
+        );
+
+        return json_encode($data, JSON_UNESCAPED_UNICODE);
+    }
+
+    /***
+     * @param $messige
+     * @param array $result_dat
+     * @param null $status
+     * @return false|string
+     */
+    public static function sendResults($messige, $result_dat = null, $status = null)
+    {
+        $status = !isDatas($status) ? $status : FAILURE;
+
+        $data = array(
+            'msg' => $messige,
+            'result' => $status,
+            'val' => null
+        );
+        $result_dat = is_string($result_dat) ? json_decode($result_dat, true) : $result_dat;
+
+        if (is_array($result_dat)) {
+            $data = array_merge($data, $result_dat);
+        }
+        return json_encode($data, JSON_UNESCAPED_UNICODE);
+        //return $data;
+    }
+
+    /***
+     * @param $tag
+     * @return bool
+     */
+    public static function config($tag = null, $var = null)
+    {
+        $url = require "config.php";
+
+        if (isset($url[$tag]) && !empty($url[$tag])) {
+
+            return !empty($var) ? $url[$tag][$var] : $url[$tag];
+        }
+        log_message::info('configs key is null ');
+        return $url;
+    }
+
+    /***
+     * @param $data
+     * @return mixed|null
+     */
+    public static function decodeDate($data)
+    {
+        if (isDatas($data)) {
+            if (is_array($data) && count($data) > ZERO) {
+                return $data;
+            }
+            return json_decode($data, true);
+        }
+        log_message::info('decode date is null');
+        return null;
+    }
+
+    /***
+     * @param $proArr
+     * @return int|string
+     */
+    public static function getPrizeRand($proArr)
+    {
+        log_message::info("&&&&&&&&&&&&++", json_encode($proArr, JSON_UNESCAPED_UNICODE));
+        $result = null;
+
+        //概率数组的总概率精度
+        $proSum = array_sum($proArr);
+        //概率数组循环
+        // 修改 key 则需要修改这里的取值范围
+
+        foreach ($proArr as $key => $proCur) {
+            $randNum = mt_rand(ONE, $proSum);
+            if ($randNum <= $proCur) {
+                $result = $key;
+                break;
+            } else {
+                $proSum -= $proCur;
+            }
+        }
+
+        unset ($proArr);
+        return $result;
+    }
+
+    public static function prizeAssembly($proArr)
+    {
+        $data = [];
+        if (isDatas($proArr)) {
+            foreach ($proArr as $key => $proCur) {
+                $data[$proCur['prize_id']] = json_encode($proCur, JSON_UNESCAPED_UNICODE);
+            }
+            return $data;
+        }
+        return false;
+    }
+
+    /***
+     * 干预判断 如果 不是无限制的类型并且 game 上限大于或等于用户已抽取的次数
+     * 表示已经达到上限符合干预条件需要系统重新随机奖品
+     * @param $role_upper_limit
+     * @param $game_upper_limit
+     * @return bool
+     */
+    public static function isUpperlimit($role_upper_limit, $game_upper_limit)
+    {
+        if (($game_upper_limit != ZERO && $game_upper_limit >= $role_upper_limit)) {
+            return true;
+        }
+        return false;
+    }
+
+    /****
+     * 判断有效范围内可增加抽取次数并返回客户端
+     * @param $role_upper_limit
+     * @param $game_upper_limit
+     * @return bool
+     */
+    public static function isNayUpperLimit($role_upper_limit, $game_upper_limit)
+    {
+        if (($game_upper_limit != ZERO && $role_upper_limit > $game_upper_limit) || $game_upper_limit == ZERO) {
+            return true;
+        }
+        return false;
+    }
+
+    /***
+     * @param $data_at
+     * @return array
+     */
+    public static function successiveTime($data_at)
+    {
+        sort($data_at);
+        $data = [];
+        for ($i = 1; $i < count($data_at); $i++) {
+            $lastone = strtotime($data_at[$i - 1]);
+            $thisone = strtotime($data_at[$i]);
+            if ($thisone - $lastone != 3600 * 24) {
+                $data = [];
+            } else {
+                $data[] = date('Y-m-d', $thisone);
+            }
+        }
+        return $data;
+    }
+
+    // 二维数组按指定的键值排序 $reque_data_out, "power", "desc", HUNDRED
+    public static function array_sort($array, $keys, $type = 'asc', $limit = null, $dimen = TWO)
+    {
+        if (!is_array($array) || empty($array) || !in_array(strtolower($type), array('asc', 'desc'))) return '';
+        $keysvalue = array();
+
+        foreach ($array as $key => $val) {
+            $val[$keys] = str_replace('-', '', $val[$keys]);
+            $val[$keys] = str_replace(' ', '', $val[$keys]);
+            $val[$keys] = str_replace(':', '', $val[$keys]);
+            $keysvalue[] = $val[$keys];
+        }
+
+        asort($keysvalue);//key值排序
+        reset($keysvalue);//指针重新指向数组第一个
+        foreach ($keysvalue as $key => $vals) {
+            $keysort[] = $key;
+        }
+        $keysvalue = array();
+        $count = count($keysort);
+        if (strtolower($type) != 'asc') {
+            for ($i = $count - 1; $i >= 0; $i--) {
+                $keysvalue[] = $array[$keysort[$i]];
+            }
+        } else {
+            for ($i = 0; $i < $count; $i++) {
+                $keysvalue[] = $array[$keysort[$i]];
+            }
+        }
+        if (!empty($limit)) {
+            array_slice($keysvalue, ZERO, $limit);
+        }
+        return $keysvalue;
+    }
+
+    /***
+     * @param $filepatch
+     * @param $filename
+     * @param $string
+     * @return bool
+     */
+    public static function mkdirFile($filepatch, $filename, $string)
+    {
+        if (is_array($string)) {
+            $string = json_encode($string, JSON_UNESCAPED_UNICODE);
+        }
+        if (file_exists($filepatch)) {
+
+            $myfile = fopen($filepatch . $filename, "w");
+            fwrite($myfile, $string);
+            return true;
+        }
+        log_message::info('mkdir file false...');
+        return false;
+    }
+
+    /***
+     * @param array $data
+     * @return bool|null
+     */
+    public static function prizeFormat($data = [])
+    {
+        $cache_data = null;
+
+        sort($data);
+        foreach ($data as $val) {
+            $cache_data[$val['prize_id']] = $val;
+        }
+        if (isDatas($cache_data)) {
+            return $cache_data;
+        }
+        return false;
+    }
+
+    /**
+     * 组发消息
+     */
+    public static function senFormatData($pact = ZERO, $data = array())
+    {
+        $package = array(
+            'pact' => $pact,
+            'data' => $data
+        );
+        $string = json_encode($package, JSON_UNESCAPED_UNICODE);
+        log_message::info($string);
+        return $string;
+    }
+
+    /***
+     *
+     */
+    public static function encodeData($string, $fd)
+    {
+
+
+    }
+
+    /***
+     * 数组维度判断
+     */
+    public statiC function arrayDimension($array)
+    {
+        if (isDatas($array)) {
+            log_message::info('arrayDimension is days ');
+            if (count($array) == count($array, ONE)) {
+                log_message::info('arrayDimension is daysq1 ');
+                return ONE;
+            } else {
+                log_message::info('arrayDimension is daysq 2 ');
+                return TWO;
+            }
+        }
+        log_message::info('arrayDimension is daysq 000 ');
+        return ZERO;
+    }
+}

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1014 - 0
lib/xredis.php


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 503 - 0
log/2019-08-04_mysqldb.txt


+ 56 - 0
log/2019-08-04_runtime.txt

@@ -0,0 +1,56 @@
+2019-08-04 15:48:47[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//log_message.php 
+2019-08-04 15:48:47[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//mysqldb.php 
+2019-08-04 15:51:15[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//log_message.php 
+2019-08-04 15:51:15[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//mysqldb.php 
+2019-08-04 15:52:43[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//log_message.php 
+2019-08-04 15:52:43[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//mysqldb.php 
+2019-08-04 16:09:42[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//log_message.php 
+2019-08-04 16:09:42[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//mysqldb.php 
+2019-08-04 16:15:23[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//log_message.php 
+2019-08-04 16:15:23[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//mysqldb.php 
+2019-08-04 16:15:48[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//log_message.php 
+2019-08-04 16:15:48[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//mysqldb.php 
+2019-08-04 16:22:12[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//log_message.php 
+2019-08-04 16:22:12[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//mysqldb.php 
+2019-08-04 16:22:19[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//log_message.php 
+2019-08-04 16:22:19[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//mysqldb.php 
+2019-08-04 16:22:21[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//log_message.php 
+2019-08-04 16:22:21[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//mysqldb.php 
+2019-08-04 16:22:23[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//log_message.php 
+2019-08-04 16:22:23[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//mysqldb.php 
+2019-08-04 16:22:37[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//log_message.php 
+2019-08-04 16:22:37[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//mysqldb.php 
+2019-08-04 16:23:30[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//log_message.php 
+2019-08-04 16:23:30[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//mysqldb.php 
+2019-08-04 16:23:31[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//log_message.php 
+2019-08-04 16:23:31[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//mysqldb.php 
+2019-08-04 16:23:32[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//log_message.php 
+2019-08-04 16:23:32[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//mysqldb.php 
+2019-08-04 16:23:33[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//log_message.php 
+2019-08-04 16:23:33[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//mysqldb.php 
+2019-08-04 16:23:53[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//log_message.php 
+2019-08-04 16:23:53[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//mysqldb.php 
+2019-08-04 16:23:54[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//log_message.php 
+2019-08-04 16:23:54[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//mysqldb.php 
+2019-08-04 16:23:55[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//log_message.php 
+2019-08-04 16:23:55[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//mysqldb.php 
+2019-08-04 16:23:55[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//log_message.php 
+2019-08-04 16:23:55[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//mysqldb.php 
+2019-08-04 16:24:38[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//log_message.php 
+2019-08-04 16:24:38[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//mysqldb.php 
+2019-08-04 16:31:13[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//log_message.php 
+2019-08-04 16:31:13[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//mysqldb.php 
+2019-08-04 16:32:23[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//log_message.php 
+2019-08-04 16:32:23[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]****function anshee_autoload:: D:\xampp\htdocs\chatroom\lib//mysqldb.php 
+2019-08-04 16:34:33[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]
+2019-08-04 16:34:33[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]
+2019-08-04 16:41:46[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]
+2019-08-04 16:41:46[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]
+2019-08-04 16:44:33[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]
+2019-08-04 16:44:33[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]
+2019-08-04 16:45:17[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]
+2019-08-04 16:45:17[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]
+2019-08-04 16:49:49[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]
+2019-08-04 16:49:49[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]
+2019-08-04 17:49:04[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]
+2019-08-04 17:49:04[D:\xampp\htdocs\chatroom\lib\runtime.php: line: 13 funtion: anshee_autoload]

+ 70 - 0
login.php

@@ -0,0 +1,70 @@
+<script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script>
+<script>
+    $(function () {
+        // 注册
+        $("#login").click(function () {
+            var form = $("#chatfrom").serializeArray();
+            form.push({"name": "type", "value": "1"});
+            $.ajax({
+                type: 'POST',
+                url: "chat.php",
+                data: form,
+                dataType: 'json',
+                success: function (result) {
+                    var data = result;
+                    alert(123);
+                    alert(result.msg);
+                    if (result.errcode == 0) {
+                        window.location.href = window.location.href;
+                    }
+                },
+                error: function(jqXHR, textStatus, errorThrown) {
+
+                    /*弹出jqXHR对象的信息*/
+                    alert(jqXHR.responseText);
+                    alert(jqXHR.status);
+                    alert(jqXHR.readyState);
+                    alert(jqXHR.statusText);
+                    /*弹出其他两个参数的信息*/
+                    alert(textStatus);
+                    alert(errorThrown);
+                },
+                beforeSend: function () {
+                    //$("#alertActivityBtn").addClass("disabled");
+                }
+            });
+        });
+         /*// login
+         $("#login").click(function () {
+             var form = $("#chatfrom").serializeArray();
+              form.push({"name": "type", "value": "2"});
+             $.ajax({
+                 type: 'POST',
+                 url: "user.php",
+                 data: form,
+                 dataType: 'json',
+                 success: function (result) {
+                     alert(result.msg);
+                     if (result.errcode == 0) {
+                         window.location.href = window.location.href;
+                     }
+                 },
+                 beforeSend: function () {
+                     //$("#alertActivityBtn").addClass("disabled");
+                 }
+             });
+         });*/
+    });
+</script>
+
+<div style="margin:0 auto;border:1px solid #000;width:300px;height:100px;margin-top: 300px">
+    <form action="chat.php" method="post" id="chatfrom">
+        <p>
+            <input type="text" name="account"/>
+        </p>
+        <input type="password" name="paw"/>
+        <!--<input type="submit"  data-type=1 id="redc" value="注册"/>-->
+        <input type="submit" name="login2" data-type=2 id="login2" value="登录"/>
+    </form>
+</div>
+

+ 418 - 0
res/css/bootstrap-datetimepicker.css

@@ -0,0 +1,418 @@
+/*!
+ * Datetimepicker for Bootstrap
+ *
+ * Copyright 2012 Stefan Petre
+ * Improvements by Andrew Rowls
+ * Licensed under the Apache License v2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ */
+.datetimepicker {
+	padding: 4px;
+	margin-top: 1px;
+	-webkit-border-radius: 4px;
+	-moz-border-radius: 4px;
+	border-radius: 4px;
+	direction: ltr;
+}
+
+.datetimepicker-inline {
+	width: 220px;
+}
+
+.datetimepicker.datetimepicker-rtl {
+	direction: rtl;
+}
+
+.datetimepicker.datetimepicker-rtl table tr td span {
+	float: right;
+}
+
+.datetimepicker-dropdown, .datetimepicker-dropdown-left {
+	top: 0;
+	left: 0;
+}
+
+[class*=" datetimepicker-dropdown"]:before {
+	content: '';
+	display: inline-block;
+	border-left: 7px solid transparent;
+	border-right: 7px solid transparent;
+	border-bottom: 7px solid #cccccc;
+	border-bottom-color: rgba(0, 0, 0, 0.2);
+	position: absolute;
+}
+
+[class*=" datetimepicker-dropdown"]:after {
+	content: '';
+	display: inline-block;
+	border-left: 6px solid transparent;
+	border-right: 6px solid transparent;
+	border-bottom: 6px solid #ffffff;
+	position: absolute;
+}
+
+[class*=" datetimepicker-dropdown-top"]:before {
+	content: '';
+	display: inline-block;
+	border-left: 7px solid transparent;
+	border-right: 7px solid transparent;
+	border-top: 7px solid #cccccc;
+	border-top-color: rgba(0, 0, 0, 0.2);
+	border-bottom: 0;
+}
+
+[class*=" datetimepicker-dropdown-top"]:after {
+	content: '';
+	display: inline-block;
+	border-left: 6px solid transparent;
+	border-right: 6px solid transparent;
+	border-top: 6px solid #ffffff;
+	border-bottom: 0;
+}
+
+.datetimepicker-dropdown-bottom-left:before {
+	top: -7px;
+	right: 6px;
+}
+
+.datetimepicker-dropdown-bottom-left:after {
+	top: -6px;
+	right: 7px;
+}
+
+.datetimepicker-dropdown-bottom-right:before {
+	top: -7px;
+	left: 6px;
+}
+
+.datetimepicker-dropdown-bottom-right:after {
+	top: -6px;
+	left: 7px;
+}
+
+.datetimepicker-dropdown-top-left:before {
+	bottom: -7px;
+	right: 6px;
+}
+
+.datetimepicker-dropdown-top-left:after {
+	bottom: -6px;
+	right: 7px;
+}
+
+.datetimepicker-dropdown-top-right:before {
+	bottom: -7px;
+	left: 6px;
+}
+
+.datetimepicker-dropdown-top-right:after {
+	bottom: -6px;
+	left: 7px;
+}
+
+.datetimepicker > div {
+	display: none;
+}
+
+.datetimepicker.minutes div.datetimepicker-minutes {
+	display: block;
+}
+
+.datetimepicker.hours div.datetimepicker-hours {
+	display: block;
+}
+
+.datetimepicker.days div.datetimepicker-days {
+	display: block;
+}
+
+.datetimepicker.months div.datetimepicker-months {
+	display: block;
+}
+
+.datetimepicker.years div.datetimepicker-years {
+	display: block;
+}
+
+.datetimepicker table {
+	margin: 0;
+}
+
+.datetimepicker  td,
+.datetimepicker th {
+	text-align: center;
+	width: 20px;
+	height: 20px;
+	-webkit-border-radius: 4px;
+	-moz-border-radius: 4px;
+	border-radius: 4px;
+	border: none;
+}
+
+.table-striped .datetimepicker table tr td,
+.table-striped .datetimepicker table tr th {
+	background-color: transparent;
+}
+
+.datetimepicker table tr td.minute:hover {
+	background: #eeeeee;
+	cursor: pointer;
+}
+
+.datetimepicker table tr td.hour:hover {
+	background: #eeeeee;
+	cursor: pointer;
+}
+
+.datetimepicker table tr td.day:hover {
+	background: #eeeeee;
+	cursor: pointer;
+}
+
+.datetimepicker table tr td.old,
+.datetimepicker table tr td.new {
+	color: #999999;
+}
+
+.datetimepicker table tr td.disabled,
+.datetimepicker table tr td.disabled:hover {
+	background: none;
+	color: #999999;
+	cursor: default;
+}
+
+.datetimepicker table tr td.today,
+.datetimepicker table tr td.today:hover,
+.datetimepicker table tr td.today.disabled,
+.datetimepicker table tr td.today.disabled:hover {
+	background-color: #fde19a;
+	background-image: -moz-linear-gradient(top, #fdd49a, #fdf59a);
+	background-image: -ms-linear-gradient(top, #fdd49a, #fdf59a);
+	background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));
+	background-image: -webkit-linear-gradient(top, #fdd49a, #fdf59a);
+	background-image: -o-linear-gradient(top, #fdd49a, #fdf59a);
+	background-image: linear-gradient(top, #fdd49a, #fdf59a);
+	background-repeat: repeat-x;
+	filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);
+	border-color: #fdf59a #fdf59a #fbed50;
+	border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+	filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+}
+
+.datetimepicker table tr td.today:hover,
+.datetimepicker table tr td.today:hover:hover,
+.datetimepicker table tr td.today.disabled:hover,
+.datetimepicker table tr td.today.disabled:hover:hover,
+.datetimepicker table tr td.today:active,
+.datetimepicker table tr td.today:hover:active,
+.datetimepicker table tr td.today.disabled:active,
+.datetimepicker table tr td.today.disabled:hover:active,
+.datetimepicker table tr td.today.active,
+.datetimepicker table tr td.today:hover.active,
+.datetimepicker table tr td.today.disabled.active,
+.datetimepicker table tr td.today.disabled:hover.active,
+.datetimepicker table tr td.today.disabled,
+.datetimepicker table tr td.today:hover.disabled,
+.datetimepicker table tr td.today.disabled.disabled,
+.datetimepicker table tr td.today.disabled:hover.disabled,
+.datetimepicker table tr td.today[disabled],
+.datetimepicker table tr td.today:hover[disabled],
+.datetimepicker table tr td.today.disabled[disabled],
+.datetimepicker table tr td.today.disabled:hover[disabled] {
+	background-color: #fdf59a;
+}
+
+.datetimepicker table tr td.today:active,
+.datetimepicker table tr td.today:hover:active,
+.datetimepicker table tr td.today.disabled:active,
+.datetimepicker table tr td.today.disabled:hover:active,
+.datetimepicker table tr td.today.active,
+.datetimepicker table tr td.today:hover.active,
+.datetimepicker table tr td.today.disabled.active,
+.datetimepicker table tr td.today.disabled:hover.active {
+	background-color: #fbf069;
+}
+
+.datetimepicker table tr td.active,
+.datetimepicker table tr td.active:hover,
+.datetimepicker table tr td.active.disabled,
+.datetimepicker table tr td.active.disabled:hover {
+	background-color: #006dcc;
+	background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
+	background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
+	background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
+	background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
+	background-image: -o-linear-gradient(top, #0088cc, #0044cc);
+	background-image: linear-gradient(top, #0088cc, #0044cc);
+	background-repeat: repeat-x;
+	filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
+	border-color: #0044cc #0044cc #002a80;
+	border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+	filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+	color: #ffffff;
+	text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+}
+
+.datetimepicker table tr td.active:hover,
+.datetimepicker table tr td.active:hover:hover,
+.datetimepicker table tr td.active.disabled:hover,
+.datetimepicker table tr td.active.disabled:hover:hover,
+.datetimepicker table tr td.active:active,
+.datetimepicker table tr td.active:hover:active,
+.datetimepicker table tr td.active.disabled:active,
+.datetimepicker table tr td.active.disabled:hover:active,
+.datetimepicker table tr td.active.active,
+.datetimepicker table tr td.active:hover.active,
+.datetimepicker table tr td.active.disabled.active,
+.datetimepicker table tr td.active.disabled:hover.active,
+.datetimepicker table tr td.active.disabled,
+.datetimepicker table tr td.active:hover.disabled,
+.datetimepicker table tr td.active.disabled.disabled,
+.datetimepicker table tr td.active.disabled:hover.disabled,
+.datetimepicker table tr td.active[disabled],
+.datetimepicker table tr td.active:hover[disabled],
+.datetimepicker table tr td.active.disabled[disabled],
+.datetimepicker table tr td.active.disabled:hover[disabled] {
+	background-color: #0044cc;
+}
+
+.datetimepicker table tr td.active:active,
+.datetimepicker table tr td.active:hover:active,
+.datetimepicker table tr td.active.disabled:active,
+.datetimepicker table tr td.active.disabled:hover:active,
+.datetimepicker table tr td.active.active,
+.datetimepicker table tr td.active:hover.active,
+.datetimepicker table tr td.active.disabled.active,
+.datetimepicker table tr td.active.disabled:hover.active {
+	background-color: #003399;
+}
+
+.datetimepicker table tr td span {
+	display: block;
+	width: 23%;
+	height: 54px;
+	line-height: 54px;
+	float: left;
+	margin: 1%;
+	cursor: pointer;
+	-webkit-border-radius: 4px;
+	-moz-border-radius: 4px;
+	border-radius: 4px;
+}
+
+.datetimepicker .datetimepicker-hours span {
+	height: 26px;
+	line-height: 26px;
+}
+
+.datetimepicker .datetimepicker-hours table tr td span.hour_am,
+.datetimepicker .datetimepicker-hours table tr td span.hour_pm {
+	width: 14.6%;
+}
+
+.datetimepicker .datetimepicker-hours fieldset legend,
+.datetimepicker .datetimepicker-minutes fieldset legend {
+	margin-bottom: inherit;
+	line-height: 30px;
+}
+
+.datetimepicker .datetimepicker-minutes span {
+	height: 26px;
+	line-height: 26px;
+}
+
+.datetimepicker table tr td span:hover {
+	background: #eeeeee;
+}
+
+.datetimepicker table tr td span.disabled,
+.datetimepicker table tr td span.disabled:hover {
+	background: none;
+	color: #999999;
+	cursor: default;
+}
+
+.datetimepicker table tr td span.active,
+.datetimepicker table tr td span.active:hover,
+.datetimepicker table tr td span.active.disabled,
+.datetimepicker table tr td span.active.disabled:hover {
+	background-color: #006dcc;
+	background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
+	background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
+	background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
+	background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
+	background-image: -o-linear-gradient(top, #0088cc, #0044cc);
+	background-image: linear-gradient(top, #0088cc, #0044cc);
+	background-repeat: repeat-x;
+	filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
+	border-color: #0044cc #0044cc #002a80;
+	border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+	filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+	color: #ffffff;
+	text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+}
+
+.datetimepicker table tr td span.active:hover,
+.datetimepicker table tr td span.active:hover:hover,
+.datetimepicker table tr td span.active.disabled:hover,
+.datetimepicker table tr td span.active.disabled:hover:hover,
+.datetimepicker table tr td span.active:active,
+.datetimepicker table tr td span.active:hover:active,
+.datetimepicker table tr td span.active.disabled:active,
+.datetimepicker table tr td span.active.disabled:hover:active,
+.datetimepicker table tr td span.active.active,
+.datetimepicker table tr td span.active:hover.active,
+.datetimepicker table tr td span.active.disabled.active,
+.datetimepicker table tr td span.active.disabled:hover.active,
+.datetimepicker table tr td span.active.disabled,
+.datetimepicker table tr td span.active:hover.disabled,
+.datetimepicker table tr td span.active.disabled.disabled,
+.datetimepicker table tr td span.active.disabled:hover.disabled,
+.datetimepicker table tr td span.active[disabled],
+.datetimepicker table tr td span.active:hover[disabled],
+.datetimepicker table tr td span.active.disabled[disabled],
+.datetimepicker table tr td span.active.disabled:hover[disabled] {
+	background-color: #0044cc;
+}
+
+.datetimepicker table tr td span.active:active,
+.datetimepicker table tr td span.active:hover:active,
+.datetimepicker table tr td span.active.disabled:active,
+.datetimepicker table tr td span.active.disabled:hover:active,
+.datetimepicker table tr td span.active.active,
+.datetimepicker table tr td span.active:hover.active,
+.datetimepicker table tr td span.active.disabled.active,
+.datetimepicker table tr td span.active.disabled:hover.active {
+	background-color: #003399;
+}
+
+.datetimepicker table tr td span.old {
+	color: #999999;
+}
+
+.datetimepicker th.switch {
+	width: 145px;
+}
+
+.datetimepicker th span.glyphicon {
+	pointer-events: none;
+}
+
+.datetimepicker thead tr:first-child th,
+.datetimepicker tfoot tr:first-child th {
+	cursor: pointer;
+}
+
+.datetimepicker thead tr:first-child th:hover,
+.datetimepicker tfoot tr:first-child th:hover {
+	background: #eeeeee;
+}
+
+.input-append.date .add-on i,
+.input-prepend.date .add-on i,
+.input-group.date .input-group-addon span {
+	cursor: pointer;
+	width: 14px;
+	height: 14px;
+}

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 9 - 0
res/css/bootstrap-responsive.min.css


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 6 - 0
res/css/bootstrap-select.min.css


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 5447 - 0
res/css/bootstrap.css


+ 136 - 0
res/js/bootstrap-collapse.js

@@ -0,0 +1,136 @@
+/* =============================================================
+ * bootstrap-collapse.js v2.0.1
+ * http://twitter.github.com/bootstrap/javascript.html#collapse
+ * =============================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============================================================ */
+
+!function( $ ){
+
+  "use strict"
+
+  var Collapse = function ( element, options ) {
+  	this.$element = $(element)
+    this.options = $.extend({}, $.fn.collapse.defaults, options)
+
+    if (this.options["parent"]) {
+      this.$parent = $(this.options["parent"])
+    }
+
+    this.options.toggle && this.toggle()
+  }
+
+  Collapse.prototype = {
+
+    constructor: Collapse
+
+  , dimension: function () {
+      var hasWidth = this.$element.hasClass('width')
+      return hasWidth ? 'width' : 'height'
+    }
+
+  , show: function () {
+      var dimension = this.dimension()
+        , scroll = $.camelCase(['scroll', dimension].join('-'))
+        , actives = this.$parent && this.$parent.find('.in')
+        , hasData
+
+      if (actives && actives.length) {
+        hasData = actives.data('collapse')
+        actives.collapse('hide')
+        hasData || actives.data('collapse', null)
+      }
+
+      this.$element[dimension](0)
+      this.transition('addClass', 'show', 'shown')
+      this.$element[dimension](this.$element[0][scroll])
+
+    }
+
+  , hide: function () {
+      var dimension = this.dimension()
+      this.reset(this.$element[dimension]())
+      this.transition('removeClass', 'hide', 'hidden')
+      this.$element[dimension](0)
+    }
+
+  , reset: function ( size ) {
+      var dimension = this.dimension()
+
+      this.$element
+        .removeClass('collapse')
+        [dimension](size || 'auto')
+        [0].offsetWidth
+
+      this.$element.addClass('collapse')
+    }
+
+  , transition: function ( method, startEvent, completeEvent ) {
+      var that = this
+        , complete = function () {
+            if (startEvent == 'show') that.reset()
+            that.$element.trigger(completeEvent)
+          }
+
+      this.$element
+        .trigger(startEvent)
+        [method]('in')
+
+      $.support.transition && this.$element.hasClass('collapse') ?
+        this.$element.one($.support.transition.end, complete) :
+        complete()
+  	}
+
+  , toggle: function () {
+      this[this.$element.hasClass('in') ? 'hide' : 'show']()
+  	}
+
+  }
+
+  /* COLLAPSIBLE PLUGIN DEFINITION
+  * ============================== */
+
+  $.fn.collapse = function ( option ) {
+    return this.each(function () {
+      var $this = $(this)
+        , data = $this.data('collapse')
+        , options = typeof option == 'object' && option
+      if (!data) $this.data('collapse', (data = new Collapse(this, options)))
+      if (typeof option == 'string') data[option]()
+    })
+  }
+
+  $.fn.collapse.defaults = {
+    toggle: true
+  }
+
+  $.fn.collapse.Constructor = Collapse
+
+
+ /* COLLAPSIBLE DATA-API
+  * ==================== */
+
+  $(function () {
+    $('body').on('click.collapse.data-api', '[data-toggle=collapse]', function ( e ) {
+      var $this = $(this), href
+        , target = $this.attr('data-target')
+          || e.preventDefault()
+          || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
+        , option = $(target).data('collapse') ? 'toggle' : $this.data()
+      $(target).collapse(option)
+    })
+  })
+
+}( window.jQuery );

+ 540 - 0
res/js/bootstrap-colorpicker.js

@@ -0,0 +1,540 @@
+/* =========================================================
+ * bootstrap-colorpicker.js 
+ * http://www.eyecon.ro/bootstrap-colorpicker
+ * =========================================================
+ * Copyright 2012 Stefan Petre
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================= */
+ 
+!function( $ ) {
+	
+	// Color object
+	
+	var Color = function(val) {
+		this.value = {
+			h: 1,
+			s: 1,
+			b: 1,
+			a: 1
+		};
+		this.setColor(val);
+	};
+	
+	Color.prototype = {
+		constructor: Color,
+		
+		//parse a string to HSB
+		setColor: function(val){
+			val = val.toLowerCase();
+			var that = this;
+			$.each( CPGlobal.stringParsers, function( i, parser ) {
+				var match = parser.re.exec( val ),
+					values = match && parser.parse( match ),
+					space = parser.space||'rgba';
+				if ( values ) {
+					if (space === 'hsla') {
+						that.value = CPGlobal.RGBtoHSB.apply(null, CPGlobal.HSLtoRGB.apply(null, values));
+					} else {
+						that.value = CPGlobal.RGBtoHSB.apply(null, values);
+					}
+					return false;
+				}
+			});
+		},
+		
+		setHue: function(h) {
+			this.value.h = 1- h;
+		},
+		
+		setSaturation: function(s) {
+			this.value.s = s;
+		},
+		
+		setLightness: function(b) {
+			this.value.b = 1- b;
+		},
+		
+		setAlpha: function(a) {
+			this.value.a = parseInt((1 - a)*100, 10)/100;
+		},
+		
+		// HSBtoRGB from RaphaelJS
+		// https://github.com/DmitryBaranovskiy/raphael/
+		toRGB: function(h, s, b, a) {
+			if (!h) {
+				h = this.value.h;
+				s = this.value.s;
+				b = this.value.b;
+			}
+			h *= 360;
+			var R, G, B, X, C;
+			h = (h % 360) / 60;
+			C = b * s;
+			X = C * (1 - Math.abs(h % 2 - 1));
+			R = G = B = b - C;
+
+			h = ~~h;
+			R += [C, X, 0, 0, X, C][h];
+			G += [X, C, C, X, 0, 0][h];
+			B += [0, 0, X, C, C, X][h];
+			return {
+				r: Math.round(R*255),
+				g: Math.round(G*255),
+				b: Math.round(B*255),
+				a: a||this.value.a
+			};
+		},
+		
+		toHex: function(h, s, b, a){
+			var rgb = this.toRGB(h, s, b, a);
+			return '#'+((1 << 24) | (parseInt(rgb.r) << 16) | (parseInt(rgb.g) << 8) | parseInt(rgb.b)).toString(16).substr(1);
+		},
+		
+		toHSL: function(h, s, b, a){
+			if (!h) {
+				h = this.value.h;
+				s = this.value.s;
+				b = this.value.b;
+			}
+			var H = h,
+				L = (2 - s) * b,
+				S = s * b;
+			if (L > 0 && L <= 1) {
+				S /= L;
+			} else {
+				S /= 2 - L;
+			}
+			L /= 2;
+			if (S > 1) {
+				S = 1;
+			}
+			return {
+				h: H,
+				s: S,
+				l: L,
+				a: a||this.value.a
+			};
+		}
+	};
+	
+	// Picker object
+	
+	var Colorpicker = function(element, options){
+		this.element = $(element);
+		var format = options.format||this.element.data('color-format')||'hex';
+		this.format = CPGlobal.translateFormats[format];
+		this.isInput = this.element.is('input');
+		this.component = this.element.is('.color') ? this.element.find('.add-on') : false;
+		
+		this.picker = $(CPGlobal.template)
+							.appendTo('body')
+							.on('mousedown', $.proxy(this.mousedown, this));
+		
+		if (this.isInput) {
+			this.element.on({
+				'focus': $.proxy(this.show, this),
+				'keyup': $.proxy(this.update, this)
+			});
+		} else if (this.component){
+			this.component.on({
+				'click': $.proxy(this.show, this)
+			});
+		} else {
+			this.element.on({
+				'click': $.proxy(this.show, this)
+			});
+		}
+		if (format === 'rgba' || format === 'hsla') {
+			this.picker.addClass('alpha');
+			this.alpha = this.picker.find('.colorpicker-alpha')[0].style;
+		}
+		
+		if (this.component){
+			this.picker.find('.colorpicker-color').hide();
+			this.preview = this.element.find('i')[0].style;
+		} else {
+			this.preview = this.picker.find('div:last')[0].style;
+		}
+		
+		this.base = this.picker.find('div:first')[0].style;
+		this.update();
+	};
+	
+	Colorpicker.prototype = {
+		constructor: Colorpicker,
+		
+		show: function(e) {
+			this.picker.show();
+			this.height = this.component ? this.component.outerHeight() : this.element.outerHeight();
+			this.place();
+			$(window).on('resize', $.proxy(this.place, this));
+			if (!this.isInput) {
+				if (e) {
+					e.stopPropagation();
+					e.preventDefault();
+				}
+			}
+			$(document).on({
+				'mousedown': $.proxy(this.hide, this)
+			});
+			this.element.trigger({
+				type: 'show',
+				color: this.color
+			});
+		},
+		
+		update: function(){
+			this.color = new Color(this.isInput ? this.element.prop('value') : this.element.data('color'));
+			this.picker.find('i')
+				.eq(0).css({left: this.color.value.s*100, top: 100 - this.color.value.b*100}).end()
+				.eq(1).css('top', 100 * (1 - this.color.value.h)).end()
+				.eq(2).css('top', 100 * (1 - this.color.value.a));
+			this.previewColor();
+		},
+		
+		setValue: function(newColor) {
+			this.color = new Color(newColor);
+			this.picker.find('i')
+				.eq(0).css({left: this.color.value.s*100, top: 100 - this.color.value.b*100}).end()
+				.eq(1).css('top', 100 * (1 - this.color.value.h)).end()
+				.eq(2).css('top', 100 * (1 - this.color.value.a));
+			this.previewColor();
+			this.element.trigger({
+				type: 'changeColor',
+				color: this.color
+			});
+		},
+		
+		hide: function(){
+			this.picker.hide();
+			$(window).off('resize', this.place);
+			if (!this.isInput) {
+				$(document).off({
+					'mousedown': this.hide
+				});
+				if (this.component){
+					this.element.find('input').prop('value', this.format.call(this));
+				}
+				this.element.data('color', this.format.call(this));
+			} else {
+				this.element.prop('value', this.format.call(this));
+			}
+			this.element.trigger({
+				type: 'hide',
+				color: this.color
+			});
+		},
+		
+		place: function(){
+			var offset = this.component ? this.component.offset() : this.element.offset();
+			this.picker.css({
+				top: offset.top + this.height,
+				left: offset.left
+			});
+		},
+		
+		//preview color change
+		previewColor: function(){
+			try {
+				this.preview.backgroundColor = this.format.call(this);
+			} catch(e) {
+				this.preview.backgroundColor = this.color.toHex();
+			}
+			//set the color for brightness/saturation slider
+			this.base.backgroundColor = this.color.toHex(this.color.value.h, 1, 1, 1);
+			//set te color for alpha slider
+			if (this.alpha) {
+				this.alpha.backgroundColor = this.color.toHex();
+			}
+		},
+		
+		pointer: null,
+		
+		slider: null,
+		
+		mousedown: function(e){
+			e.stopPropagation();
+			e.preventDefault();
+			
+			var target = $(e.target);
+			
+			//detect the slider and set the limits and callbacks
+			var zone = target.closest('div');
+			if (!zone.is('.colorpicker')) {
+				if (zone.is('.colorpicker-saturation')) {
+					this.slider = $.extend({}, CPGlobal.sliders.saturation);
+				} 
+				else if (zone.is('.colorpicker-hue')) {
+					this.slider = $.extend({}, CPGlobal.sliders.hue);
+				}
+				else if (zone.is('.colorpicker-alpha')) {
+					this.slider = $.extend({}, CPGlobal.sliders.alpha);
+				} else {
+					return false;
+				}
+				var offset = zone.offset();
+				//reference to knob's style
+				this.slider.knob = zone.find('i')[0].style;
+				this.slider.left = e.pageX - offset.left;
+				this.slider.top = e.pageY - offset.top;
+				this.pointer = {
+					left: e.pageX,
+					top: e.pageY
+				};
+				//trigger mousemove to move the knob to the current position
+				$(document).on({
+					mousemove: $.proxy(this.mousemove, this),
+					mouseup: $.proxy(this.mouseup, this)
+				}).trigger('mousemove');
+			}
+			return false;
+		},
+		
+		mousemove: function(e){
+			e.stopPropagation();
+			e.preventDefault();
+			var left = Math.max(
+				0,
+				Math.min(
+					this.slider.maxLeft,
+					this.slider.left + ((e.pageX||this.pointer.left) - this.pointer.left)
+				)
+			);
+			var top = Math.max(
+				0,
+				Math.min(
+					this.slider.maxTop,
+					this.slider.top + ((e.pageY||this.pointer.top) - this.pointer.top)
+				)
+			);
+			this.slider.knob.left = left + 'px';
+			this.slider.knob.top = top + 'px';
+			if (this.slider.callLeft) {
+				this.color[this.slider.callLeft].call(this.color, left/100);
+			}
+			if (this.slider.callTop) {
+				this.color[this.slider.callTop].call(this.color, top/100);
+			}
+			this.previewColor();
+			this.element.trigger({
+				type: 'changeColor',
+				color: this.color
+			});
+			return false;
+		},
+		
+		mouseup: function(e){
+			e.stopPropagation();
+			e.preventDefault();
+			$(document).off({
+				mousemove: this.mousemove,
+				mouseup: this.mouseup
+			});
+			return false;
+		}
+	}
+
+	$.fn.colorpicker = function ( option ) {
+		return this.each(function () {
+			var $this = $(this),
+				data = $this.data('colorpicker'),
+				options = typeof option === 'object' && option;
+			if (!data) {
+				$this.data('colorpicker', (data = new Colorpicker(this, $.extend({}, $.fn.colorpicker.defaults,options))));
+			}
+			if (typeof option === 'string') data[option]();
+		});
+	};
+
+	$.fn.colorpicker.defaults = {
+	};
+	
+	$.fn.colorpicker.Constructor = Colorpicker;
+	
+	var CPGlobal = {
+	
+		// translate a format from Color object to a string
+		translateFormats: {
+			'rgb': function(){
+				var rgb = this.color.toRGB();
+				return 'rgb('+rgb.r+','+rgb.g+','+rgb.b+')';
+			},
+			
+			'rgba': function(){
+				var rgb = this.color.toRGB();
+				return 'rgba('+rgb.r+','+rgb.g+','+rgb.b+','+rgb.a+')';
+			},
+			
+			'hsl': function(){
+				var hsl = this.color.toHSL();
+				return 'hsl('+Math.round(hsl.h*360)+','+Math.round(hsl.s*100)+'%,'+Math.round(hsl.l*100)+'%)';
+			},
+			
+			'hsla': function(){
+				var hsl = this.color.toHSL();
+				return 'hsla('+Math.round(hsl.h*360)+','+Math.round(hsl.s*100)+'%,'+Math.round(hsl.l*100)+'%,'+hsl.a+')';
+			},
+			
+			'hex': function(){
+				return  this.color.toHex();
+			}
+		},
+		
+		sliders: {
+			saturation: {
+				maxLeft: 100,
+				maxTop: 100,
+				callLeft: 'setSaturation',
+				callTop: 'setLightness'
+			},
+			
+			hue: {
+				maxLeft: 0,
+				maxTop: 100,
+				callLeft: false,
+				callTop: 'setHue'
+			},
+			
+			alpha: {
+				maxLeft: 0,
+				maxTop: 100,
+				callLeft: false,
+				callTop: 'setAlpha'
+			}
+		},
+		
+		// HSBtoRGB from RaphaelJS
+		// https://github.com/DmitryBaranovskiy/raphael/
+		RGBtoHSB: function (r, g, b, a){
+			r /= 255;
+			g /= 255;
+			b /= 255;
+
+			var H, S, V, C;
+			V = Math.max(r, g, b);
+			C = V - Math.min(r, g, b);
+			H = (C === 0 ? null :
+				V == r ? (g - b) / C :
+				V == g ? (b - r) / C + 2 :
+					(r - g) / C + 4
+				);
+			H = ((H + 360) % 6) * 60 / 360;
+			S = C === 0 ? 0 : C / V;
+			return {h: H||1, s: S, b: V, a: a||1};
+		},
+		
+		HueToRGB: function (p, q, h) {
+			if (h < 0)
+				h += 1;
+			else if (h > 1)
+				h -= 1;
+
+			if ((h * 6) < 1)
+				return p + (q - p) * h * 6;
+			else if ((h * 2) < 1)
+				return q;
+			else if ((h * 3) < 2)
+				return p + (q - p) * ((2 / 3) - h) * 6;
+			else
+				return p;
+		},
+	
+		HSLtoRGB: function (h, s, l, a)
+		{
+			if (s < 0) {
+				s = 0;
+			}
+			var q;
+			if (l <= 0.5) {
+				q = l * (1 + s);
+			} else {
+				q = l + s - (l * s);
+			}
+			
+			var p = 2 * l - q;
+
+			var tr = h + (1 / 3);
+			var tg = h;
+			var tb = h - (1 / 3);
+
+			var r = Math.round(CPGlobal.HueToRGB(p, q, tr) * 255);
+			var g = Math.round(CPGlobal.HueToRGB(p, q, tg) * 255);
+			var b = Math.round(CPGlobal.HueToRGB(p, q, tb) * 255);
+			return [r, g, b, a||1];
+		},
+		
+		// a set of RE's that can match strings and generate color tuples.
+		// from John Resig color plugin
+		// https://github.com/jquery/jquery-color/
+		stringParsers: [
+			{
+				re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
+				parse: function( execResult ) {
+					return [
+						execResult[ 1 ],
+						execResult[ 2 ],
+						execResult[ 3 ],
+						execResult[ 4 ]
+					];
+				}
+			}, {
+				re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
+				parse: function( execResult ) {
+					return [
+						2.55 * execResult[1],
+						2.55 * execResult[2],
+						2.55 * execResult[3],
+						execResult[ 4 ]
+					];
+				}
+			}, {
+				re: /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/,
+				parse: function( execResult ) {
+					return [
+						parseInt( execResult[ 1 ], 16 ),
+						parseInt( execResult[ 2 ], 16 ),
+						parseInt( execResult[ 3 ], 16 )
+					];
+				}
+			}, {
+				re: /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/,
+				parse: function( execResult ) {
+					return [
+						parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
+						parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
+						parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
+					];
+				}
+			}, {
+				re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
+				space: 'hsla',
+				parse: function( execResult ) {
+					return [
+						execResult[1]/360,
+						execResult[2] / 100,
+						execResult[3] / 100,
+						execResult[4]
+					];
+				}
+			}
+		],
+		template: '<div class="colorpicker dropdown-menu">'+
+							'<div class="colorpicker-saturation"><i><b></b></i></div>'+
+							'<div class="colorpicker-hue"><i></i></div>'+
+							'<div class="colorpicker-alpha"><i></i></div>'+
+							'<div class="colorpicker-color"><div /></div>'+
+						'</div>'
+	};
+
+}( window.jQuery )

+ 454 - 0
res/js/bootstrap-datepicker.js

@@ -0,0 +1,454 @@
+/* =========================================================
+ * bootstrap-datepicker.js 
+ * http://www.eyecon.ro/bootstrap-datepicker
+ * =========================================================
+ * Copyright 2012 Stefan Petre
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================= */
+ 
+!function( $ ) {
+	
+	// Picker object
+	
+	var Datepicker = function(element, options){
+		this.element = $(element);
+		this.format = DPGlobal.parseFormat(options.format||this.element.data('date-format')||'mm/dd/yyyy');
+		this.picker = $(DPGlobal.template)
+							.appendTo('body')
+							.on({
+								click: $.proxy(this.click, this),
+								mousedown: $.proxy(this.mousedown, this)
+							});
+		this.isInput = this.element.is('input');
+		this.component = this.element.is('.date') ? this.element.find('.add-on') : false;
+		
+		if (this.isInput) {
+			this.element.on({
+				focus: $.proxy(this.show, this),
+				blur: $.proxy(this.hide, this),
+				keyup: $.proxy(this.update, this)
+			});
+		} else {
+			if (this.component){
+				this.component.on('click', $.proxy(this.show, this));
+			} else {
+				this.element.on('click', $.proxy(this.show, this));
+			}
+		}
+		this.minViewMode = options.minViewMode||this.element.data('date-minviewmode')||0;
+		if (typeof this.minViewMode === 'string') {
+			switch (this.minViewMode) {
+				case 'months':
+					this.minViewMode = 1;
+					break;
+				case 'years':
+					this.minViewMode = 2;
+					break;
+				default:
+					this.minViewMode = 0;
+					break;
+			}
+		}
+		this.viewMode = options.viewMode||this.element.data('date-viewmode')||0;
+		if (typeof this.viewMode === 'string') {
+			switch (this.viewMode) {
+				case 'months':
+					this.viewMode = 1;
+					break;
+				case 'years':
+					this.viewMode = 2;
+					break;
+				default:
+					this.viewMode = 0;
+					break;
+			}
+		}
+		this.startViewMode = this.viewMode;
+		this.weekStart = options.weekStart||this.element.data('date-weekstart')||0;
+		this.weekEnd = this.weekStart === 0 ? 6 : this.weekStart - 1;
+		this.fillDow();
+		this.fillMonths();
+		this.update();
+		this.showMode();
+	};
+	
+	Datepicker.prototype = {
+		constructor: Datepicker,
+		
+		show: function(e) {
+			this.picker.show();
+			this.height = this.component ? this.component.outerHeight() : this.element.outerHeight();
+			this.place();
+			$(window).on('resize', $.proxy(this.place, this));
+			if (e ) {
+				e.stopPropagation();
+				e.preventDefault();
+			}
+			if (!this.isInput) {
+				$(document).on('mousedown', $.proxy(this.hide, this));
+			}
+			this.element.trigger({
+				type: 'show',
+				date: this.date
+			});
+		},
+		
+		hide: function(){
+			this.picker.hide();
+			$(window).off('resize', this.place);
+			this.viewMode = this.startViewMode;
+			this.showMode();
+			if (!this.isInput) {
+				$(document).off('mousedown', this.hide);
+			}
+			this.set();
+			this.element.trigger({
+				type: 'hide',
+				date: this.date
+			});
+		},
+		
+		set: function() {
+			var formated = DPGlobal.formatDate(this.date, this.format);
+			if (!this.isInput) {
+				if (this.component){
+					this.element.find('input').prop('value', formated);
+				}
+				this.element.data('date', formated);
+			} else {
+				this.element.prop('value', formated);
+			}
+		},
+		
+		setValue: function(newDate) {
+			if (typeof newDate === 'string') {
+				this.date = DPGlobal.parseDate(newDate, this.format);
+			} else {
+				this.date = new Date(newDate);
+			}
+			this.set();
+			this.viewDate = new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0, 0);
+			this.fill();
+		},
+		
+		place: function(){
+			var offset = this.component ? this.component.offset() : this.element.offset();
+			this.picker.css({
+				top: offset.top + this.height,
+				left: offset.left
+			});
+		},
+		
+		update: function(newDate){
+			this.date = DPGlobal.parseDate(
+				typeof newDate === 'string' ? newDate : (this.isInput ? this.element.prop('value') : this.element.data('date')),
+				this.format
+			);
+			this.viewDate = new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0, 0);
+			this.fill();
+		},
+		
+		fillDow: function(){
+			var dowCnt = this.weekStart;
+			var html = '<tr>';
+			while (dowCnt < this.weekStart + 7) {
+				html += '<th class="dow">'+DPGlobal.dates.daysMin[(dowCnt++)%7]+'</th>';
+			}
+			html += '</tr>';
+			this.picker.find('.datepicker-days thead').append(html);
+		},
+		
+		fillMonths: function(){
+			var html = '';
+			var i = 0
+			while (i < 12) {
+				html += '<span class="month">'+DPGlobal.dates.monthsShort[i++]+'</span>';
+			}
+			this.picker.find('.datepicker-months td').append(html);
+		},
+		
+		fill: function() {
+			var d = new Date(this.viewDate),
+				year = d.getFullYear(),
+				month = d.getMonth(),
+				currentDate = this.date.valueOf();
+			this.picker.find('.datepicker-days th:eq(1)')
+						.text(DPGlobal.dates.months[month]+' '+year);
+			var prevMonth = new Date(year, month-1, 28,0,0,0,0),
+				day = DPGlobal.getDaysInMonth(prevMonth.getFullYear(), prevMonth.getMonth());
+			prevMonth.setDate(day);
+			prevMonth.setDate(day - (prevMonth.getDay() - this.weekStart + 7)%7);
+			var nextMonth = new Date(prevMonth);
+			nextMonth.setDate(nextMonth.getDate() + 42);
+			nextMonth = nextMonth.valueOf();
+			html = [];
+			var clsName;
+			while(prevMonth.valueOf() < nextMonth) {
+				if (prevMonth.getDay() === this.weekStart) {
+					html.push('<tr>');
+				}
+				clsName = '';
+				if (prevMonth.getMonth() < month) {
+					clsName += ' old';
+				} else if (prevMonth.getMonth() > month) {
+					clsName += ' new';
+				}
+				if (prevMonth.valueOf() === currentDate) {
+					clsName += ' active';
+				}
+				html.push('<td class="day'+clsName+'">'+prevMonth.getDate() + '</td>');
+				if (prevMonth.getDay() === this.weekEnd) {
+					html.push('</tr>');
+				}
+				prevMonth.setDate(prevMonth.getDate()+1);
+			}
+			this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
+			var currentYear = this.date.getFullYear();
+			
+			var months = this.picker.find('.datepicker-months')
+						.find('th:eq(1)')
+							.text(year)
+							.end()
+						.find('span').removeClass('active');
+			if (currentYear === year) {
+				months.eq(this.date.getMonth()).addClass('active');
+			}
+			
+			html = '';
+			year = parseInt(year/10, 10) * 10;
+			var yearCont = this.picker.find('.datepicker-years')
+								.find('th:eq(1)')
+									.text(year + '-' + (year + 9))
+									.end()
+								.find('td');
+			year -= 1;
+			for (var i = -1; i < 11; i++) {
+				html += '<span class="year'+(i === -1 || i === 10 ? ' old' : '')+(currentYear === year ? ' active' : '')+'">'+year+'</span>';
+				year += 1;
+			}
+			yearCont.html(html);
+		},
+		
+		click: function(e) {
+			e.stopPropagation();
+			e.preventDefault();
+			var target = $(e.target).closest('span, td, th');
+			if (target.length === 1) {
+				switch(target[0].nodeName.toLowerCase()) {
+					case 'th':
+						switch(target[0].className) {
+							case 'switch':
+								this.showMode(1);
+								break;
+							case 'prev':
+							case 'next':
+								this.viewDate['set'+DPGlobal.modes[this.viewMode].navFnc].call(
+									this.viewDate,
+									this.viewDate['get'+DPGlobal.modes[this.viewMode].navFnc].call(this.viewDate) + 
+									DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1)
+								);
+								this.fill();
+								this.set();
+								break;
+						}
+						break;
+					case 'span':
+						if (target.is('.month')) {
+							var month = target.parent().find('span').index(target);
+							this.viewDate.setMonth(month);
+						} else {
+							var year = parseInt(target.text(), 10)||0;
+							this.viewDate.setFullYear(year);
+						}
+						if (this.viewMode !== 0) {
+							this.date = new Date(this.viewDate);
+							this.element.trigger({
+								type: 'changeDate',
+								date: this.date,
+								viewMode: DPGlobal.modes[this.viewMode].clsName
+							});
+						}
+						this.showMode(-1);
+						this.fill();
+						this.set();
+						break;
+					case 'td':
+						if (target.is('.day')){
+							var day = parseInt(target.text(), 10)||1;
+							var month = this.viewDate.getMonth();
+							if (target.is('.old')) {
+								month -= 1;
+							} else if (target.is('.new')) {
+								month += 1;
+							}
+							var year = this.viewDate.getFullYear();
+							this.date = new Date(year, month, day,0,0,0,0);
+							this.viewDate = new Date(year, month, Math.min(28, day),0,0,0,0);
+							this.fill();
+							this.set();
+							this.element.trigger({
+								type: 'changeDate',
+								date: this.date,
+								viewMode: DPGlobal.modes[this.viewMode].clsName
+							});
+						}
+						break;
+				}
+			}
+		},
+		
+		mousedown: function(e){
+			e.stopPropagation();
+			e.preventDefault();
+		},
+		
+		showMode: function(dir) {
+			if (dir) {
+				this.viewMode = Math.max(this.minViewMode, Math.min(2, this.viewMode + dir));
+			}
+			this.picker.find('>div').hide().filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName).show();
+		}
+	};
+	
+	$.fn.datepicker = function ( option, val ) {
+		return this.each(function () {
+			var $this = $(this),
+				data = $this.data('datepicker'),
+				options = typeof option === 'object' && option;
+			if (!data) {
+				$this.data('datepicker', (data = new Datepicker(this, $.extend({}, $.fn.datepicker.defaults,options))));
+			}
+			if (typeof option === 'string') data[option](val);
+		});
+	};
+
+	$.fn.datepicker.defaults = {
+	};
+	$.fn.datepicker.Constructor = Datepicker;
+	
+	var DPGlobal = {
+		modes: [
+			{
+				clsName: 'days',
+				navFnc: 'Month',
+				navStep: 1
+			},
+			{
+				clsName: 'months',
+				navFnc: 'FullYear',
+				navStep: 1
+			},
+			{
+				clsName: 'years',
+				navFnc: 'FullYear',
+				navStep: 10
+		}],
+		dates:{
+			days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
+			daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
+			daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
+			months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
+			monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+		},
+		isLeapYear: function (year) {
+			return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0))
+		},
+		getDaysInMonth: function (year, month) {
+			return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]
+		},
+		parseFormat: function(format){
+			var separator = format.match(/[.\/\-\s].*?/),
+				parts = format.split(/\W+/);
+			if (!separator || !parts || parts.length === 0){
+				throw new Error("Invalid date format.");
+			}
+			return {separator: separator, parts: parts};
+		},
+		parseDate: function(date, format) {
+			var parts = date.split(format.separator),
+				date = new Date(),
+				val;
+			date.setHours(0);
+			date.setMinutes(0);
+			date.setSeconds(0);
+			date.setMilliseconds(0);
+			if (parts.length === format.parts.length) {
+				for (var i=0, cnt = format.parts.length; i < cnt; i++) {
+					val = parseInt(parts[i], 10)||1;
+					switch(format.parts[i]) {
+						case 'dd':
+						case 'd':
+							date.setDate(val);
+							break;
+						case 'mm':
+						case 'm':
+							date.setMonth(val - 1);
+							break;
+						case 'yy':
+							date.setFullYear(2000 + val);
+							break;
+						case 'yyyy':
+							date.setFullYear(val);
+							break;
+					}
+				}
+			}
+			return date;
+		},
+		formatDate: function(date, format){
+			var val = {
+				d: date.getDate(),
+				m: date.getMonth() + 1,
+				yy: date.getFullYear().toString().substring(2),
+				yyyy: date.getFullYear()
+			};
+			val.dd = (val.d < 10 ? '0' : '') + val.d;
+			val.mm = (val.m < 10 ? '0' : '') + val.m;
+			var date = [];
+			for (var i=0, cnt = format.parts.length; i < cnt; i++) {
+				date.push(val[format.parts[i]]);
+			}
+			return date.join(format.separator);
+		},
+		headTemplate: '<thead>'+
+							'<tr>'+
+								'<th class="prev">&lsaquo;</th>'+
+								'<th colspan="5" class="switch"></th>'+
+								'<th class="next">&rsaquo;</th>'+
+							'</tr>'+
+						'</thead>',
+		contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>'
+	};
+	DPGlobal.template = '<div class="datepicker dropdown-menu">'+
+							'<div class="datepicker-days">'+
+								'<table class=" table-condensed">'+
+									DPGlobal.headTemplate+
+									'<tbody></tbody>'+
+								'</table>'+
+							'</div>'+
+							'<div class="datepicker-months">'+
+								'<table class="table-condensed">'+
+									DPGlobal.headTemplate+
+									DPGlobal.contTemplate+
+								'</table>'+
+							'</div>'+
+							'<div class="datepicker-years">'+
+								'<table class="table-condensed">'+
+									DPGlobal.headTemplate+
+									DPGlobal.contTemplate+
+								'</table>'+
+							'</div>'+
+						'</div>';
+
+}( window.jQuery )

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1763 - 0
res/js/bootstrap-datetimepicker.js


+ 16 - 0
res/js/bootstrap-datetimepicker.zh-CN.js

@@ -0,0 +1,16 @@
+/**
+ * Simplified Chinese translation for bootstrap-datetimepicker
+ * Yuan Cheung <advanimal@gmail.com>
+ */
+;(function($){
+	$.fn.datetimepicker.dates['zh-CN'] = {
+			days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"],
+			daysShort: ["周日", "周一", "周二", "周三", "周四", "周五", "周六", "周日"],
+			daysMin:  ["日", "一", "二", "三", "四", "五", "六", "日"],
+			months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
+			monthsShort: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
+			today: "今日",
+			suffix: [],
+			meridiem: ["上午", "下午"]
+	};
+}(jQuery));

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1622 - 0
res/js/bootstrap-select.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1998 - 0
res/js/bootstrap.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 6636 - 0
res/js/bootstrapValidator.js


+ 114 - 0
res/js/jquery.cookie.js

@@ -0,0 +1,114 @@
+/*!
+ * jQuery Cookie Plugin v1.4.1
+ * https://github.com/carhartl/jquery-cookie
+ *
+ * Copyright 2006, 2014 Klaus Hartl
+ * Released under the MIT license
+ */
+(function (factory) {
+    if (typeof define === 'function' && define.amd) {
+        // AMD (Register as an anonymous module)
+        define(['jquery'], factory);
+    } else if (typeof exports === 'object') {
+        // Node/CommonJS
+        module.exports = factory(require('jquery'));
+    } else {
+        // Browser globals
+        factory(jQuery);
+    }
+}(function ($) {
+
+    var pluses = /\+/g;
+
+    function encode(s) {
+        return config.raw ? s : encodeURIComponent(s);
+    }
+
+    function decode(s) {
+        return config.raw ? s : decodeURIComponent(s);
+    }
+
+    function stringifyCookieValue(value) {
+        return encode(config.json ? JSON.stringify(value) : String(value));
+    }
+
+    function parseCookieValue(s) {
+        if (s.indexOf('"') === 0) {
+            // This is a quoted cookie as according to RFC2068, unescape...
+            s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
+        }
+
+        try {
+            // Replace server-side written pluses with spaces.
+            // If we can't decode the cookie, ignore it, it's unusable.
+            // If we can't parse the cookie, ignore it, it's unusable.
+            s = decodeURIComponent(s.replace(pluses, ' '));
+            return config.json ? JSON.parse(s) : s;
+        } catch(e) {}
+    }
+
+    function read(s, converter) {
+        var value = config.raw ? s : parseCookieValue(s);
+        return $.isFunction(converter) ? converter(value) : value;
+    }
+
+    var config = $.cookie = function (key, value, options) {
+
+        // Write
+
+        if (arguments.length > 1 && !$.isFunction(value)) {
+            options = $.extend({}, config.defaults, options);
+
+            if (typeof options.expires === 'number') {
+                var days = options.expires, t = options.expires = new Date();
+                t.setMilliseconds(t.getMilliseconds() + days * 864e+5);
+            }
+
+            return (document.cookie = [
+                encode(key), '=', stringifyCookieValue(value),
+                options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
+                options.path    ? '; path=' + options.path : '',
+                options.domain  ? '; domain=' + options.domain : '',
+                options.secure  ? '; secure' : ''
+            ].join(''));
+        }
+
+        // Read
+
+        var result = key ? undefined : {},
+            // To prevent the for loop in the first place assign an empty array
+            // in case there are no cookies at all. Also prevents odd result when
+            // calling $.cookie().
+            cookies = document.cookie ? document.cookie.split('; ') : [],
+            i = 0,
+            l = cookies.length;
+
+        for (; i < l; i++) {
+            var parts = cookies[i].split('='),
+                name = decode(parts.shift()),
+                cookie = parts.join('=');
+
+            if (key === name) {
+                // If second argument (value) is a function it's a converter...
+                result = read(cookie, value);
+                break;
+            }
+
+            // Prevent storing a cookie that we couldn't decode.
+            if (!key && (cookie = read(cookie)) !== undefined) {
+                result[name] = cookie;
+            }
+        }
+
+        return result;
+    };
+
+    config.defaults = {};
+
+    $.removeCookie = function (key, options) {
+        // Must not alter options, thus extending a fresh object...
+        $.cookie(key, '', $.extend({}, options, { expires: -1 }));
+        return !$.cookie(key);
+    };
+
+}));

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 4 - 0
res/js/jquery.min.js


+ 89 - 0
test.php

@@ -0,0 +1,89 @@
+<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
+<script type="text/javascript" src="http://localhost:8055/chatroom/res/js/jquery.cookie.js"></script>
+
+<?php
+
+//include "autoload.php";
+
+//$config = Utils::config();
+//$pact = 'login';
+/*function isAction($pact,$config)
+{
+
+    $data = isParame($config['server_pact'], $pact);
+
+    if ($data) {
+
+        var_dump($pact);
+    }
+   var_dump($data);
+}*/
+/***
+ * 参数是否为空
+ * @param $data
+ * @return bool
+ */
+/*   function isParame($data, $key)
+{
+    if ($red = isDatas($data, $key)) {
+        return $red;
+    }
+    log_message::info("$key is null ");
+    //exit(Utils::sendResults("$key is null"));
+    //exit(Utils::errorCode("$key is null ", FAILURE));
+    return null;
+}
+$data = isParame($config['server_pact'], $pact);
+
+if (in_array($pact,  $config['server_pact'])) {
+
+    echo "dddddddd". $pact;
+}
+
+isAction('login',$config);*/
+
+/*function tess()
+{
+
+    return "123";
+}
+
+
+$dd = 'tess';
+if (function_exists($dd)) {
+
+    echo $dd();
+} else {
+
+    echo "fall";
+}*/
+
+$dd = '{"friend_msg":"555","friendid":2105055520,"friend_nickname":"byjames","create_at":"2019-05-12 星期日 20:01:58","status":1}';
+$aa = ' {"friend_msg":"dff123","friendid":2105055520,"friend_nickname":"byjames","create_at":"2019-05-12 星期日 20:01:58","status":1}';
+$cc2 = ' {"friend_msg":"dff1234","friendid":2105055520,"friend_nickname":"byjames","create_at":"2019-05-12 星期日 20:01:58","status":1}';
+
+$a = json_decode($dd, true);
+$b = json_decode($aa, true);
+//var_dump($a);
+echo "<br>";
+//var_dump($b);
+
+echo "<br>";
+$m = $a + $b;
+$data[] = $a;
+$data[] = $b;
+
+//var_dump($data);
+
+$aa = json_encode($data, JSON_UNESCAPED_UNICODE);
+
+$cc = json_decode($aa, true);
+
+$dam[] = $cc;
+$dam[] = json_decode($cc2, true);
+ echo count($a);
+echo count($b, 1);
+?>
+
+
+

+ 34 - 0
user.php

@@ -0,0 +1,34 @@
+<?php
+ini_set("display_errors", "On");
+
+error_reporting(E_ALL | E_STRICT);
+require "autoload.php";
+
+$name = $_REQUEST['account'];
+$pas = $_REQUEST['paw'];
+$type = !empty($_REQUEST['type']) ? $_REQUEST['type'] : ZERO; // 1 注册 2 登录
+log_message::info(1);
+$ChatModel = new  ChatModel($type);
+log_message::info(2);
+log_message::info(json_encode($_REQUEST, JSON_UNESCAPED_UNICODE));
+log_message::info($name . "--" . $pas);
+
+if (isBlank($name) || isBlank($pas)) {
+
+    $rs = [
+        'msg' => '用户名密码不能为空',
+    ];
+    echo json_encode($rs, JSON_UNESCAPED_UNICODE);
+}
+if (!isBlank($name) && !isBlank($pas)) {
+    log_message::info(3);
+    $data = $ChatModel->userVerif();
+    $data = is_string($data) ? json_decode($data, true) : $data;
+    $rs = [
+        'msg' => '用户名密码ok',
+        'data' => $data
+    ];
+    log_message::info(4);
+    echo json_encode($data, JSON_UNESCAPED_UNICODE);
+    // 校验用户名
+}