key = C('ADDONS_BUY_KEY'); $AdminModel = new RetailAdminModel(); $admin = $AdminModel->getFind(array('id' => array('gt', 0)), 'phone,sign'); $this->phone = $admin['phone']; $this->password = $admin['sign']; } /** * 获取推荐应用列表 */ public function getPlugAddonAppList() { $result = $this->sendRequest('addon_app/getReferrerAddonAppList'); if ($result && $result['code'] == 000000) { $result['status'] = 1; } else { $result['status'] = 0; } $this->ajaxReturn($result); } /** * 获取插件详情 */ public function getAddonDetails() { $PlugModel = new RetailPlugModel(); $identification = I('post.identification'); $map = array( 'identification' => $identification, ); $plug = $PlugModel->getFind($map); $post['identification'] = $identification; $response = $this->sendRequest('addon_app/getAddonDetails', $post); if (empty($plug)) { $response['is_buy'] = 0; //是否已购买 $response['is_install'] = 0; //是否已安装 } else { $response['is_buy'] = 1; //是否已购买 $response['is_install'] = $plug['is_install'] ? 1 : 0; //是否已安装 } if (!empty($plug) && $plug['origin_type'] == 2 && $plug['is_install'] == 1) { $upgrade = $this->getBranchRenewal($identification, $plug['version']);//查看版本是否有更新 $response['upgrade'] = $upgrade['status']; } else { $response['upgrade'] = 2; } $this->ajaxReturn($response); } /** * 查看版本是否有更新 * @param $identification 插件唯一标识 * @param $version 插件当前版本号 * @return mixed */ public function getBranchRenewal($identification, $version) { $param['atustr'] = createKey(); //随机字符串 $param['support_id'] = 4; $param['identification'] = $identification; $param['versions'] = "V" . $version; $param['sign'] = createSign($param, $this->key); //生成签名 $param['test'] = $this->debug; //是否是测试 $response = http_request($this->request_url . 'addon_app/getBranchRenewal', $param); //POST方式请求http $response = json_decode($response, true); if ($response['code'] == 000000) { $result['status'] = $response['data']['status']; } else { $result['status'] = 2; } return $result; } /** * 获取版本详情 */ public function getBranchVersions() { $post['identification'] = I('post.identification'); $response = $this->sendRequest('addon_app/getBranchVersions', $post); if ($response) { $result['code'] = $response['code']; $result['msg'] = $response['msg']; $result['data'] = $response['data']; } else { $result['status'] = 0; $result['msg'] = '数据获取失败'; } $this->ajaxReturn($result); } /** * 获取最新版本名 */ public function getNewestVersionName() { $identification = I('post.identification'); $post['private_key'] = $this->getAddonKey($identification); $response = $this->sendRequest('addon_file/getZIPFilename', $post); return $response; } /** * 获取购买记录接口(这个是请求控制台的) */ public function getOrderList() { $post['start_time'] = I('post.start_time') ? I('post.start_time') : ''; $post['end_time'] = I('post.end_time') ? I('post.end_time') : ''; $post['page'] = I('post.page') ? I('post.page') : 1; $post['limit'] = I('post.limit') ? I('post.limit') : 10; $post['like'] = I('post.like') ? I('post.like') : ''; $response = $this->sendRequest('AddonPingOrder/getPingOrderList', $post); if ($response && $response['code'] == 000000) { $result['status'] = 1; $result['msg'] = $response['msg']; $result['data'] = $response['data']; $result['count'] = $response['count']; } else { $result['status'] = 0; $result['msg'] = '数据获取失败'; } $this->ajaxReturn($result); } /** * 获取支付配置信息 */ public function getPayConfigInfo() { $response = $this->sendRequest('AddonPayConfig/getState', array()); if ($response && $response['code'] == 000000) { $result['status'] = 1; $result['msg'] = $response['msg']; $result['data'] = $response['data']; } else { $result['status'] = 0; $result['msg'] = '数据获取失败'; } $this->ajaxReturn($result); } /** * 获取支付宝收款码 */ public function getAliPayCode() { $identification = I('post.identification'); $data['identification'] = $identification; $version = $this->sendRequest('addon_app/getBranchVersions', $data); //获取当前需要购买的版本 $detail = $this->sendRequest('addon_app/getAddonDetails', $data); //获取插件详情 $post['price'] = $detail['data']['price']; $post['remark'] = $detail['data']['name']; $post['id'] = $detail['data']['branch_id']; $post['name'] = $detail['data']['name']; $post['branch_id'] = $detail['data']['branch_id']; $post['trade_amount'] = $detail['data']['price']; $post['versions'] = $version['data'][0]['versions']; $post['private_key'] = $this->getSecretKey(); $response = $this->sendRequest('Index/precreate', $post); //支付宝下单 //支付宝比较特殊 10000是成功 if ($response && $response['code'] == '10000') { $result['status'] = 1; $result['msg'] = $response['msg']; $result['out_trade_no'] = $response['out_trade_no']; $result['qr_code'] = $response['qr_code']; } else { $result['status'] = 0; $result['msg'] = '下单失败'; } $result['post'] = $post; // $result['response'] = $response; $result['$version'] = $version; $result['$detail'] = $detail; $this->ajaxReturn($result); } /** * 获取微信收款码 */ public function getWxCode() { $identification = I('post.identification'); $data['identification'] = $identification; $version = $this->sendRequest('addon_app/getBranchVersions', $data); //获取当前需要购买的版本 $detail = $this->sendRequest('addon_app/getAddonDetails', $data); //获取插件详情 $post['price'] = $detail['data']['price']; $post['remark'] = $detail['data']['name']; $post['branch_id'] = $detail['data']['branch_id']; $post['trade_amount'] = $detail['data']['price']; $post['versions'] = $version['data'][0]['versions']; $post['private_key'] = $this->getSecretKey(); $response = $this->sendRequest('Index/unifiedOrder', $post); //微信下单 if ($response && $response['code'] == 000000) { $result['msg'] = $response['msg']; $result['data'] = $response['data']; $result['status'] = 1; } else { $result['status'] = 0; $result['msg'] = '下单失败'; } $this->ajaxReturn($result); } /** * 查询订单支付状态 */ public function getOrderPaystate() { $post['out_trade_no'] = I('post.out_trade_no'); $response = $this->sendRequest('addon_ping_order/getPhingOrderInfo', $post); if ($response && $response['code'] == 000000) { $result['status'] = 1; $result['msg'] = $response['msg']; $result['data'] = $response['data']; $result['result'] = $response; } else { $result['status'] = 0; $result['msg'] = '数据获取失败'; } $this->ajaxReturn($result); } /** * 获取我的应用列表 */ public function getPlugList() { $PlugModel = new RetailPlugModel(); $map = array( 'id' => array('gt', '0'), ); $data = $PlugModel->getSelect($map); foreach ($data as &$val) { $val['addtime'] = date('Y-m-d H:i:s', $val['addtime']); if ($val['origin_type'] == 2) { $upgrade = $this->getBranchRenewal($val['identification'], $val['version']); $val['upgrade'] = $upgrade['status']; } else { $val['icon_url'] = getServerUrl() . $val['icon_url']; $val['upgrade'] = 2; } } $result['status'] = 1; $result['data'] = $data; $result['msg'] = $data ? '数据获取成功!' : '暂无数据!'; $this->ajaxReturn($result); } /** * 获取安装包 */ public function getZip() { $RetailPlugModel = new RetailPlugModel(); $identification = I('post.identification'); $post['atustr'] = createKey(); //随机字符串 $post['phone'] = $this->phone; $post['password'] = $this->password; $post['support_id'] = 4; $post['private_key'] = $this->getAddonKey($identification); $post['sign'] = createSign($post, $this->key); $post['test'] = $this->debug; $url = $this->request_url . 'addon_file/getZIP'; $res = $this->GetWebFileStream($url, $post, 'post'); if (!is_dir('./Addons')) { mkdir('./Addons', 0777, true); } //插件压缩包安装目录 $zip_path = './Addons/' . $identification . '.zip'; if (file_exists($zip_path)) { unlink($zip_path); } $fp2 = @fopen($zip_path, 'a'); fwrite($fp2, $res); fclose($fp2); //解压 $z = new Unzip; $res = $z->unzip($zip_path, false, true, true); if ($res) { //截取插件名称 $file_name = file_get_contents('./Addons/' . $identification . "/" . $identification . '/data.json'); $name = json_decode($file_name, true)['plug_file_name']; //解压到Application下插件目录 $path = self::$copyto . "/" . $name; is_dir($path) or mkdir($path, 0777, true); $old_path = './Addons/' . $identification . "/" . $identification . "/" . $name; $save_path = self::$copyto . "/" . $name . "/"; $this->fileCover($old_path, $save_path); //安装Addons插件 $public_zip_path = './Addons/' . $identification . "/" . $identification . "/Public"; try { is_dir($public_zip_path) && $this->fileCover($public_zip_path, "./Public"); //处理Public文件 } catch (\Exception $e) { } //config文件'MODULE_ALLOW_LIST'添加插件模块 if (!in_array($name, C('MODULE_ALLOW_LIST'))) { $config = file_get_contents('./Application/Common/Conf/config.php'); if ($config) { $test = str_replace("'NotifyApi'", "'NotifyApi', '$name'", $config); file_put_contents('./Application/Common/Conf/config.php', $test); } } //解压文件tags.tpl写入Common/Conf/tags.php $path = './Addons/' . $identification . "/" . $identification . '/tags.json'; $conf = file_get_contents($path); $set = include("./Application/Common/Conf/tags.php"); if ($conf) { $conf = json_decode($conf, true); $conf = str_replace(',', '\\', $conf); $opposite_conf = array_flip($conf); foreach ($opposite_conf as $val) { if (!$set[$val]) { $update = " '$val' => " . $conf[$val] . ',' . PHP_EOL; $tags = file_get_contents('./Application/Common/Conf/tags.php'); $msg = str_replace(');', $update . ');', $tags); file_put_contents('./Application/Common/Conf/tags.php', $msg); } } } //执行sql $sql_path = self::$copydir . "/" . $identification . "/" . $identification . "/" . "data.sql"; if (file_get_contents($sql_path)) { $this->sqlQuerys($sql_path); } $version_data = $this->getNewestVersionName(); $data = array( 'is_install' => 1, 'version' => str_replace('V', '', $version_data['data']['versions']), ); $RetailPlugModel->updateOrder(['identification' => $identification], $data); $result['status'] = 1; $result['msg'] = '压缩包安装成功!'; } else { $result['status'] = 0; $result['msg'] = '压缩包安装失败'; } $this->ajaxReturn($result); } /*------------------------------------------------------------------- 一些封装及调用 ------------------------------------------------*/ /** * 公共往应用中心请求的方法 * @param $request_url 请求地址 * @param array $param 请求的非公共参数之外的参数 * @return bool|mixed|\returns|string */ protected function sendRequest($request_url, $param = array()) { $param['phone'] = $this->phone; $param['password'] = $this->password; $param['support_id'] = 4; $param['atustr'] = createKey(); //随机字符串 $param['sign'] = createSign($param, $this->key); //生成签名 $param['test'] = $this->debug; //是否是测试 $response = http_request($this->request_url . $request_url, $param); //POST方式请求http $response = json_decode($response, true); return $response; } /** * 生成应用私钥 * @return string */ private function getSecretKey() { $result = $this->sendRequest('Index/getSecretKey'); if ($result['data']['key']) { return $result['data']['key']; } else { return ''; } } /** * 获取已安装插件私钥 * @param $identification 应用唯一标识 * @return mixed|string */ private function getAddonKey($identification) { $PlugModel = new RetailPlugModel(); $map = array( 'identification' => $identification, ); $secret_key = $PlugModel->getFindField($map, 'private_key'); return $secret_key ? $secret_key : ''; } /** * 更新sql 文件语句 */ private function sqlQuerys($path) { try { $sql = file_get_contents($path); $sql = str_replace("\r", "\n", $sql); $sql = explode(";", $sql); foreach ($sql as $value) { $value = trim($value); if (empty($value)) { continue; } if (substr($value, 0, 12) == 'CREATE TABLE') { $name = preg_replace("/^CREATE TABLE `(\w+)` .*/s", "\\1", $value); $msg = "创建数据表{$name}"; if ($this->isTable($name) != '1') { //表不存在 if (false !== M()->execute($value)) { $str = $msg . '...成功!'; } else { $str = $msg . '...失败!'; } } else { $str = $msg . '...失败!'; } $sqlMsg[] = $str; } else if (substr($value, 0, 11) == 'ALTER TABLE' && strpos($value, "ADD COLUMN") !== false) { //查找字段的名称 $name = $this->getNeedBetween($value, "`", "`"); $field = $this->getNeedBetween($value, "COLUMN `", "` "); $re = $this->_iset_field(substr($name, 3), $field); if (!$re) { $res = M(substr($name, 3))->execute($value); if ($res !== false) { $sqlMsg[] = $field . "字段更新成功"; } else { $sqlMsg[] = $field . "字段更新失败"; } } else { $sqlMsg[] = $field . "字段更新失败"; } } else if (substr($value, 0, 11) == 'ALTER TABLE' && strpos($value, "ADD INDEX") !== false) { //获取索引名称 $table_name = $this->getNeedBetween($value, "`", "`"); $index_name = $this->getNeedBetween($value, "INDEX `", "`"); //查询索引是否存在 $sql = "SELECT * FROM information_schema.statistics WHERE table_name = '" . $table_name . "' AND index_name = '" . $index_name . "'"; $res = M()->execute($sql); if (empty($res)) { $res = M()->execute($value); if ($res !== false) { $sqlMsg[] = $index_name . "索引添加成功"; } else { $sqlMsg[] = $index_name . "索引添加成功"; } } } else { M()->execute($value); } } $this->sqlArr = $sqlMsg; return true; } catch (\Exception $e) { self::$error = $e->getMessage(); return false; } } /** * 查询指定的字段是否存在表中 * @param type $field 字段名称 * @return void * @access protected */ protected function _iset_field($dbname, $field) { $fields = M($dbname)->getDbFields(); return array_search($field, $fields); } /** * 正则判断 */ public function getNeedBetween($txtname, $start, $end) { $i = strpos($txtname, $start); if (!$i) { return false; } $i += strlen($start); $j = strpos($txtname, $end, $i); if (!$j) { return false; } return substr($txtname, $i, $j - $i); } /** 判断数据表是否存在 * @param $table_name * @return mixed */ public function isTable($table_name) { $sql = "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '" . C("DB_NAME") . "' AND table_name = '" . $table_name . "'"; $isTable = M()->query($sql); return $isTable[0]["count(*)"]; } /** * 更新静态文件 */ public function zippublic() { $publicDir = "./tempApp"; $saveDir = "./Public/"; $version = I("post.version"); //执行更新sql文件 $unzipObj = new Unzip(); $versions = "V" . $version; $path = $publicDir . "/" . $versions . "/App/" . $versions . "/auto/" . $version . ".zip"; $re = $unzipObj->unzip($path, $saveDir, true, true); if ($re !== false) { $data["code"] = 1; $data["msg"] = "静态文件更新成功"; } else { $data["code"] = 0; $data["msg"] = "静态文件更新失败"; } $this->ajaxReturn($data); } /** * 获取网络接口里面的文件流 **/ public function GetWebFileStream($strUrl, $urlParams = '', $type = 'get') { $stream = ""; if (!isset($strUrl) || empty($strUrl)) return ""; //初始化 $ch = curl_init(); if ($type === 'post') { curl_setopt_array($ch, [ CURLOPT_URL => $strUrl, CURLOPT_RETURNTRANSFER => 1, CURLOPT_POST => 1, CURLOPT_HEADER => 0, CURLOPT_POSTFIELDS => $urlParams ]); } else { curl_setopt_array($ch, [ CURLOPT_URL => $strUrl, CURLOPT_RETURNTRANSFER => 1, CURLOPT_HEADER => 0 ]); } //输出结果 $stream = curl_exec($ch); //推断curl请求是否超时 if (curl_errno($ch)) { $stream = file_get_contents($strUrl); } //关闭 curl_close($ch); return $stream; } private function fileCover($path, $save_path) { $handler = opendir($path); //打开当前文件夹由$path指定。 while (($filename = readdir($handler)) !== false) { if ($filename != "." && $filename != "..") { //文件夹文件名字为'.'和‘..',不要对他们进行操作 if (is_dir($path . "/" . $filename)) { // 如果读取的某个对象是文件夹,则递归 is_dir($save_path . "/" . $filename) or mkdir($save_path . "/" . $filename, 0777, true); $this->fileCover($path . "/" . $filename, $save_path . "/" . $filename); } else { //文件复制 copy($path . "/" . $filename, $save_path . "/" . $filename); } } } @closedir($handler); } /** * 插件首页 */ public function index() { $this->display(); } /** * 插件详情页面 */ public function detail() { $this->display(); } /** * 插件购买记录页面 */ public function purchaseRecord() { $this->display(); } //插件信息 public function plugSetInfo() { $data = I('post.'); $PlugSetClass = new PlugSet(); $result = $PlugSetClass->setInfo($data); $this->ajaxReturn($result); } //插件信息配置 public function plugSet() { $data = I('post.'); $data['operator_id'] = session('jurisdiction_user')['id']; $PlugSetClass = new PlugSet(); $result = $PlugSetClass->plugSet($data); $this->ajaxReturn($result); } }